Вы находитесь на странице: 1из 17

Princpios de programao em Linguagem C

Cesar Tadeu Pozzer UFSM 16/08/2010

Introduo a Programao em Linguagem C Antes de um algoritmo ser executado no computador, ele deve ser traduzido em uma linguagem que o computador possa compreender. Para isso existem os compiladores, que varrem o algoritmo, verificam a existncia de erros e o convertem na notao da mquina sendo usada. O cdigo executvel de um programa para PC no igual ao cdigo do mesmo programa para Mac, por exemplo. Neste curso ser estudada a linguagem C [2][3] e o compilador usado ser o Microsoft Visual C++ para plataforma Windows. Outra forma de executar programas com o uso de interpretadores, como no caso da linguagem Lua, Javascript, etc. Interpretadores so frequentemente utilizados para fazer processamento de linguagens de script, como no caso engines de jogos e aplicativos grficos, como o 3D Studio, dentre outros. Para transformar um algoritmo em C, vrias adaptaes devem ser feitas. C, como qualquer outra linguagem, tem um nvel de formalismo muito maior que um algoritmo. Em C, as variveis devem ter um tipo especfico. Por exemplo: Tipo int float char Descrio do tipo Usado para armazenar nmeros inteiros. Ex: 30, -10, 1001 Usado para armazenar nmeros reais. Ex: 12.1, 0.003, 1000 Usado para armazenar caracteres. Ex: a, M

Em vez de usar Inicio e Fim, deve-se usar os caracteres { } para definio de blocos de dados ou funes. A linguagem C define um grande nmero de bibliotecas de funes. Algumas delas so: Nome da biblioteca math.h stdio.h string.h O que contm Funes matemticas, como seno, cosseno, etc. Funes de leitura e impresso de dados Funes de manipulao de texto

A existncia destas funes reduz o tempo de criao de uma aplicao, e tornam o cdigo mais compacto e legvel. Cabe ressaltar que no existem funes complexas como por exemplo tomar gua ou trocar uma lmpada. No prximo captulo a linguagem C ser estudada em maior profundidade. A Linguagem C A linguagem C nasceu na dcada de 70, por Dennis Ritchie. O C derivado de uma outra linguagem: o B, criado por Ken Thompson. O B, por sua vez, veio da linguagem BCPL, inventada por Martin Richards. Uma boa referncia da linguagem por ser vista em [1]. Estrutura de um programa C Todo programa escrito em C composto por funes. Uma funo um bloco de programa onde so descritas as operaes que devem ser realizadas. Existe uma nica funo que deve estar presente em todos os programas, que a funo main( ), e o ponto de partida de execuo do programa. A sintaxe de uma funo a seguinte:

tipo_retorno nome_funo( parametros ) O seguinte exemplo mostra a sintaxe de um programa simples, que somente imprime na tela o valor de uma expresso aritmtica. Linha 1 2 3 4 5 6 7 8 9 10 11 Comando C #include <stdio.h> int main( void ) { int dado1, dado2, resp; dado1 = 20; scanf(%d, &dado2 ); /*Isto um comentrio*/ resp = dado1*dado2; printf(O valor da expresso %d, resp); return 0; }

