Académique Documents
Professionnel Documents
Culture Documents
Além disso, toda vez que for necessário ou desejado passar argumentos na linha de comando de
um programa escrito em C, deve-se declarar a função principal como:
main(int argc,char *argv[]) /* OU int main(int argc,char *argv[]) */
é essencialmente equivalente a
p = (int *)malloc(m*n*sizeof(int));
memset(p,0,m*n*sizeof(int));
Há ainda a função realloc, que permite alterar a dimensão de uma área pré-alocada. Esta
função recebe dois argumentos: o apontador para a área que havia sido previamente alocada e a nova
dimensão para esta área (em bytes). Quando malloc, calloc e realloc não conseguem alocar o
espaço requisitado, o valor retornado pela função é o apontador nulo, que aponta para um endereço
especial que não pode ser atribuído a nenhuma variável.
sendo que o acesso ao elemento (i,j) do arranjo se dá utilizando a indexação arranjo[i][j], com i e j
inteiros tais que 0 ≤ i < NLIN e 0 ≤ j < NCOL.
Como uma alternativa, é possível simular um arranjo bidimensional via um arranjo
unidimensional na forma:
int arranjo[NLIN*NCOL];
Esta última forma é a mais recomendada, mesmo que se conheça antecipadamente o número de
linhas e colunas. No entanto, ela não garante alocação de posições contíguas de memória. Para obter
alocação de posições contíguas, sugere-se o seguinte código:
#include <stdlib.h>
int nlin,ncol;
int **arranjo;
/* definicao on-line do numero de linhas e colunas */
arranjo = (int **)malloc(nlin*sizeof(int *));
arranjo[0] = (int *)malloc(nlin*ncol*sizeof(int));
for(i=0;i<nlin,i++)
arranjo[i] = arranjo[0] + i*ncol;
Para número de linhas e colunas definidos em tempo de execução, é fundamental que se garanta
alocação contígua de memória, permitindo utilizar a seguinte declaração de função:
tipo1 f(a,nlin,ncol)
tipo2 **a;
int nlin;
int ncol; {}
outros:
#ifndef
#elif
K&R ANSI
int f(a,b) int main()
int a; {
int b; int f(int,int);
{} double c,d;
int e;
int main() e = f(c,d);
{ }
double c,d;
int e; int f(int a, int b)
e = f(c,d); {}
}
3. Você sabia?
• na expressão f()+g()*h(), o produto vai ser realizado antes da soma, mas não é possível antecipar
qual vai ser a ordem de execução das três funções. Por outro lado, em expressões envolvendo os
operadores <&&>, <||>, <?:> e <,>, como em
while((c=getchar()) != EOF && c !='\n'){} /* while(f() && g()){} */
4. Atividades práticas
1) Quais são as saídas geradas pelos seguintes programas compilados com cc? O que elas representam?
#include <stdio.h>
int inteiro = 5;
char caractere = '5';
char *cadeia = "5";
int main()
{
IMPRIME(%d,cadeia); IMPRIME(%d,caractere); IMPRIME(%d,inteiro);
IMPRIME(%s,cadeia); IMPRIME(%c,caractere);
inteiro = 53; IMPRIME(%c,inteiro);
IMPRIME(%d,('5'>5));
{
int ax = 8;
int sx = -8;
unsigned int ux = -8;
IMPRIME(%o,ax); IMPRIME(%o,sx); IMPRIME(%o,ux);
sx = sx>>3; IMPRIME(%o, sx); ux = ux>>6; IMPRIME(%o, ux);
IMPRIME(%d, sx); IMPRIME(%d, ux);
}
return(1);
}
#include <stdio.h>
int main()
{
int x,y,z;
x = 2; y = 1; z = 0;
x = x && y || z; IMPRIME(x);
IMPRIME(x || !y && z);
x = y = 1;
z = x ++ - 1; IMPRIME(x); IMPRIME(z);
z += -x ++ + ++ y; IMPRIME(x); IMPRIME(z);
return(1);
}
#include <stdio.h>
int main()
{
int x,y,z;
x = 03; y = 02; z = 01;
IMPRIME(x|y&z); IMPRIME(x|y&~z); IMPRIME(x^y&~z); IMPRIME(x&y&&z);
x = 1; y = -1;
IMPRIME(!x | x); IMPRIME(~x | x); IMPRIME(x ^ x);
x <<= 3; IMPRIME(x); y <<= 3; IMPRIME(y); y >>= 3; IMPRIME(y);
return(1);
}
#include <stdio.h>
int a[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int *pa[3] = {
a[0], a[1], a[2]
};
int *p = a[0];
int main()
{
int i;
for (i=0; i<3; i++)
IMPRIME3(%d, a[i][2-i],*a[i],*(*(a+i)+i)); NL;
for (i=0; i<3; i++)
IMPRIME2(%d, *pa[i], p[i]);
return(1);
}
#include <stdio.h>
struct S1{
char *s;
struct S1 *s1p;
};
int main()
{
static struct S1 a[] = {
{"abcd", a+1},
{"efgh", a+2},
{"ijkl", a}
};
struct S1 *p[3];
int i;
for (i=0; i<3; i++) p[i] = a[i].s1p;
IMPRIME3(%s, p[0]->s, (*p)->s, (**p).s);
troca(*p,a); IMPRIME3(%s, p[0]->s, (*p)->s, (*p)->s1p->s);
troca(p[0],p[0]->s1p); IMPRIME3(%s, p[0]->s, (*++p[0]).s, ++(*++(*p)->s1p).s);
return(1);
}
(a) prog1.c
/* Este programa aceita o primeiro nome digitado pelo usuario
e compoe uma frase a ser apresentada na tela
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *nome,mens1[100],mens2;
mens2 = malloc(100); /* */
printf("Qual e' seu nome? "); /* */
scanf("%s",nome); /* */
mens1 = "Bem-vindo, ";
mens2 = " `as atividades praticas do curso EA869!\n";
printf("%s%s%s",mens1,nome,mens2); /* */
return(0);
}
4) Com base na noção de escopo de variáveis em C, explique o motivo pelo qual os arranjos de
caracteres cnum1 e cnum2 recebem lixo (ftoc converte ponto flutuante para caractere). Apresente as
correções necessárias para resolver o problema.
#include <stdio.h>
main()
{
char *ftoc(double);
char *cnum1,*cnum2;
double a=13.956,b=123456789.01;
cnum1 = ftoc(a); cnum2 = ftoc(b);
printf("%s %s\n",cnum1,cnum2);
return(1);
}
char *ftoc(double a)
{
char b[100];
sprintf(b,"%f",a);
return b;
}
5) Use o comando sizeof para verificar a quantos bytes corresponde um char, int, float, double, short
int, unsigned int, long int. Verifique o valor retornado por sizeof('a') e então responda como são
representados os caracteres alfanuméricos. Com base na representação adotada para os caracteres
alfanuméricos, indique como deve ser declarado o valor de retorno (c) da função getchar em
while((c=getchar())!='z'){}
6) Em uma expressão condicional para verificar se um arranjo de caracteres abc previamente definido
casa com uma determinada expressão (seqüência de caracteres), deve-se utilizar
strcmp(abc,"expressao")==0 e nunca abc == "expressao". Explique o motivo de não ser
possível utilizar abc == "expressao".
7) Sabendo-se que a função rand(), definida em <stdlib.h>, retorna um valor inteiro aleatório no
intervalo (0,RAND_MAX), escreva um programa que receba zero, um ou dois argumentos (valores
inteiros) e retorne um número inteiro aleatório. De acordo com o número de argumentos (nargs), o
programa deve retornar um número inteiro aleatório:
• no intervalo (0,RAND_MAX), se nargs=0;
• no intervalo (0,arg1) ou (arg1,0) -- arg1 pode ser negativo --, se nargs=1;
• no intervalo (arg1,arg2) ou (arg2,arg1) -- vai depender de quem é maior --, se nargs=2;
Como vai ser necessário trabalhar com escalas, é recomendado o uso de retipagem. O
programa não deve aceitar mais que dois argumentos. Como arg1 e arg2 podem ser maiores que
RAND_MAX, utilizar long int.
8) Devido à necessidade de representação binária, não é possível assumir que os resultados em ponto
flutuante sejam exatos. Isto implica na impossibilidade de verificar a igualdade de duas variáveis
declaradas como float ou double, como no trecho de programa:
double a,b;
/* bloco de comandos que define valores para a e b */
if(a == b){}
9) Escreva um programa que receba como argumento dois números (inteiros ou reais) intercalados por
um símbolo indicando uma operação (+, −, x ou /), retornando o resultado da operação na forma:
arg1 arg2 arg3 = resultado.