Na linha 1, a diretiva de compilao #include faz o compilador adicionar o arquivo stdio.h ao cdigo do programa. Este arquivo adicionado contm prottipos de vrias funes de entrada e sada. A incluso necessria pois na linha 6 chamada a funo scanf( ), que faz a leitura do teclado de um nmero inteiro e atribui a varivel dado2; e na linha 9 chamada a funo printf( ), que faz a impresso do valor da expresso, calculada na linha 8, na tela do computador. Na linha 2 est declarada a funo main( ). Para este exemplo, a funo deve retornar um valor inteiro (int) e no recebe nenhum parmetro (void). O corpo da funo main delimitado pelo bloco { } , que tem incio na linha 4 e termina na linha 10. Qualquer cdigo fora deste bloco no ir pertencer a funo main( ). O uso de variveis necessrio para fazer a manipulao dos dados do programa. Na linha 4 so declaradas 3 variveis do tipo inteiro (variveis que somente podem armazenar valores inteiros). A varivel chamada dado1 inicializada na linha seguinte com o valor 20. A varivel dado2 lida do teclado pela chamada da funo scanf( ). O programa somente segue a execuo para o prximo comando quando o usurio digitar algum valor e pressionar a tecla <Enter>. Na linha 7 adicionado um comentrio ao programa, que ser ignorado pelo compilador na gerao do cdigo executvel. Comentrios so de grande importncia na documentao do cdigo fonte. Na linha 8 avaliada uma expresso de multiplicao, que consiste em armazenar na varivel resp o valor da multiplicao da varivel dado1 com dado2. O valor da expresso mostrado na tela pela chamada da funo printf( ). Ao final, o programa retorna o valor 0 ao sistema operacional, indicando que a finalizao do programa ocorreu de forma correta. Um programa pode ter qualquer nmero de funes. O uso de funes uma boa forma de estruturao do programa e facilita a reutilizao de cdigo. Variveis declaradas dentro de uma funo somente so visveis somente dentro da prpria funo. Variveis podem ter qualquer nome, desde que iniciem com letras, como por exemplo: a, dado, v_13df, teste, tmp, etc. No so permitidos caracteres especiais como -, +, *, etc, bem como acentuao. Aconselha-se dar nomes significativos as variveis, pois tornam o cdigo fonte mais legvel, como por exemplo: media, temp, opcao, resp, etc. Observa-se que comandos e declaraes de variveis so terminadas com ponto-e-vrgula. Caso algum ; for esquecido (erro de sintaxe), ser gerada uma mensagem de erro pelo compilador indicando a linha onde o erro ocorreu. Outra observao que o C "Case Sensitive", isto , maisculas e minsculas fazem diferena. Se for declarada uma varivel com o nome soma ela ser diferente de Soma, SOMA, SoMa ou sOmA. Da mesma maneira, os comandos do C if e for, por exemplo, s podem ser escritos em minsculas pois seno o compilador no ir interpret-los como sendo comandos, mas sim como variveis. Este mesmo programa poderia ser escrito de forma mais estruturada, colocando a operao de multiplicao em uma funo especfica.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

#include <stdio.h> int produto(int n1, int n2); int produto(int n1, int n2) { int resp; resp = n1 * n2; return resp; } int main( void ) { int dado1, dado2, resp; dado1 = 20; scanf(%d, &dado2 ); /*chamada da funcao produto passando dado1 e dado2*/ resp = produto(dado1, dado2); printf(O valor da expresso %d, resp); return 0; }

Neste exemplo, foi criada a funo multiplica, que recebe dois parmetros inteiros e retorna outro inteiro, representando o produto de n1 com n2. Esta funo chamada de dentro da funo main( ), na linha 18. Quando a funo chamada, a execuo do programa sai da funo main e vai para a funo produto e a varivel dado1 copiada na varivel n1 e a varivel dado2 copiada na varivel n2. Quando a funo produto retorna (linha 9), o valor de retorno atribudo a varivel resp na linha 18. Cabe lembrar que as variveis resp so locais funo onde foram declaradas, logo a varivel resp da funo produto( ) no a mesma da funo main( ). Quando a funo produto( ) retorna, a execuo continua na funo main( ). Na linha 3 declarado o prottipo da funo produto( ), que usada para indicar ao compilador da existncia da funo produto. A declarao do prottipo obrigatria caso a funo seja chamada antes de sua declarao, o que no ocorre neste exemplo.

3 Tipo de Dados 3.1 Tipos bsicos A linguagem C oferece vrios tipos bsicos para definio de valores do tipo caractere, inteiro e de ponto flutuante. Deve-se usar o tipo mais adequado ao dado que se deseja representar. A tabela a seguir ilustra os tipos, com respectivos tamanhos e representatividades.

Tabela de tipos bsicos Tipo char unsigned char short int unsigned short int int unsigned int float double

Espao ocupado 1 byte 1 byte 2 bytes 2 bytes 4 bytes 4 bytes 4 bytes 8 bytes

Representatividade -128 a 127 0 a 255 -32 768 a 32 767 0 a 65 535 -2 147 483 648 a 2 147 483 647 0 a 4 294 967295 10-38 a 1038 10-308 a 10308

A declarao de variveis segue o mesmo modelo dos exemplos anteriores. A inicializao pode ocorrer juntamente com a declarao da varivel. Varivel no inicializada leva a erros na execuo do programa. float a, b, c=10.4; char nome = 20, letra=m; unsigned char byte; Deve-se ter os seguintes cuidados no uso de variveis: -Deve-se garantir que no ser atribudo valor superior ao da representatividade de cada tipo, o que pode levar ao truncamento e alterao da informao armazenada; -A converso de nmeros inteiros para flutuantes ocorre de forma automtica e sem perda, porm o contrrio no; -Variveis no inicializadas contm lixo. int a, b, c; a = 2; c = a + b; /*b no foi inicializada e contm lixo*/ De forma complementar a definio de variveis, pode-se tambm definir strings que sero substitudas pelos seus identificadores toda vez que encontrados no cdigo fonte. Isso feito pela diretiva #define. No seguinte exemplo, o identificador o MAX_JOGADORES, e a string correspondente 5. #define MAX_JOGADORES 5 ... /* antes de ser compilada, esta linha ser transformada em if (cont<5)*/ if ( cont < MAX_JOGADORES ) /* comandos */ Este recurso deixa o cdigo mais legvel e uma tcnica muito usada em jogos. #define #define #define #define #define POWERUP_TYPE_HULL POWERUP_TYPE_SHIELD POWERUP_TYPE_QUAD POWERUP_TYPE_INVISIBLE POWERUP_TYPE_INVENSIBLE 1 2 3 4 5

Alm dos tipos bsicos, tambm existem os tipos estruturados, que permitem a definio de dados mais complexos.

3.2 Vetores e Strings Uma forma simples de implementar tipos de dados mais complexos por meio de vetores. Eles permitem que conjuntos de dados do mesmo tipo sejam definidos por uma nica varivel, como no seguinte exemplo. float vet[5] = {1.2, 0.09, 34, 1.01, 50000}; int tabela[2]; tabela[0] = 1000; tabela[1] = 88; Neste exemplo, vet um vetor com 5 posies para nmeros do tipo float. A inicializao de vetores tambm pode ocorrer juntamente com a declarao. Em C, a primeira posio do vetor a de ndice 0 e a ltima a de ndice N-1, como mostrado na inicializao do vetor de inteiros tabela. A atribuio tabela[2] = 90 causa invaso de memria pois a posio de ndice 2 no est definida. Deve-se observar que o tamanho dos vetores definido em tempo de compilao, ou seja, o compilador ir reservar espao suficiente na memria para comportar os vetores vet e tabela. Caso no se saiba de antemo o espao que ser necessrio para armazenar os dados, como por exemplo o nmero de jogadores que estaro conectados ao servidor, deve-se ento usar uma estratgia de alocao de memria em tempo de execuo (alocao dinmica). Em C, isso pode ser feito com o uso de ponteiros, que so variveis cujo contedo um endereo de memria. Para o exemplo acima, a verso com alocao dinmica se torna: float *vet; /* vet um ponteiro para float */ int *tabela; /* tabela um ponteiro para int */ vet = (float*)malloc(5*sizeof(float)); tabela = (int*) malloc(2*sizeof(int)); tabela[0] = 1000; tabela[1] = 88; Em termos de sintaxe, a diferena entre um ponteiro e uma varivel normal a presena do asterisco antes do nome da varivel. O operador sizeof( tipo ) retorna o nmero de bytes ocupado pelo tipo (ver tabela de tipos bsicos). A funo malloc( size ) aloca size bytes e retorna o endereo inicial da regio alocada. Este endereo retornado atribudo ao ponteiro que passa a apontar para a regio alocada. Ponteiros, alm de apontar para regies de memria alocadas, podem tambm apontar para outras variveis, e so de grande importncia na passagem de parmetros por referncia. float *pont; /*declara um ponteiro para float */ float var = 30; /*declara uma varivel com o valor de 30.0 */ pont = &var; /*faz pont apontar para o endereo da varivel var */ printf(%f, *pont); /*Imprime o contedo do ponteiro que vale 30 */ A representao de strings em C feita por meio de vetores. C no possui um tipo bsico especfico. Outra particularidade do C, que quando se aloca um string deve-se reservar um espao a mais para guardar um caractere terminador de string, o \0. Sem ele, no se pode saber qual o tamanho da string.

char str[10] = oi; Neste exemplo, str[0]=o, str[1]=i e str[2]=\0. C fornece diversas funes para manipulao de strings, como por exemplo strcat( ), que concatena duas strings, strcpy( ), que faz cpia de strings, strlen( ), que retorna o tamanho da string, gets (), que l uma string do teclado. Todas estas funes e muitas outras esto na biblioteca string.h. Caso alguma destas funes for usada, deve-se adicionar no topo do programa a diretiva: #include <string.h>

3.3 Estruturas Para definir tipos de dados complexos de tipos variados, C define o tipo struct, que permite aglomerar em um nico elemento diversos tipos bsicos ou complexos. A sintaxe de definio a seguinte: struct nome{ /* colocar aqui os tipos desejados */ /* colocar aqui os tipos desejados */ }; Um exemplo muito comum em jogos a definio de primitivas geomtricas. A definio de um ponto em 3D pode ser da seguinte maneira: struct ponto3D { float x, y, z; }; Com esta definio, o tipo struct ponto3D pode ser usado para armazenar pontos do espao 3D. O exemplo seguinte mostra a utilizao de estruturas. struct p1.x = p1.y = p1.z = p2.x = ponto3D p1, p2; /*define duas variveis do tipo struct ponto3D */ 20; /* atribui 20 ao campo x de p1 */ 1.002; 70; p1.x p1.z;

Para acessar os elementos da estrutura deve-se usar ponto. Caso a estrutura for alocada dinamicamente, deve-se usa o operador seta (->). struct ponto3D *p1; p1 = (struct ponto3D *) malloc(sizeof(struct ponto3D)); p1->x = 20; Outra caracterstica do C permitir criar nomes de tipos. No seguinte exemplo: typedef struct

{ float x, y, z; }ponto3D; define-se ponto3D como um tipo, o que facilita a futura utilizao: ponto3D *p1; p1 = (ponto3D *) malloc(sizeof(ponto3D)); p1->x = 20; Estruturas podem conter outras estruturas bem como pode-se tambm definir vetores de estruturas: ponto3D vet[100]; /*vetor com 100 posies do tipo ponto3D */ /*definio da estrutura quadrado compostas por 4 ponto3D e mais uma string para conter o nome do elemento */ typedef struct{ char nome[100]; ponto3D pontos[4]; }quadrado; A passagem de estruturas para funes semelhante aos outros tipos de dados. Neste exemplo a varivel quadro1 passada por referncia para a funo imprime. A funo imprime recebe somente o endereo da localizao da varivel quadro1. /* a definio da estrutura quadrado e ponto3D deve ser feita fora de main( ) pois a funo imprime tambm usa esta estrutura */ void imprime(quadrado *q) { int cont; printf("Nome da varivel: %s", q->nome ); for( cont=0; cont<4; cont++) { printf("%f ", q->pontos[cont].x); printf("%f ", q->pontos[cont].y); printf("%f ", q->pontos[cont].z); } } int main(void) { /*declarao da varivel quadro1 */ quadrado quadro1; /* eh passado para a funo imprime o endereo (&) da varivel quadrado, que deve ser inicializada */ imprime( &quadro1 );

return 0; } 4 Operadores Existem vrios tipo de operadores em C, que podem ser classificados, segundo sua funo, nos seguintes grupos:

Tipo do Operador Aritmticos +, -, *, /, % (mdulo) Atribuio = Incremento ++ -+= -= Relacionais == < , <= >, >= != Lgicos && || !

Exemplo f = a+b; c = a%b; a = 10; cont++; cont--; cont+=5 cont-=3 a==b a<=b a>b a!=b

Descrio Operaes aritmtica convencionais c recebe o resto da diviso inteira de a por b Inicializa a com 10 Incrementa cont em 1 Decrementa cont em 1 Incrementa cont em 5 Decrementa cont em 3 Testa se a igual a b Testa se a menor ou igual a b Testa se b menor que a Testa se a diferente de b E (and) lgico Ou (or) lgico Negao (not)

Exemplos de operadores relacionais e lgicos sero apresentados na seo seguinte.

5 Controle de fluxo Para efetuar tomada de decises, desvios condicionais e controle de laos de repetio, C fornece um amplo conjunto de construes para as mais diversas necessidades. O comando principal, que a base para os outros o if (se, em portugus). A sintaxe a seguinte. if (expresso for verdadeira) { /* bloco de comandos */ } ou

if (expresso for verdadeira) { /* bloco de comandos */ } else /*senao */ { /* bloco de comandos se expresso for falsa */ } Em C, uma expresso verdadeira se tiver valor diferente de 0 (zero) e falsa se for igual a 0. Suponha o seguinte exemplo: int a; scanf(%d, &a); if(a>5) printf( A eh maior que 5); else if(a<=5) printf( A eh menor ou igual a 5); Alm de operadores relacionais, pode-se tambm usar operadores lgicos if( (a < 4 && b <=10) || c!=6 ) { d -= 30; } Neste exemplo deve-se cuidar a precedncia dos parnteses. A expresso verdadeira em duas situaes, devido ao OU lgico: 1) se (a menor 4 E b menor igual 10) 2) se (c diferente 6) Quando o encadeamento de if-else se tornar muito grande, pode-se usar a estrutura switch, que torna o cdigo mais estruturado e legvel. A sintaxe a seguinte: switch ( expressao ) { case opcao1: /* comandos executados se expressao == opcao1 */ break; case opcao2: /* comandos executados se expressao == opcao2 */ break; default: /* se expressao for diferente de todos as opes anteriores */ break; }

O valor da expresso deve ser um nmero inteiro ou uma constante caractere. Caso expresso for igual a opcao1, sero executados todos os comandos at o comando break. A opo default opcional. Para tratar laos de repetio, pode-se usar o for(;;), while() ou do-while(). O comando for e while tem funcionalidades semelhantes, porm o for mais compacto: for(inicializao; condio; incremento while (condio) ) { { } } for(int i=0; i<=20; i++) int i=0; { while( i<= 20 ) printf(%d, i); { } printf(%d, i); i++; } Nos dois casos, inicialmente testada a condio. Se ela for verdadeira, o lao executa e a varivel i incrementada, de forma iterativa. Deve-se usar preferencialmente o for quando se sabe com certeza quantas iteraes vo ser executadas e o while quando no se tem esta informao. Deve-se ter cuidado para NO colocar ; aps o for ou while, pois o bloco do lao no mais executado (isso no causa erro de compilao). O comando do-while() muito semelhante ao while, com a diferena que o lao primeiramente executado para posterior teste condicional: int i=0; do{ printf(%d, i); }while(i<20);

7 Referncias Bibliogrficas [1] Kernighan, B., Ritchie, D. C, A linguagem de Programao Padro Ansi. Ed. Campus, 1990. [2] Schildt, H. C completo e total. Ed. Makron Books, 1991.

8 Apndices Nesta seo so apresentados 5 programas exemplo que mostram as principais caractersticas da linguagem C. No cabealho de cada exemplo existe uma descrio dos assuntos apresentados.

8.1 Exemplo 1 /* TOPICOS - impressao de mensagens na tela - leitura de valores inteiros e reais

- definicao de vetores de inteiros e caracteres - manipulacao de vetores - passagem de vetores para funes - lacos de repeticao */
#include <stdio.h> void imprime_vetor(int v[]) { int cont; printf("\nOs numeros digitados foram: /*imprime os 4 valores lidos for(cont=0; cont<4; cont++) { /* apos imprimir o numero, eh adicionado dois espacos em branco */ printf("%d } } int main(void) { int char int int a; str[20]; /*define um vetor com 19 posicoes uteis */ vet[4]; cont; /*define um vetor de inteiros com 4 posicoes */ float b; ", v[cont] ); */ ");

/* o caractere '\n' faz pular uma linha na tela*/ printf("\nDigite um numero inteiro e um float, separados por espaco e tecle <enter>:\n"); /*"%i" indica que a variavel a sera lida como inteira. */ /*"%f" indica que a variavel a sera lida como float. */ /* a funcao scanf recebe o endereco das variaveis a serem lidas */ scanf("%i %f", &a, &b); /* para formatar a saida do tipo float com 3 casas decimais, usar 0.3f */ printf("\nOs numeros foram: \ninteiro: %i \nfloat: /* limpa o buffer de teclado */ fflush(stdin); printf("\nDigite uma string com no maximo 19 caracteres\n"); gets(str); /* %s indica que a variavel str sera lida como uma string */ %0.3f\n", a, b);

printf("\nA string digitada foi: %s\n", str); /* limpa o buffer de teclado */ fflush(stdin); printf("\n\nDigite 4 numeros inteiros: for(cont=0; cont<4; cont++) { scanf("%d", &vet[cont] ); } /* chama funcao para imprimir o vetor */ imprime_vetor(vet); return 0; } "); /*faz a leitura de um vetor com 4 posicoes de inteiro */

8.2 Exemplo 2 /* TOPICOS - utilizacao de #defines - leitura de valores char - uso do comando switch */
#define KEY_UP #define KEY_DOWN #define KEY_LEFT #define KEY_EXIT #include <stdio.h> #include <conio.h> int main(void) { char opcao; /*define uma variavel char. */ 72 80 75 27

#define KEY_RIGHT 77

/* inicializa a varival opcao */ opcao = 0; printf("\nPressione alguma seta ou ESC para sair: "); while(opcao != KEY_EXIT ) { /* limpa o buffer de teclado */ fflush(stdin); /*le uma tecla */ opcao = getch();

//printf("%d ", opcao); switch(opcao) { case KEY_UP: printf("\n Seta para cima"); break; case KEY_DOWN: printf("\n Seta para baixo"); break; case KEY_LEFT: printf("\n Seta para esquerda"); break; case KEY_RIGHT: printf("\n Seta para direita"); break; } } return 0; }

8.3 Exemplo 3 /* TOPICOS - uso de funcoes da biblioteca string.h - representacao numerica de caracteres - conversao de caracteres para maiusculo - manipulacao de caracteres dentro de vetores (strings) */
#include <stdio.h> #include <string.h> /* Cada letra tem um numero decimal associado. Para descobrir o valor, pode-se usar printf("%d", variavel)*/ void valor_decimal(void) { char letra1='a', letra2='A', letra3='5'; printf("\nO valor da letra a eh: %d", letra1); printf("\nO valor da letra A eh: %d", letra2); printf("\nO valor da diferenca eh %d", letra1-letra2); printf("\nO valor da letra 5 eh: %d", letra3); }

void maiusculo(char *str) { int i=0; /*enquanto nao encontrar o final da string, troca as letras para maiusculo.*/ while( str[i] != '\0' ) { str[i] = str[i]-32; /* outra solucao eh str[i] = str[i]-('a'-'A');*/ i++; } } int main(void) { int a, tam; char str[100]; /*copia a string "teste" em str */ strcpy(str, "teste"); /*verifica o tamanho de str */ tam = strlen(str); printf("\n O tamanho de str eh %d", tam); /*Varre a string e troca as letras 'e' por 'a' Observar a diferenca entre o operador de atribuicao e comparacao*/ for(a=0; a<tam; a++) { if(str[a]=='e') /* "==" -> coparacao logica */ str[a] = 'a'; /* "=" -> atribuicao */ } /*imprime a nova string alterada*/ printf("\nA nova string eh %s", str); /*adiciona uma nova string ao final de str */ strcat(str, ".exe"); printf("\nA nova string eh %s", str); /*trunca a string para 2 caracteres colocando o caractere '\0' na posicao 2*/ str[2]='\0'; printf("\nA nova string truncada eh %s", str); /*imprime o valor decimal de algumas letras. Tambem vale para numeros */ valor_decimal();

/*chama a funcao maiusculo passando uma referencia da string. Nao precisa colocar o & antes de str pois somente str ja igual ao endereco da primeira posicao do vetor = &str[0].*/ maiusculo(str); printf("\nA nova string maiuscula eh %s", str); return 0; }

8.4 Exemplo 4 /* TOPICOS - definicao de tipos de dados - passagem de tipos por valor - passagem de tipos por referencia - passgem de strings. - indexacao de estruturas por ponteiros - leitura de valores reais - ponteiros para tipos definidos */
#include <stdio.h> /*como a definicao da estrutura foi feita fora da funcao main, pode ser acessada de qualquer parte do programa */ typedef struct { float x; float y; }ponto2D; /*funcao que recebe uma referncia de uma variavel do tipo ponto2D Como a passagem eh por referencia, qualquer alteracao nesta funcao ira alterar o valor de p1 na funo main. p eh um ponteiro void altera_referencia(ponto2D *p) { p->x = 10; p->y = 10; } /*neste caso, p eh possado por valor. Para alterar p1 de main deve-se retornar o novo valor */ ponto2D altera_valor(ponto2D p) { p.x = 1000; p.y = 1000; return p; */

} void imprime(ponto2D p, char *msg) { /* o argumento %0.2f indica que a variavel sera impressa com duas casas decimais */ printf("%s = (%.2f, %.2f)\n", msg, p.x, p.y); } int main (void) { /*definicao de p1 do tipo struct ponto2D*/ ponto2D p1; printf("Digite as coordenadas do ponto(x y): "); /* na funcao scanf, deve-se passar o endereco "&" das variaveis que serao lidas */ scanf("%f %f", &p1.x, &p1.y); /* chama a funcao imprime passando uma copia de p1 e uma mensagem*/ imprime(p1, "O ponto lido foi "); altera_referencia(&p1); p1 = altera_valor(p1); /* eh passado o endereco da varival p1 */ /* eh passado uma copia da varival p1 */ imprime(p1, "O ponto alterado eh "); imprime(p1, "O ponto alterado eh "); return 0; }

8.5 Exemplo 5 /* TOPICOS - definicao de tipos de dados - alocacao dinamica - ponteiros para tipos definidos - vetores de ponteiros para estruturas - funcoes matematicas */
#include <stdio.h> #include <math.h> #include <stdlib.h> #define NUM_PONTOS 8 /*funcao printf() */ /*funcao seno e rand() */ /*funcao malloc() */

/*como a definicao da estrutura foi feita fora da funcao main, pode ser acessada de qualquer parte do programa */ typedef struct { float x; float y; }ponto2D; void imprime(ponto2D *p, int indice) { /* o argumento %0.2f indica que a variavel sera impressa com duas casas decimais */ printf("\n Ponto %d = (%.2f, %.2f)\n", indice, p->x, p->y); } int main (void) { int i; /*definicao de um vetor de ponteiros para ponto2D*/ ponto2D *p1[NUM_PONTOS]; /*agora deve-se fazer a alocacao dos pontos */ for(i=0; i< NUM_PONTOS; i++) { p1[i] = (ponto2D*)malloc(sizeof(ponto2D)); } /*faz a inicializacao dos pontos com valores randomicos */ for(i=0; i< NUM_PONTOS; i++) { p1[i]->x = (float)sin(i); p1[i]->y = (float)(rand()%100); /* valor randomico entre 0 e 100 */ } /*faz a impressao dos pontos */ for(i=0; i< NUM_PONTOS; i++) { imprime(p1[i], i); } return 0; }

Вам также может понравиться