You are on page 1of 59

PROJETO AGIT | PIC

PIC

Apostila do Aluno

Luiz Rafael de Souza / Michel Fornaciali

PROJETO AGIT | PIC

1. Introduo
A linguagem C, uma linguagem adequada programao estruturada, foi criada por Dennis Ritchie, em 1972. Com o sucesso desta linguagem em 1980 j existiam vrios compiladores C, desta forma a linguagem no se restringia ao UNIX, sistema operacional que foi reescrito em C. As caractersticas da linguagem C so: portabilidade, modularidade, compilao separada, recursos de baixo nvel, gerao de cdigo eficiente, confiabilidade, regularidade, simplicidade e facilidade de uso. A linguagem C segue algumas etapas para a gerao do executvel, estas etapas so:

Editor (mdulo fonte em C)

Pr-processador (novo fonte expandido)

Compilador (arquivo objeto)

Lincador (executvel)
Figura 01

2. Tipos de dados e declarao de variveis


Uma linguagem de programao precisa de uma unidade bsica para representar o conhecimento. Tendo em vista que os programas trabalham com nmeros, estes precisam ser representados, armazenados e manipulados. A linguagem ANSI C utiliza tipos bsicos para representar, armazenar e manipular dados, que podem ser nmeros Inteiros, nmeros Reais e Caracteres. Para uma compreenso maior do tamanho que cada tipo ter ou suas faixas de valores vide anexo.

2.1. Tipos de Dados


A linguagem C possui 5 tipos bsicos: int float

PROJETO AGIT | PIC double char void

E para cada um destes tipos existem seus modificadores, desta forma podendo restringir ou ampliar sua faixa de valores: signed unsigned long short

Os modificadores no so aplicados como um todo para cada tipo, o float no pode ser modificado, double pode ser modificado apenas pelo long e o int pode ser modificado por todos. Tipos int assumem o tamanho indicado pela maquina, ou seja, se a maquina for de 16 bits o int provavelmente ter 16 bits, em caso de uma maquina de 32 bits o mesmo ter 3 bits. Os modificadores short e long possuem algumas restries: short int e int devem ocupar pelo menos 16 bits long int pelo menos 32 bits short int no pode ser maior que int, que no pode ser maior que long int.

Unsigned serve para indicar que os valores so sem sinais. Os inteiros que so modificados usando o unsigned podem assumir apenas valores positivos. Para uma compreenso maior do tamanho que cada tipo ter ou suas faixas de valores vide anexo. A linguagem ANSI C tambm permite que o usurio crie seus prprios tipos de dados usando estruturas, unies e enumeraes. Uma estrutura o agrupamento de varias varivel e para declarar uma estrutura usamos a palavra-chave struct e os elementos que iro compor esta estrutura so chamados de membros, estes membros no necessariamente devem ser do mesmo tipo.
#include <stdio.h> struct Ponto{ int x; int y; char z; }; int main() { struct Ponto p1; struct Ponto p2; struct Ponto p3 = {10,11,'w'}; /*Inicializao dos valores*/

PROJETO AGIT | PIC


p1.x = 1; p1.y = 2; p1.z = 'z'; /*Outra maneira de inicializar os valores*/ printf("p1. x:%d / p1.y:%d / p1.z:%c \n",p1.x,p1.y,p1.z); /*Copia da struct p1 para a p2*/ p2 = p1; printf("p2. x:%d / p2.y:%d / p2.z:%c \n",p2.x,p2.y,p2.z); printf("p3. x:%d / p3.y:%d / p3.z:%c \n",p3.x,p3.y,p3.z); return(0); }

Console:
p1. x:1 / p1.y:2 / p1.z:z p2. x:1 / p2.y:2 / p2.z:z p3. x:10 / p3.y:11 / p3.z:w

Quando as variveis do tipo da struct so declaradas necessrio adicionar a palavra-chave struct para que indique que aquele tipo refere-se a um tipo de dado criado pelo programador, isto pode ser suprido caso seja usado o typedef e desta forma adicionando o nome na criao da struct.
#include <stdio.h> typedef struct { int x; int y; char z; }Ponto; int main() { Ponto p1; Ponto p2; Ponto p3 = {10,11,'w'}; ... return(0); }

Console:
p1. x:1 / p1.y:2 / p1.z:z p2. x:1 / p2.y:2 / p2.z:z p3. x:10 / p3.y:11 / p3.z:w

PROJETO AGIT | PIC Uma unio bem parecida com uma estrutura, mas pela diferena a struct aloca um espao de memoria igual soma de todos os tipos de seus elementos, enquanto a union aloca espao de memoria igual ao tamanho do elemento de maior tipo e para sua declarao usamos a palavra-chave union.
#include <stdio.h> union Ponto{ int x; int y; char z; }; int main() { union Ponto p1; union Ponto p2; union Ponto p3 = {10,11,'w'}; /*Inicializao dos valores*/ p1.x = 1; p1.y = 2; p1.z = 'z'; /*Outra maneira de inicializar os valores*/ printf("p1. x:%d / p1.y:%d / p1.z:%c \n",p1.x,p1.y,p1.z); /*Copia da struct p1 para a p2*/ p2 = p1; printf("p2. x:%d / p2.y:%d / p2.z:%c \n",p2.x,p2.y,p2.z); printf("p3. x:%d / p3.y:%d / p3.z:%c \n",p3.x,p3.y,p3.z); return(0); }

Console:
p1. x:122 / p1.y:122 / p1.z:z p2. x:122 / p2.y:122 / p2.z:z p3. x:10 / p3.y:10 / p3.z:

Enumerao possui um nmero de valores finitos definidos pelo programador. A varivel que for declarada com um tipo enumerador s poder assumir os valores conhecidos pelo enumerador. Para criar um enumerador usamos palavra-chave enum.
#include <stdio.h> typedef enum{ VERDE, AZUL, ROXO, AMARELO, VERMELHO, }cores; /* /* /* /* /* 0 1 2 3 4 */ */ */ */ */

PROJETO AGIT | PIC


int main() { cores tipo_cores; tipo_cores = VERDE; if(tipo_cores if(tipo_cores if(tipo_cores if(tipo_cores if(tipo_cores == == == == == 0){printf("COR 1){printf("COR 2){printf("COR 3){printf("COR 4){printf("COR ATRIBUIDA ATRIBUIDA ATRIBUIDA ATRIBUIDA ATRIBUIDA VERDE!!!!");} AZUL!!!!");} ROXO!!!!");} AMARELO!!!!");} VERMELHO!!!!");}

tipo_cores = AMARELO; if(tipo_cores if(tipo_cores if(tipo_cores if(tipo_cores if(tipo_cores return(0); } == == == == == 0){printf("COR 1){printf("COR 2){printf("COR 3){printf("COR 4){printf("COR ATRIBUIDA ATRIBUIDA ATRIBUIDA ATRIBUIDA ATRIBUIDA VERDE!!!!\n");} AZUL!!!!\n");} ROXO!!!!\n");} AMARELO!!!!\n");} VERMELHO!!!!\n");}

Console:
COR ATRIBUIDA VERDE!!!! COR ATRIBUIDA AMARELO!!!!

Enumerao no possui declarao de tipos nos membros, no so divididos usando ; e a ordem de declarao definir o valor de cada membro caso o programador no defina um valor default.
#include <stdio.h> typedef enum{ VERDE, AZUL = 10, ROXO, AMARELO = 15, VERMELHO, }cores; int main() { cores tipo_cores; tipo_cores = ROXO; if(tipo_cores if(tipo_cores if(tipo_cores if(tipo_cores if(tipo_cores == == == == == 0){printf("COR ATRIBUIDA VERDE!!!!\n");} 10){printf("COR ATRIBUIDA AZUL!!!!\n");} 11){printf("COR ATRIBUIDA ROXO!!!!\n");} 15){printf("COR ATRIBUIDA AMARELO!!!!\n");} 16){printf("COR ATRIBUIDA VERMELHO!!!!\n");} /* 0 */ /* 11 */ /* 16 */

tipo_cores = VERMELHO;

PROJETO AGIT | PIC


if(tipo_cores if(tipo_cores if(tipo_cores if(tipo_cores if(tipo_cores return(0); } == == == == == 0){printf("COR ATRIBUIDA VERDE!!!!\n");} 10){printf("COR ATRIBUIDA AZUL!!!!\n");} 11){printf("COR ATRIBUIDA ROXO!!!!\n");} 15){printf("COR ATRIBUIDA AMARELO!!!!\n");} 16){printf("COR ATRIBUIDA VERMELHO!!!!\n");}

Console:
COR ATRIBUIDA ROXO!!!! COR ATRIBUIDA VERMELHO!!!!

2.2. Declarao e inicializao de variveis e constantes


Existem 3 nveis de escopo para a declarao de variveis: Global Todas as funes acessam Local Apenas o bloco de funo onde foi declarado pode acessar Esttica Conserva o valor durante a execuo do programa, similar a variveis globais, mas so reconhecidas apenas no escopo da funo que a declarou. Parmetros Apenas a funo que esta recebendo pode acessar

#include <stdio.h> int main() { int _valor_int_1 = 0; int valor_int_2 = 0; float valor_float_1 = 0.0; char valor_char_1 = 'a'; }

Existem algumas boas praticas para a elaborao do nome da varivel: 1 regra) O nome deve comear com uma letra ou sublinhado ( _ ) e os outros caracteres que compem o nome devem ser letras, nmeros ou sublinhado ( _ ). 2 regra) O nome da varivel no pode ser o mesmo que uma palavra reservada da linguagem ANSI C ou tambm um nome de funo declarada pelo programador ou

PROJETO AGIT | PIC existente em alguma biblioteca do ANSI C, para verificar as palavras reservadas existentes no padro ANSI C vide anexo. No podemos considerar que toda varivel declarada ser iniciada com um valor prdefinido pelo compilador. Em geral costuma-se assumir que uma varivel recm declarada automaticamente iniciada com zero ou vazio: Isto no e verdade. Uma varivel recm declarada ira ocupar uma regio de memria e conter o valor daquela regio, que pode ser desde zero, vazio ou qualquer outro valor. necessrio, ento, que inicialize a mesma. O operador de atribuio =.
#include <stdio.h> int main() { int _valor_int_1 = 0; int valor_int_2 = 0; float valor_float_1 = 0.0; char valor_char_1 = 'a'; }

Para um bom entendimento durante a leitura do cdigo, boas praticas podem ser adotadas: usar os nomes das variveis somente em minscula e para as constantes somente maisculas, lembrando que a linguagem ANSI C case sensitive, o que significa que diferencia entre letras maisculas e minsculas.
#include <stdio.h> int main() { int valor1 = 0; int valor2 = 0; int valor3 = valor1+VaLoR2 */ } /* varivel VaLoR2 no existe

Console:

..\Arquivo.c:9:23: error: 'VaLoR2' undeclared (first use in this function)

PROJETO AGIT | PIC Outro tipo de declarao a de constantes, ou seja, seu valor considerado fixo pelo compilador e no mudar em tempo de execuo. Constantes podem ser dos tipos convencionais, hexadecimais, octais, string e barra invertida. Para declarar uma constante podemos usar const ou a diretiva #define.

#include <stdio.h> #define CONSTANTE 100 int main() { const int valor1 = CONSTANTE; int valor2 = 1; int valor3 = valor1+valor2; */ printf("valor3: %d",valor3); return(0); } /* varivel VaLoR2 no existe

Console:

valor3: 101

Estas so as regras e tipos para a declarao de variveis e constantes.

3. Operadores
Os operadores na linguagem ANSI C so usados para realizar operaes aritmticas, comparaes e expresses.

3.1.

Precedncia de operadores

Em ANSI C existe precedncia entre os operadores. A tabela abaixo exibe estes operadores. Maior precedncia
() [] -> ! ~ ++ -- . -(unrio) (cast) *(unrio) &(unrio) sizeof

*/% +<< >> <<= >>= == != &

PROJETO AGIT | PIC


^ | && || ? = += -= *= /=

Menor precedncia

Esta precedncia define qual a ordem que os operadores sero executados e esta precedncia pode alterar o resultado da expresso que estiver sendo montada. ...
result result result result = = = = 2+5*7; /* Resultado da expresso 37*/ (2+5)*7; /* Resultado da expresso 49*/ 2+2+2+2/4; /* Resultado da expresso 6,5 como o tipo int ser exibido 6*/ (2+2+2+2)/4; /* Resultado da expresso 2*/

...

Console:
2+5*7 = 37 (2+5)*7 = 49 2+2+2+2/4 = 6 (2+2+2+2)/4 = 2

Para alterar a ordem de precedncia podemos usar os parnteses ( e), assim tornando as expresses mais legveis. A Linguagem ANSI C avalia os tipos de dados envolvidos em determinada expresso. Quando forem diferentes entre eles, avalia se possvel convert-los. Caso a converso seja possvel, ser feita, a converso do contrario exibido uma mensagem de erro pelo compilador. As regras para converso so: 1) char convertido para int 2) float convertido para double 3) se um dos valores for long double ento o resultado ser convertido long double 4) se um dos valores for double ento o resultado ser convertido double 5) se um dos valores for long ento o resultado ser convertido long 6) se um dos valores for unsigned ento o resultado ser convertido unsigned

3.2.

Operadores Aritmticos

Os operadores aritmticos so os mesmos para muitas linguagens, estes so usados para realizar operaes matemticas. Os operadores em ANSI C so: + ADIO (inteiro e ponto flutuante)

PROJETO AGIT | PIC - SUBTRAO (inteiro e ponto flutuante) * MULTIPLICAO (inteiro e ponto flutuante) / DIVISO (inteiro e ponto flutuante) % RESTO DA DIVISO (inteiros) ++ INCREMENTO (inteiro e ponto flutuante) -- DECREMETNO (inteiro e ponto flutuante)

#include <stdio.h> int main() { ... result result result result result result result result result result result result result ... } = 2 + 2; //Adio de inteiros += 2; // result = result + 2; = 2.2 + 2.2; //Adio de ponto flutuante = 2 - 2; //Subtrao de inteiros -= 2; //result = result 2; = 2.2 - 2.2; //Subtrao de ponto flutuante = 2 * 2; //Multiplicao de inteiros *= 2; //result = result *2; = 2.2 * 2.2; // Multiplicao de ponto flutuante = 2 /2; //Diviso de inteiros /= 2; //result = result/2; = 2.2/2.2; //Diviso de ponto flutuante = 2 %2; //Resto da diviso de inteiros

3.3.

Operadores lgicos e relacionais

Os operadores lgicos e relacionais realizam comparaes entre variveis e valores, variveis e variveis, variveis e constantes, valores e constantes e por fim constantes e constantes. Estes operadores tambm se mantem para vrias linguagens. Em ANSI C eles so: Operadores relacionais: > maior que < menor que >= maior ou igual que <= menor ou igual que == igual que != no igual

#include <stdio.h> int main()

PROJETO AGIT | PIC


{ int valor1 = 0; int valor2 = 1; int result = 0; if(valor2 > 0){printf("VERDADEIRO\n");} /*Se for verdade exibe VERDADEIRO*/

printf("Falso: %d \n", valor1 > valor2); printf("Falso: %d \n", valor1 < valor2); result = 2 > 3; printf("Falso: %d \n", result); result = 2 < 3; printf("Verdadeiro: %d \n", result); result = 2 <= 3; printf("Verdadeiro: %d \n", result); result = 2 <= 2; printf("Verdadeiro: %d \n", result); result = 2 >= 3; printf("Falso: %d \n", result); result = 2 >= 2; printf("Verdadeiro: %d \n", result); result = 2 == 2; printf("Verdadeiro: %d \n", result); result = 2 == 3; printf("Falso: %d \n", result); result = 2 != 3; printf("Verdadeiro: %d \n", result); result = 2 != 2; printf("Falso: %d \n", result); return(0); }

Console:
VERDADEIRO Falso: 0 Falso: 1 Falso: 0 Verdadeiro: Verdadeiro: Verdadeiro: Falso: 0 Verdadeiro: Verdadeiro: Falso: 0 Verdadeiro: Falso: 0

1 1 1 1 1 1

Em ANSI C, valores booleanos como Verdadeiro (true) e Falso (false) so reconhecidos como 0 (verdadeiro) e 1 (falso).

PROJETO AGIT | PIC

Operadores lgicos: && || ! AND - todas as condies devem ser verdadeiras OR - apenas uma condio deve ser verdadeira NOT - inverte o resultado da condio

#include <stdio.h> int main() { int valor1 = 0; int valor2 = 1; printf("%d printf("%d AND %d %d\n", valor1,valor2, valor1 && valor2); OR %d %d\n", valor1,valor2, valor1 || valor2);

if(valor1 < 1 && valor2 > 0){printf("Ambas as condies so verdade\n");} if(valor1 < 1 || valor2 <= 0){ printf("Uma condio verdade\n");} if(!(valor1 > 1)){ printf("Condio falsa, mas o NOT inverte para verdadeiro\n");} if(!(valor1 < 1)){printf("Condio verdadeira, mas o NOT inverte para falso\n");}/*No executa pois foi invertido para falso*/ return (0); }

Console:
0 AND 1 0 0 OR 1 1 Ambas as condies so verdade Uma condio verdade Condio falsa, mas o NOT inverte para verdadeiro

3.4.

Operadores bit-a-bit

Podemos realizar operaes lgicas bit-a-bit, ou seja, o nmero e reconhecido por sua forma binaria e ento executada a operao em cada um de seus bits. & AND - todas as condies devem ser verdadeiras | OR - apenas uma condio deve ser verdadeira ^ XOR - inverte o resultado da condio ~ NOT << Deslocamento de bits a esquerda >> Deslocamento de bits a direita

PROJETO AGIT | PIC

3.5.

Operador cast

Podemos converter o resultado de uma expresso para o tipo que queremos. Isto possvel usando cast ou modelador.
#include <stdio.h> int main() { int x,y; x=y=2; printf("%d / %d / 3 = %f",x,y,(float)x/y/3); return (0); }

Console:
2 / 2 / 3 = 0.333333

4. Entrada e sada de dados


A linguagem ANSI C nos disponibiliza mecanismos de entrada e sada (I/O), desta forma possvel inserir valores usando um dispositivo de entrada de dados, por exemplo, o teclado no programa desenvolvido e obter uma sada de dados, por exemplo, o monitor, do mesmo.

4.1.

Entrada de dados

Os comandos de entrada so: scanf, getchar,getch,getche e gets. Vamos explicar e exemplificar cada um deles, mas antes uma diferena dentre estes comandos. Alguns comandos so usados para receber strings, ou seja, sequncia de caracteres. Outros so usados para receber apenas um nico caractere. Outros, ainda, podem ser formatados para receber outros tipos de dados. O comando scanf usado para ler um valor de entrada. Deve-se especificar a varivel que ir receb-lo e seu tipo, ou seja, no prprio comando definido o tipo de dado de entrada. Em resumo com a funo scanf possvel formatar a entrada que ser recebida.

#include <stdio.h> int main() { char ch_1,ch_2;

PROJETO AGIT | PIC


int in_1, in_2; printf("Digite dois caracteres:\n"); fflush(stdout); scanf("%c %c",&ch_1, &ch_2); printf("Digite dois nmeros inteiros:\n"); fflush(stdout); scanf("%d %d",&in_1, &in_2); if(in_1 > 0 && in_2 > 0){printf("Ambos os valores so maiores que zero!!!!!!\n");} else{printf("Um ou mais valores so menores que zero!!!!!!\n");} printf("Os nmeros digitados foram: %d %d \n", in_1, in_2);

return (0); }

Console:
Digite dois caracteres:qq Digite dois nmeros inteiros:12 -1 Um ou mais valores so menores que zero!!!!!! Os nmeros digitados foram: 12 -1

No scanf indicamos o endereo da varivel que armazenar o valor digitado, para isto usado o &.

Figura 02. Endereamento Tabela

PROJETO AGIT | PIC Quando codificamos &x e &y estamos dizendo a posio e memria, ou seja, o endereo onde o valor esta armazenada e quando codificamos x e y estamos acessando o valor da posio de memria. Vamos ilustrar de uma forma computacional:

Figura 03. Endereamento pilha

Aps digitar os valores usando o endereo da varivel ento conhecida a posio de memria que ira armazenar o valor digitado. A figura acima ilustra a hiptese de terem sido digitados os valores 5, para a varivel y, e 3 para a varivel z. Onde 1001002 referem-se a C4 e 1001004 refere-se E7. Importante: No confundir o & de endereo de memria com o & operador bit-abit AND. Outra funo de entrada usada para ler caracteres o getchar, que a funo original do UNIX. Ela armazena o valor digitado em uma rea de memoria intermediaria at que a tecla Enter seja pressionada, e ento retorna o contedo digitado.
int main() { char ch; printf("Digite um caractere:\n"); fflush(stdout); ch = getchar(); printf("O caracter digitado foi: %c \n", ch); return (0); }

Console:

PROJETO AGIT | PIC


Digite um caractere: a O caracter digitado foi: a

Com a funo getchar temos um problema em potencial no padro ANSI C, pois esta funo deveria ser implementada de uma forma iterativa, mas isto raramente ocorre. Ento esta funo seguiu o padro UNIX, de onde originaria, onde existia uma rea de memria (buffer) linear para os terminais de entrada, onde os valores digitados eram armazenados at que a tecla ENTER fosse pressionada e aps isto a entrada era enviada para o computador. Isto causa um problema para ambientes iterativos, pois ficam caractres neste buffer esperando o ENTER ser pressionado. recomendado que usemos duas alternativas para a funo getchar: So as funes getch e getche. Os prottipos para estas funes esto definidas na biblioteca CONIO.H. A funo getch captura os caractres inseridos sem exibi-los enquanto que a funo getche tem o mesmo funcionamento, mas com o diferencial de exibir o que foi digitado na tela. As funes mencionadas so usadas especificamente para capturar caracteres. Para que seja possvel capturar uma cadeia de caracteres necessrio usar uma repetio de fluxo, ou seja, um loop.
#include <stdio.h> int main() { char c[10],c1; int i;

printf("Digite dois valor inteiro:"); fflush(stdout); for(i=0; i<10;i++){ scanf("%c", &c1); fflush(stdin); c[i] = c1; } c[10] = '\0'; printf("String digitada: %s", c); return (0); }

Console:
Digite dois valor inteiro:a a a a

PROJETO AGIT | PIC


a a a a a a String digitada: aaaaaaaaaa

#include <stdio.h> int main() { char c[10],c1; printf("Digite dois valor inteiro:"); fflush(stdout); for(int i=0; i<10;i++){ c[i] = getchar(); fflush(stdin); } printf("String digitada: %s", c); return (0); }

Console:
Digite dois valor inteiro:a a a a a a a a a a String digitada: aaaaaaaaaa

Podemos usar a funo gets para capturar uma cadeia de caracteres digitada, ou seja, uma string.
#include <stdio.h> #include <string.h> int main() { int x,y,z; char str[100]; printf("Digite uma frase:"); gets(str); printf("A frase digitada foi -> %s e possui a quantidade de caracteres: %d",str, strlen(str));

PROJETO AGIT | PIC


return (0); }

Console:
Digite uma frase: Testando A frase digitada foi -> Testando e possui a quantidade de caracteres: 8

A funo gets armazena a entrada no endereo de memria indicado em seu parmetro e a funo retorna um ponteiro, Figuras 1 e 2, para a mesma posio de memria. O prottipo desta funo existe na biblioteca STDIO.H.

4.2.

Sada de dados

Os comandos de sada so: printf e puts e vamos explicar e exemplificar cada um deles, mas antes uma diferena dentre estes comandos. A funo puts usada para exibir strings, mas no possvel formatar sua sada ou imprimir valores, por este motivo sua execuo acaba sendo mais rpida em comparao a funo printf que possvel formatar a sada.
#include <stdio.h> #include <string.h> int main() { int x,y,z; char str[100]; printf("Digite uma frase:"); gets(str); printf("A frase digitada foi -> %s e possui a quantidade de caracteres: %d",str, strlen(str)); return (0); }

A funo printf nos permite aumentar a preciso do valor que ser exibido isto possvel incluindo no campo de formato, indicado pela porcentagem (%).
#include <stdio.h> int main() { float x = 2.22; char y[] = "Teste_teste"; printf("%f \n",x); printf("%.4f \n",x); preciso .4*/ printf("%-4f \n",x); 4*/ printf("%04f \n",x); 04*/ printf("%5.7f \n",x); /*Especificador de /*Especificador de preciso /*Especificador de preciso /*Especificador de preciso

PROJETO AGIT | PIC


5.7*/ printf("%5.7s \n",y); 5.7*/ return (0); } /*Especificador de preciso

Console:
2.220000 2.2200 2.220000 2.220000 2.2200000 Teste_t

O especificador de preciso usado para definir a largura mnima de um determinado campo a partir de seu tipo de dado. O especificador de preciso pode ser identificado verificando o campo de formato, mais especificamente o valor entre o porcentagem e o tipo de dado.

5. Fluxo de Execuo
Podemos mudar o fluxo de execuo do programa que ser executado de acordo com uma condio, repetio ou salto.

5.1.

Desvios condicionais

Em ANSI C temos os comandos de desvios condicionais if e switch, ambos funcionam de forma similar. O comando if necessita de uma expresso que, caso seja satisfeita, o comando ou o bloco de comandos sero executados, ou seja, o fluxo de comando ira sofrer um desvio ou no.
#include<stdio.h> int main(int argc, char** argv) { int pos = 0; do{ printf("Digite um numero entre 0 e 10:"); scanf("%d", &pos); if(pos>0 && pos<10){ puts("Valor no esta no intervalo de 0 at 10. \nPor favor, digite novamente."); } }while(pos < 0 && pos > 10); printf("Valor digitado foi: %d", pos);

PROJETO AGIT | PIC


return (0); }

Uma vez que a expresso verdadeira ento o bloco de funo associado ao comando if ter seu contedo executado, caso a expresso seja falsa ento no ser executado e o comando else ser executado. Lembrando que o comando else no obrigatrio.
#include<stdio.h> int main(int argc, char** argv) { int pos = 0; do{ printf("Digite um numero entre 0 e 10:"); scanf("%d", &pos); if(pos < 0 && pos >10){ puts("Valor no esta no intervalo de 0 at 10. \nPor favor, digite novamente."); }else{ puts("Valor esta no intervalo de 0 at 10.");} }while(pos < 0 && pos >10); puts("Fora do do-while!!!!!!"); return (0); }

Podemos ter vrios ifs encadeados com ou nenhum else associado a eles, mas o else, quando existir, deve estar aplicado a um comando if diretamente.
#include<stdio.h> int main(int argc, char** argv) { int pos = 0; do{ printf("Digite um nmero entre 0 e 10:"); fflush(stdout); scanf("%d", &pos); if(pos < 0){puts("Valores negativos. \n Por favor, digite novamente."); } if(pos > 10){puts("Valor acima de 10. \n Por favor, digite novamente. ");} }while(pos < 0 || pos > 10); puts("Valor return (0); } valido. Obrigado!!!!!!");

Console:
Digite um nmero entre 0 e 10: 11 Valor acima de 10.

PROJETO AGIT | PIC


Por favor, digite novamente. Digite um nmero entre 0 e 10: -1 Valores negativos. Por favor, digite novamente. Digite um nmero entre 0 e 10: 7 Valor valido. Obrigado!!!!!!

Os operadores usados em comparaes entre valores so: == , != , <= ,>= , < e >. O ANSI C nos disponibiliza outro comando para realizar estes tipos de comparaes e este comando o switch. O switch recebe um determinado valor como parmetro, caractere ou inteiro, e ento ele ir executar o case cujo valor seja igual ao respectivo valor do parmetro.
#include <stdio.h> int main() { int x; printf("Digite um valor:"); fflush(stdout); scanf("%d",&x); switch(x){ case 1: printf("Case 1 foi acessado\n"); case 2: printf("Case 2 foi acessado\n"); case 3: printf("Case 3 foi acessado\n"); } return (0); }

Console:
Digite Case 1 Case 2 Case 3 um valor:1 foi acessado foi acessado foi acessado

Podemos adicionar o default caso nenhum dos cases seja executado, mas o default no obrigatrio.
#include <stdio.h> int main() { int x; printf("Digite um valor:"); fflush(stdout); scanf("%d",&x); switch(x){ case 1:

PROJETO AGIT | PIC


printf("Case 1 foi acessado\n"); case 2: printf("Case 2 foi acessado\n"); case 3: printf("Case 3 foi acessado\n"); default: printf("Default foi acessado"); } return (0); }

Console:
Digite um valor:4 Default foi acessado

Os exemplos acima, referentes ao comando switch, possuem um problema referente ao acesso dos cases, vamos supor que fosse digitado o valor 2, ento seria exibido:
Case 2 foi acessado Case 3 foi acessado Case default foi acessado

Pois uma vez que o case foi acessado, assim que finalizar sua execuo os outros cases subsequentes sero acessados ao termino do mesmo. Ao final de cada case necessrio adicionar o comando break para que o case subsequente no seja executado.
#include <stdio.h> int main() { int x; printf("Digite um valor:"); fflush(stdout); scanf("%d",&x); switch(x){ case 1: printf("Case 1 foi acessado"); break; case 2: printf("Case 2 foi acessado"); break; case 3: printf("Case 3 foi acessado"); break; default: printf("Default foi acessado"); break; } return (0); }

PROJETO AGIT | PIC Console:


Digite um valor:2 Case 2 foi acessado

Switch e if so os comando condicionais que ANSI C nos fornece para que possamos manipular/desviar o fluxo de execuo caso seja necessrio.

5.2.

Repetio de fluxo

Algumas vezes necessrio executar um comando ou bloco de comandos, um exemplo seria percorrer posies de memoria. Para isto podemos usar os comandos for, while e do while. Estes comando so os mesmos para a maioria das linguagens procedurais. O comando for possui 3 parmetros: Uma varivel que e considerada o contador de loops, uma expresso que quando falsa o loop interrompe sua execuo e o incremento da varivel contadora.
#include <stdio.h> int main() { char str[10]= "Testando01"; int i; /*Exemplo 1 de comando for*/ for(i = 0; i < 10; i++){ printf("Exemplo1 : str[%d] = %c \n",i,str[i]); } printf("\n\n"); /*Exemplo 2 de comando for*/ int j = 0; for(; j < 10; j++){ printf(" Exemplo2 : str[%d] = %c \n",j,str[j]); } printf("\n\n"); /*Exemplo 3 de comando for*/ int k = 0; for(;; k++){ if(k < 10){printf(" Exemplo3 : str[%d] = %c \n",k,str[k]);} else{break;} } printf("\n\n"); /*Exemplo 4 de comando for*/ int t = 0; for(;;){ if(t < 10){printf(" Exemplo4 : str[%d] = %c \n",t,str[t]);} else{break;} t++; }

PROJETO AGIT | PIC


printf("\n\n"); /*Exemplo 5 de comando for*/ int t1 = 0; for(;t1 < 10;){ printf(" Exemplo5 : str[%d] = %c \n",t,str[t1]); t1++; } return (0); }

Console:
Exemplo1 Exemplo1 Exemplo1 Exemplo1 Exemplo1 Exemplo1 Exemplo1 Exemplo1 Exemplo1 Exemplo1 Exemplo2 Exemplo2 Exemplo2 Exemplo2 Exemplo2 Exemplo2 Exemplo2 Exemplo2 Exemplo2 Exemplo2 Exemplo3 Exemplo3 Exemplo3 Exemplo3 Exemplo3 Exemplo3 Exemplo3 Exemplo3 Exemplo3 Exemplo3 : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : str[0] str[1] str[2] str[3] str[4] str[5] str[6] str[7] str[8] str[9] = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = T e s t a n d o 0 1 T e s t a n d o 0 1 T e s t a n d o 0 1

str[0] str[1] str[2] str[3] str[4] str[5] str[6] str[7] str[8] str[9] str[0] str[1] str[2] str[3] str[4] str[5] str[6] str[7] str[8] str[9]

Exemplo4 Exemplo4 Exemplo4 Exemplo4 Exemplo4 Exemplo4 Exemplo4 Exemplo4 Exemplo4 Exemplo4

: : : : : : : : : :

str[0] str[1] str[2] str[3] str[4] str[5] str[6] str[7] str[8] str[9]

= = = = = = = = = =

T e s t a n d o 0 1

Exemplo5 : str[10] = T Exemplo5 : str[10] = e

PROJETO AGIT | PIC


Exemplo5 Exemplo5 Exemplo5 Exemplo5 Exemplo5 Exemplo5 Exemplo5 Exemplo5 : : : : : : : : str[10] str[10] str[10] str[10] str[10] str[10] str[10] str[10] = = = = = = = = s t a n d o 0 1

No exemplo 1 a varivel i pode ser usada apenas no bloco de funo do for uma vez que o mesmo foi declarado no comando for e no no bloco de comando da funo, j nos outros exemplos possvel usar as variveis contadoras fora do for, pois foram declaradas fora do comando. Exemplificamos 5 variantes do comando for importante perceber que os parmetros do for foram alterados e mesmo assim o comando aceito, ou seja, para o compilador basta que exista os delimitadores de parmetros que so os ;. Mas, observando o exemplo 4 podemos verificar um problema, caso no fosse adicionado um comando if no haveria condio de parada ento o comando for seria executado infinitamente. Isso chamado de loop infinito e com isto podem ocorrer problemas de estouro de buffer. Outro comando o while. O uso deste comando prximo do exemplo 5, referente ao comando for ele possui somente a expresso de condio.
#include <stdio.h> int main() { int i = 0; char str[10]= "Testando01"; while(i < 10){ printf("str[%d] = %c \n",i,str[i]); i++; } return (0); }

Console:
str[0] str[1] str[2] str[3] str[4] str[5] str[6] str[7] str[8] str[9] = = = = = = = = = = T e s t a n d o 0 1

PROJETO AGIT | PIC O while tem a mesma execuo que o for, mas possui um nico parmetro que caso no seja verdadeiro, interrompe o loop. While e for executam o loop assim que so verdadeiros, no existe a possibilidade de realizar uma verificao, atribuio ou qualquer outra ao caso a condio do loop seja falsa.
#include <stdio.h> int main() { char str[10]= "Testando01"; int i , j; char c = ' '; i = j = 11; for(; i < 10; i++){ printf("Escolha uma opo:\n"); printf("(I) Inserir:\n"); printf("(D) Deletar:\n"); printf("(A) Alterar:\n"); fflush(stdout); scanf("%c", &c); if(c != ' ' && (c != 'I' || c != 'D' || c != 'A')){continue;} } while(j < 10){ printf("Escolha uma opo:\n"); printf("(I) Inserir:\n"); printf("(D) Deletar:\n"); printf("(A) Alterar:\n"); scanf("%c", &c); if(c != ' ' && (c != 'I' || c != 'D' || c != 'A')){continue;} j++; } return (0); }

Console:

NENHUMA INFORMAO EXIBIDA.

No exemplo acima o comando for no seria executado, uma vez que a condio seria falsa de primeira instncia, ento o menu nunca seria exibido e a execuo do programa finalizada. Podemos notar o comando continue ele o oposto do break, o break interrompe o loop enquanto que o continue no executar o que esta aps sua declarao, mas continua o loop normalmente at que a condio seja falsa. Para isto temos o comando do while com este comando possvel executar o bloco de comando do loop, uma primeira vez, mesmo que a condio no seja verdadeira de primeira instancia.

PROJETO AGIT | PIC


#include <stdio.h> int main() { int j = 11; char c = ' '; do{ printf("Escolha uma opo:\n"); printf("(I) Inserir:\n"); printf("(D) Deletar:\n"); printf("(A) Alterar:\n"); fflush(stdout); scanf("%c", &c); j++; } while(j < 10 && (c != ' ' && (c != 'I' || c != 'D' || c != 'A'))); return (0); }

Console:
Escolha uma opo: (I) Inserir: (D) Deletar: (A) Alterar:

Uma vez que a condio do while falsa o bloco executado uma nica vez, esta a diferena do comando do while para o comando while/for. ANSI C nos proporciona outra maneira de alterar o fluxo de execuo ou repetio o comando o goto. Este comando executa um salto assim alterando a execuo, mas fortemente recomendado que NO use este comando uma vez que pode deixar o fluxo to desordenando que compreender a execuo do programa ser impossvel. O fluxo de execuo no somente pode ser repetido ou desviado, mas ele pode ser interrompido e para isto podemos usar a funo exit() esta funo interrompe o fluxo e retornando para o sistema operacional um indicativo o retorno 0 indica que foi finalizado com sucesso e um valor diferente de zero indica que ocorreu algum erro.

6. Vetores e Matrizes
Vetores so estruturas de dados que possuem todas as posies de memoria que ocupam do mesmo tipo definido, nesta seo veremos como manipul-las. As explicaes e exemplos aqui apresentados so referentes a vetores estticos.

6.1.

Vetores Unidimensionais

Quando definimos um vetor, estamos alocando espaos de memria de um determinado tipo de dado. Durante sua declarao definimos a quantidade de memria que queremos e definimos um tipo de dado que ser propagado para cada posio de memria reservado, ou seja, se alocarmos um vetor do tipo int de 15 posies todas as 15 posies sero do tipo int.

PROJETO AGIT | PIC


#include <stdio.h> int main() { int vet_int[10] = {0,1,2,3,4,5,6,7,8,9}; char vet_char[10] = {'a','a','a','a','a','a','a','a','a','a'}; int i; printf("string de caracteres: %s \n",vet_char); printf("string de inteiros:"); for(i=0; i<10; i++){ printf("%d",vet_int[i]); } return (0); }

Console:
string de caracteres: aaaaaaaaaa string de inteiros:0123456789

Vetores contendo somente char so chamados tambm de strings. Todo vetor associado a um ponteiro e quando usamos um loop para percorrer este vetor alterando o valor de endereo, localizado entre os [ ] ou alteramos manualmente, estamos fazendo com que este apontador mude a posio de memria que o mesmo esta acessando, por este motivo importante lembrar do terminador de string \0 pois uma vez que este ponteiro invade outra posio de memoria que no pertence a seu programa pode ocorrer problemas, pois esta outra regio de memoria pode estar sendo usado por outro programa.
#include <stdio.h> int main() { int vet_int[10] = {0,1,2,3,4,5,6,7,8,9}; char vet_char[10] = {'a','a','a','a','a','a','a','a','a','a'}; int i; printf("string de caracteres: %s \n",vet_char); printf("string de inteiros:"); for(i=0;; i++){ printf("%d",vet_int[i]); } return (0); }

PROJETO AGIT | PIC Neste exemplo a varivel i incrementada, mas no temos condio de parada ento ocorrera um loop infinito desta forma acessando posies de memoria alm do \0 e isto um problema serio e o compilador gera um erro.

6.2.

Vetores Bidimensionais

Um vetor bidimensional tambm conhecido como matriz similar ao vetor unidimensional quanto ao funcionamento, mas no quando a estruturao este tipo de vetor possui linhas e colunas.
#include <stdio.h> int main() { int i,k,j; int vet_int[2][10] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; char vet_char[10] = {'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }; for(i = 0;i <2; i++){ for(j=0; j<10; j++){ printf("string de inteiros: %d \n",vet_int[i][j]); } } for(k=0; k<10; k++){ printf("string de caracteres: %c \n",vet_char[k]); } return (0); }

Console:
string string string string string string string string string string string string string string string string string string string string string string string string string de de de de de de de de de de de de de de de de de de de de de de de de de inteiros: 0 inteiros: 1 inteiros: 2 inteiros: 3 inteiros: 4 inteiros: 5 inteiros: 6 inteiros: 7 inteiros: 8 inteiros: 9 inteiros: 10 inteiros: 11 inteiros: 12 inteiros: 13 inteiros: 14 inteiros: 15 inteiros: 16 inteiros: 17 inteiros: 18 inteiros: 19 caracteres: a caracteres: a caracteres: a caracteres: a caracteres: a

PROJETO AGIT | PIC


string string string string string de de de de de caracteres: caracteres: caracteres: caracteres: caracteres: a a a a a

Vamos ilustrar como os strings vet_int e vet_char esto estruturadas: vet_int:

Figura 04. zzzzzz

vet_char:

Figura 05. kkkkkk

6.3.

Inicializao sem especificao de tamanho

A Linguagem ANSI C nos permite inicializar strings sem especificar a quantidade de memria que deve ser alocada.
#include <stdio.h> #include<string.h> int main() { char vet_char[] = "abcdefghij"; printf("Tamanho da string: %d", strlen(vet_char)); return (0); }

Console:

PROJETO AGIT | PIC


Tamanho da string: 10

Neste caso o vet_char ir assumir o tamanho da string sendo atribuda como seu tamanho. O comando strlen pertence a biblioteca string.h dentre outros comandos para manipular strings, alguns so: strcpy, strcomp, strcat dentre outros. Para evitar um ataque por estouro de pilha por alocao podemos no substituir as funes strXX pelas strnXX, estas recebem um parmetro adicional que indica o tamanho que a sequencia de caracteres possui. Quando manipular strings necessrio tomar muitos cuidados uma vez que o ponteiro que manipula a regio de memoria referente a string alocada pode nos confundir um exemplo :
#include <stdio.h> #include<string.h> int main() { char vet_char[] = "abcdefghij"; char vet_char2[10]; vet_char2 = vet_char; /*NO FAA ISSO*/ strcpy(vet_char2, vet_char); /*ACEITAVEL*/ printf("Tamanho da string: %d", strlen(vet_char)); return (0); }

Acima exemplificamos algo que no seria legal de ser feito, pois pode no ocorrer o esperado neste caso ambos os ponteiro iro apontar para o mesmo endereo de memoria. Vetores podem ser usados para tipos de dados criados pelo usurio, por exemplo, uma estrutura.
#include <stdio.h> #include<string.h> typedef struct{ char* login; char* senha; }Usuario; int main() { char login[7], senha[10]; int loop = 0; Usuario usr; usr.login = (char*) malloc (7*sizeof(char)); usr.senha = (char*) malloc (10*sizeof(char)); do{

PROJETO AGIT | PIC


puts("Digite o login:"); fflush(stdout); gets(login); puts("Digite o senha:"); fflush(stdout); gets(senha); if(strlen(login) >= 7 && strlen(senha) >=10) { puts("Qtd de caracteres invalida!!!!!!"); loop = 1; } else{loop=0;} }while(loop); strcpy(usr.login,login); strcpy(usr.senha,senha); printf("LOGIN: %s \n", usr.login); printf("SENHA: %s \n", usr.senha); return (0); }

Console:
Digite Digite LOGIN: SENHA: o login: aaa o senha: aaa aaa aaa

Foi declarado uma estrutura Usuario onde existem 2 elementos, login e senha, que so ponteiros e os valores digitados foram copiados para estes elementos.

7. Buffer Overflow
Ao lidarmos com dados que esto na memria principal estamos suscetveis a cometer pequenos deslizes que podem causar problemas no programa o que pode levar a inmeras consequncias. Nesta seo iremos estudar o que um buffer e quais so os problemas que podem advir do seu mau uso.

7.1.

Definies

Um buffer qualquer regio da memria utilizada para armazenar um amontoado de dados. Computacionalmente falando, um buffer pode ser entendido como uma varivel (regio da memria) que possui um tamanho especfico para armazenar qualquer tipo de dado.

PROJETO AGIT | PIC Desta forma, dizemos que ocorreu um Buffer Overflow (transbordamento de buffer) quando tentamos colocar mais dados em um buffer do que ele pode armazenar, ou seja, quando atingimos seu limite mximo, mas ainda continuamos a inserir informaes.

7.2.

Problemas decorrentes do Buffer Overflow

Todo cdigo que apresente Buffer Overflow possui o que chamamos de bug. Bugs so qualquer tipo de problema, erro ou anomalia existente no cdigo. Existem vrios tipos de bug, mas quando programamos em C uma boa parte deles so causados por transbordamento de buffer. Quando causamos um buffer overflow (por exemplo, tentando inserir uma string de tamanho 10 numa string de tamanho 7) o programa pode encerrar de forma inesperada, causando um comportamento no condizente com o esperado. Alm disto, problemas de buffer podem ser uma fonte para hackers injetarem cdigo malicioso na aplicao, desviando o fluxo normal de execuo e causando os mais diversos tipos de danos (roubo de dados pessoas, invaso de computadores, derrubamento de sistemas, etc.). Alm disto, quando um programa encerra inesperadamente, ele pode deixar os dados manipulados num estado inconsistente, estejam eles em banco de dados ou em arquivos.

7.3.

Preveno de Buffer Overflow

Existem vrias formas de evitar o buffer overflow. A mais usual por meio da checagem do limite de dados que pode ser copiado. Isto pode ser feito de duas formas: ou por meio de compiladores que j fazem isto em tempo de compilao, ou por meio da insero de cdigo que cheque condies de erro. Para manipular strings, por exemplo, recomenda-se o uso de funes com a letra n no seu nome. Tais funes possuem a mesma funcionalidade das equivalentes sem a letra n, porm so mais seguras, pois verificam o limite de dados que pode ser manipulado. Por exemplo, a funo strcat(str1, str2) copia contedo de str2 para o final de str1. Se str1 no for suficientemente grande para comportar str1 + str2, iremos causar um buffer overflow. Uma forma de contornar este problema por meio do uso da funo strncat(str1, str2, n) que copia no mximo n caracteres de str2 para o final de str1. Um possvel valor para n seria a capacidade mxima de str1 menos seu tamanho real. Por fim, outra maneira de evitar buffer overflow por meio da anlise dos dados informados pelo usurio. Antes de atribuir os dados para as variveis, verifique se elas possuem o tamanho necessrio para armazen-los.

PROJETO AGIT | PIC

8. Ponteiros
8.1. Declarando ponteiros
Para declarar um ponteiro devemos pegar uma declarao de uma varivel e adicionar o asterisco ( * ) e desta forma o compilador entende que esta varivel ir conter um endereo e no um valor.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int *p; int end = 10; printf("Valor do end: %d \n\n", end); p = &end; *p = 13; puts("Valores printf("Valor printf("Valor printf("Valor return (0); } referentes ao ponteiro\n"); do end: %d\n", end); do ponteiro: %d \n", *p); do endereo do ponteiro: %d \n", p);

Console:
Valor do end: 10 Valores referentes ao ponteiro Valor do end: 13 Valor do ponteiro: 13 Valor do endereo do ponteiro: 2686748

Sempre que atribumos um endereo de memria para um ponteiro o mesmo aponta, ou seja, acessa a posio de memoria referente ao endereo atribudo. Incremento(adio) e decremento(subtrao) tambm podem ser aplicados a ponteiros, mas reforando ponteiros contm endereos e no valores, ento quando est incrementando ou decrementando estamos alterando o endereo do ponteiro e no algum valor de varivel. Os operadores relacionais <,>,<=,>=, != e == quando estes operadores so usados eles comparam o endereo do ponteiro.
#include <stdio.h> int main() {

PROJETO AGIT | PIC


int *p1, *p2; int end1 = 10; int end2 = 20; printf("Valor do end1: %d \n\n", end1); p1 = &end1; *p1 = 13; printf("Valor do end2: %d \n\n", end2); p2 = &end2; *p2 = 15; puts("Valores referentes ao ponteiro p1\n"); printf("Valor do end1: %d\n", end1); printf("Valor do ponteiro: %d \n", *p1); printf("Valor do endereo do ponteiro: %d \n", p1); printf("\n\n\n"); puts("Valores printf("Valor printf("Valor printf("Valor referentes ao ponteiro p2\n"); do end2: %d\n", end2); do ponteiro: %d \n", *p2); do endereo do ponteiro: %d \n", p2);

if(p1 > p2){puts("p1 esta mais adiante que p2");} else{ puts("p2 esta mais adiante que p1");} return (0); }

Console:
Valor do end1: 10 Valor do end2: 20 Valores referentes ao ponteiro p1 Valor do end1: 13 Valor do ponteiro: 13 Valor do endereo do ponteiro: 2686744

Valores referentes ao ponteiro p2 Valor do end2: 15 Valor do ponteiro: 15 Valor do endereo do ponteiro: 2686748 p2 esta mais adiante que p1

#include <stdio.h> #include <stdlib.h> int main() { int *p1, *p2; int end1 = 10; int end2 = 20;

PROJETO AGIT | PIC


printf("Valor do end1: %d \n\n", end1); p1 = &end1; *p1 = 13; printf("Valor do end2: %d \n\n", end2); p2 = &end2; *p2 = 15; if(p1 == p2){puts("p1 esta apontando para o mesmo endereo que p2");} else{puts("p1 esta apontando para um endereo diferente de p2");} p1 = p2; printf("Aps atribuir p2 para p1"); if(p1 == p2){puts("p1 esta apontando para o mesmo endereo que p2");} else{puts("p1 esta apontando para um endereo diferente de p2");} return (0); }

Console:
Valor do end1: 10 Valor do end2: 20 p1 esta apontando para um endereo diferente de p2 Aps atribuir p2 para p1p1 esta apontando para o mesmo endereo que p2

Existem aes que no podem ser aplicadas a ponteiros como diviso e multiplicao, adicionar 2 ponteiros, adicionar ou subtrair floats ou doubles de ponteiros. Reforando o contedo de ponteiros so endereos de memria e no valores. Tambm possvel declararmos ponteiros de ponteiros para isto basta colocar 2 asteriscos (**), na verdade podemos declarar ponteiros de ponteiros de ponteiros de N ponteiros basta adicionar a quantidade de asterisco (*) referente a quantos ponteiros desejar.
#include <stdio.h> int main() { int **pp_val, v=10,*p_val; p_val = &v; pp_val = &p_val; printf("pp_val valor %d \n", **pp_val); printf("pp_val endereo %d \n", pp_val); printf("p_val valor %d \n", *p_val); printf("p_val endereo %d \n", p_val); return (0); }

PROJETO AGIT | PIC Console:


pp_val valor 10 pp_val endereo 2686748 p_val valor 10 p_val endereo 2686744

Ponteiro de ponteiro funciona da mesma forma para acessar o valor em sua posio de memria basta colocarmos a varivel com os 2 asteriscos (**). Para deixar mais claro a ideia de ponteiros e ponteiro de ponteiro, vamos exemplificar realizando um comparativo com vetores. Ponteiro int *vet; int **vet; Iint vet[10]; int vet[10][2]; Vetor

Ponteiro (Endereo)

Vetor(Endereo)

&vet

vet[9];

&vet

vet[9][2]

Lembrando, que para que um ponteiro seja semelhante devemos alocar o ponteiro dinamicamente, usando os comandos malloc ou calloc, e desta forma definir o tamanho da regio de memria apontado.

8.2.

Ponteiros como vetores

Sempre que um vetor criado ele possui um ponteiro associado a ele e isto explica por que todos os vetores comeam na posio 0 (zero), pois nesta posio indexa o ponteiro associado a esta regio de memoria. O compilador ANSI C no sabe quanto de memria est sendo alocado para aquela regio de memria, por isto quando alocamos um vetor o ponteiro colocado no inicio do vetor e quando percorre o vetor encontra os valores, lembrando que percorrer o vetor caminhar incrementando ou decrementando o vetor.
#include <stdio.h>

PROJETO AGIT | PIC


#include<string.h> int main() { char vet_char[10] = "abcdefghij"; printf("Tamanho da string: %d", strlen(vet_char)); return (0); }

Console:

Tamanho da string: 10

Este exemplo pode ser facilmente reescrito com ponteiro:


#include <stdio.h> #include<string.h> int main() { char *vet_char; char aux[10] = "abcdefghij"; int i; vet_char = aux; printf("Tamanho da string: %d \n",strlen(vet_char)); for(i=0; i<10;i++){ printf("vet_char[%d] : %c \n",i, *vet_char); vet_char++; } return (0); }

Console:
Tamanho da string: 10 vet_char[0] : a vet_char[1] : b vet_char[2] : c vet_char[3] : d vet_char[4] : e vet_char[5] : f vet_char[6] : g vet_char[7] : h vet_char[8] : i vet_char[9] : j

Aps associar o ponteiro vet_char ao vetor aux o ponteiro est com o endereo referente posio 0 (zero) do vetor. Ento quando feito o vet_char++ o ponteiro ir

PROJETO AGIT | PIC incrementar o endereo e desta forma caminhar pelas posies de memria referente ao aux. Como podemos notar strings em ANSI C podem ser escritas com char* ao invs de char[].
#include <stdio.h> void trocaLetra(char *str, char letra_real, char letra_troca){ while(*str != '\0'){ if(*str == letra_real){*str = letra_troca;} str++; } } int main() { char aux[10] = "abcdefghij"; int i = 0; trocaLetra (&aux, 'e', 'z'); printf("String aps troca:"); while(i < 10){ printf("%c", aux[i]); i++; } return (0); }

Console:

String aps troca:abcdzfghij

Quando uma funo recebe uma string como parmetros a mesma indicada como um ponteiro (char*) e ento manipul-la.

9. Funes
Quando estamos desenvolvendo um sistema complexo importante estrutur-lo de forma que existam funes que faam aes especficas, desta forma o programa fica mais legvel. As funes podem ou no possuir parmetros e podem ou no retornar valores.

9.1.

Retorno e parmetros de funo

Toda funo possui um valor de retorno que especificado durante sua declarao antes do nome da funo e caso no haja um tipo de retorno ento e especificado como void.
#include <stdio.h> float soma(float x, float y) { return (x+y) ;

PROJETO AGIT | PIC


} float multiplicacao(float x, float y, float result) { result = x*y; } void exibeMensagem(char *msg, float val) { printf("%s : %3.2f\n",msg,val); } void exibeMensagem2() { printf("FIM DO PROGRAMA!!!!!\n"); } void main(int argc, char** argv) { float a = 2.2; float b = 2.3; float result = 0.0; char msg[] = "Calculo realizado com sucesso o resultado "; result = soma(a,b); multiplicacao(a,b,result); exibeMensagem(msg,result); exibeMensagem2(); } /*retorna o resultado da soma*/ /*no retorna o resultado da multiplicao*/ /*exibe mensagem*/ /*exibe mensagem*/

Console:

Calculo realizado com sucesso o resultado : 4.50 FIM DO PROGRAMA!!!!!

Quando uma funo recebe um valor por parmetro, o mesmo deve se responsabilizar por atualizar, pois os parmetros so uma copia do valor, ou seja, quando uma funo altera um parmetro no necessariamente o valor real foi alterado. Um exemplo a funo multiplicacao(float,float,float): Isto conhecido como passagem de parmetro por valor. Com ponteiros o funcionamento um pouco diferente possvel alterar os valores de variveis que esto chamando a funo.
#include <stdio.h> void soma(float x, float y, float *result) { *result = x+y; } void exibeMensagem(char *msg, float val) { printf("%s : %3.2f\n",msg,val); } void exibeMensagem2() {

PROJETO AGIT | PIC


printf("FIM DO PROGRAMA!!!!!\n"); } void main(int argc, char** argv) { float a = 2.2; float b = 2.3; float result = 0.0; char msg[] = "Calculo realizado com sucesso o resultado "; soma(a,b,&result); exibeMensagem(msg,result); exibeMensagem2(); }

Console:
Calculo realizado com sucesso o resultado : 4.50 FIM DO PROGRAMA!!!!!

Lembrando um pouco de ponteiro, quando passamos o endereo da varivel por parmetro, ento possvel manipular o valor da mesma mesmo que no seja a funo em que foi declarada. Isto conhecido como passagem de parmetros por referncia. Perceba que neste exemplo a funo main tem 2 parmetros uma varivel inteira argc (argument count) e um ponteiro de ponteiro do tipo caractere o argv (argument value) os valores destes parmetros so passados durante a compilao do programa ento o argc armazena a quantidade de valores passadas pela linha de comando, enquanto que o argv uma matriz que armazena os valores que foram passados pela linha de comando.

9.2.

Passagem de vetores para funes

Quando um vetor passado por parmetro, o mesmo recebido como um ponteiro. Este ponteiro onde est armazenado o endereo da primeira posio do vetor, ou seja, a posio 0 (zero). Ento, neste caso no passada uma cpia de todos os itens e sim o endereo do inicio, para que desta maneira seja possvel percorrer o vetor, lembrando que desta forma possvel alterar os valores do vetor.

10.

Manipulao de arquivos

Em C, um arquivo identificado como qualquer dispositivo de entrada e sada, desde um arquivo em disco (no formato .txt, por exemplo), uma impressora, ou o terminal (entrada e sada padro). Um arquivo pode ainda ser associado a um leitor de caracteres no formato binrio.

PROJETO AGIT | PIC Para manipularmos arquivos em C, necessitamos de uma estrutura utilizada para descrever tal arquivo, ou seja, apontar para a regio de memria onde ele est armazenado fisicamente. Esta estrutura chamada de descritor e um ponteiro definido na biblioteca stdio.h. FILE * arquivo; Ao declarar um ponteiro para arquivo podemos associ-lo a qualquer tipo de arquivo. Aps associ-lo, podemos manipul-lo da maneira que nos conveniar. Quando falamos de manipulao de arquivos, estamos nos referindo s operaes bsicas abaixo. Para consultar exemplos de cdigo, vide Slides de aula.

10.1. Abrir um arquivo


Abrir um arquivo corresponde a vincular o arquivo fsico a um descritor do tipo FILE. Se o arquivo no existir, ele ser criado e vinculado ao descritor. Se o arquivo j existir, ele ser apenas vinculado. Estrutura padro: FILE modo_abertura); Exemplo: FILE w); * * arquivo fopen(FILE*, = int

fopen(Agit.txt,

Para maiores detalhes sobre os modos de abertura de arquivos, vide anexos.

10.2. Escrever/Ler num arquivo


Aqui mostraremos funes para escrever e ler dados em um arquivo. Escrita de Arquivos Funo fputc fputs fprintf fwrite fgetc O que faz Escreve um caractere no arquivo Escreve uma string no arquivo (no formatvel) Escreve uma string no arquivo (formatvel) Grava dados binrios em um arquivo Recebe apenas um caractere Assinatura int fputc(int , FILE*) int fputs(const chat*, FILE*) int fprintf(FILE*, formatos (const char*), argumentos) size_t fwrite(const void*, size_t,size_t,FILE*) int fgetc(FILE*)

A r q u i v o s

t u r a

d e

PROJETO AGIT | PIC fgets fscanf fread L uma string (Linha completa) char* fgets(char*, int, FILE*) int fscanf(FILE*, formatos (cont char*), L uma string formatada argumentos) L dados binrios do arquivo size_t fread(void*, size_t, size_t, FILE*)

10.3. Deslocar o cursor de I/O num arquivo


Aqui mostraremos funes para realizar deslocamentos em um arquivo. Funo feof Deslocamentos em Arquivos O que faz Indicador de fim do arquivo, similar ao \0 do vetor. Verifica se a ultima ao de acesso ao arquivo (leitura ou escrita) foi realizada com sucesso. A referencia de onde esta sendo executada a leitura ou escrita no arquivo alterada. Posiciona a referencia no inicio do arquivo. Assinatura feof(FILE*)

ferror

ferror(FILE*)

fseek

int fseek(FILE*, long int, int)

rewind

void rewind(FILE*)

10.4. Fechar o arquivo


Finalmente, ao termos certeza que no utilizaremos mais o arquivo em questo podemos romper a ligao lgica do arquivo fsico com seu descritor. Esta ao libera a memria principal alocada para o arquivo e a disponibiliza para uso em outros programas. Isto feito da seguinte forma: Estrutura padro: Exemplo: void fclose(FILE*); fclose(arquivo);

11.

Alocao Dinmica

Existem 4 funes de alocao de memria malloc, calloc, realloc e free e todas esto definidas na biblioteca stdlib.h.

PROJETO AGIT | PIC

11.1. Alocao dinmica de memria


Alocaes estticas como so feitas com vetores podem ser um desperdcio ou at mesmo um problema, pois uma vez que necessite mais memria no existe maneira de alocar e caso no use toda memoria alocada esta memria no ser disponibilizada. Os comandos malloc ou calloc alocam uma regio de memria. Em seus parmetros so especificados o tipo de dado dos campos e a quantidade de posies de memria. Retorna um ponteiro void* e caso no haja memria suficiente, o ponteiro retornado null.
#include<stdio.h> #include<stdlib.h> void main(int argc, char** argv) { char *str_malloc, *str_calloc; int pos = 0; int i; printf("Digite o numero de posies:"); fflush(stdout); scanf("%d", &pos); str_malloc = (char*)malloc(pos*sizeof(char)); str_calloc = (char*)calloc(pos,sizeof(char));

if(!str_malloc){ printf("Memria } if(!str_calloc){ printf("Memria }

no foi alocada com malloc!!!!!");

no foi alocada com calloc!!!!!");

for(i=0; i<pos;i++) { str_malloc[i] = 97+i; str_calloc[i] = 97+i; } for(i=0; i<pos;i++){ printf("str_malloc[%d] = %c \n",i,str_malloc[i]); printf("str_malloc[%d] = %c \n",i,str_calloc[i]); } }

Console:
Digite o numero str_malloc[0] = str_malloc[0] = str_malloc[1] = str_malloc[1] = str_malloc[2] = str_malloc[2] = de posies:3 a a b b c c

PROJETO AGIT | PIC O sizeof retorna o tamanho do tipo de dado. Desta forma ser alocada uma quantidade de posies de memria onde cada posio ter o tamanho do tipo que ir armazenar. Como o malloc retorna um void*, como mencionado anteriormente, ento foi feito um cast para char*. Quando alocamos a memria com calloc todas as posies so inicializadas, diferente de quando alocamos com malloc que as posies no so inicializadas. Esquema de alocao dinmica usando malloc:

Figura 06. gggggg

Esquema de alocao dinmica usando calloc:

Figura 07. qqqqqq

Existe outra maneira de alocar memria dinamicamente, mas apartir de outra memria j alocada, usando malloc ou calloc, esta funo o realloc.

PROJETO AGIT | PIC


#include<stdio.h> #include<stdlib.h> void main(int argc, char** argv) { char *str_malloc, *str_calloc; int pos = 0; int pos_1 = 10; int i,j,l,k; printf("Digite o numero de posies:"); fflush(stdout); scanf("%d", &pos); str_malloc = (char*)malloc(pos*sizeof(char)); str_calloc = (char*)calloc(pos,sizeof(char)); if(!str_malloc){printf("Memria if(!str_calloc){printf("Memria no foi alocada com malloc!!!!!");} no foi alocada com calloc!!!!!");}

for(i=0; i<pos;i++){str_malloc[i] = 97+i;} for(j=0; j<pos;j++){ str_calloc[j] = 97+j;} for(i=0; i<pos;i++){printf("str_malloc[%d] = %c \n",i,str_malloc[i]);} for(j=0; j<pos;j++){printf("str_calloc[%d] = %c \n",j,str_calloc[j]);} str_malloc = (int*)realloc(str_malloc, pos_1*sizeof(int)); str_calloc = (int*)realloc(str_calloc, pos_1*sizeof(int)); for(l=0; l<(pos+pos_1);l++){str_malloc[l] = 97+l;} for(k=0; k<(pos+pos_1);k++){ str_calloc[k] = 97+k;} printf("\n\n APS O REALLOC \n\n"); for(i=0; i<pos+pos_1;i++){printf("str_malloc[%d] = %c \n",i,str_malloc[i]);} for(j=0; j<pos+pos_1;j++){printf("str_calloc[%d] = %c \n",j,str_calloc[j]);} free(str_malloc); free(str_calloc); }

Console:
Digite o numero str_malloc[0] = str_malloc[1] = str_calloc[0] = str_calloc[1] = APS O REALLOC str_malloc[0] = a str_malloc[1] = b str_malloc[2] = c str_malloc[3] = d str_malloc[4] = e str_malloc[5] = f str_malloc[6] = g str_malloc[7] = h str_malloc[8] = i str_malloc[9] = j str_malloc[10] = k str_malloc[11] = l de posies:2 a b a b

PROJETO AGIT | PIC


str_calloc[0] = a str_calloc[1] = b str_calloc[2] = c str_calloc[3] = d str_calloc[4] = e str_calloc[5] = f str_calloc[6] = g str_calloc[7] = h str_calloc[8] = i str_calloc[9] = j str_calloc[10] = k str_calloc[11] = l

O comando realloc pode mover todo o bloco de memria alocado anteriormente para conseguir mais espao de memria, ento o mesmo devolve um ponteiro para o bloco de memria e como este ponteiro refere-se ao bloco todo ento as informaes no so perdidas, caso os ponteiros str_malloc ou str_calloc, no exemplo acima, fossem nulos seria alocada a memoria referente ao pos_1 e seria retornado um ponteiro para esta memria. Caso no haja memria suficiente para ser realocado ento retornado um ponteiro NULL e o bloco de memria original se mantem o mesmo sem alteraes. Matrizes tambm podem ser alocadas usando estes comandos, mas neste caso cada item, linha e coluna, devem ser alocados.
#include<stdio.h> #include<stdlib.h> #define QTD_POS 3 void main(int argc, char** argv) { char **mtr; int i, linha, coluna, letra; i=linha=coluna=0; /*Alocar linhas*/ mtr = (char**)malloc(QTD_POS*sizeof(char*)); /*Alocar colunas*/ for(i=0; i<QTD_POS;i++){ mtr[i] = (char*)malloc(QTD_POS*sizeof(char)); } /*Preenche a matriz*/ letra = 65; for(linha=0; linha < QTD_POS; linha++){ for(coluna=0; coluna < QTD_POS; coluna ++){ mtr[linha][coluna] = (char)letra; /*cast converter o 65 para 'a'*/ letra++; } } /*Imprime a matriz*/ letra = 0; for(linha=0; linha < QTD_POS; linha++){ for(coluna=0; coluna < QTD_POS; coluna ++){ printf("mtr[%d][%d] = %c\n",linha, coluna, mtr[linha][coluna]); } printf("\n"); }

PROJETO AGIT | PIC


free(mtr); }

Console:
mtr[0][0] = A mtr[0][1] = B mtr[0][2] = C mtr[1][0] = D mtr[1][1] = E mtr[1][2] = F mtr[2][0] = G mtr[2][1] = H mtr[2][2] = I

Todas as alocaes foram feitas com char para que facilitasse a explicao, mas poderiam ser feitas com ints, floats doubles e qualquer outro tipo de dado.

11.2. Liberao de memria alocada


Toda memria alocada dinamicamente deve ser liberada e para isto usamos a funo free() esta funo ir liberar a memria referenciada por um ponteiro.
#include<stdio.h> #include<stdlib.h> void main(int argc, char** argv) { char *str_malloc, *str_calloc; int i,pos = 0; printf("Digite o numero de posies:"); scanf("%d", &pos); str_malloc = (char*)malloc(pos*sizeof(char)); str_calloc = (char*)calloc(pos,sizeof(char)); if(!str_malloc){printf("Memria no foi alocada com malloc!!!!!");} else{printf("Memria foi alocada com malloc!!!!!\n");} if(!str_calloc){printf("Memria no foi alocada com calloc!!!!!");} else{printf("Memria foi alocada com calloc!!!!!\n");} for(i=0; i<pos;i++){str_malloc[i] = i;} for(i=0; i<pos;i++){str_calloc[i] = i;} free(str_malloc); free(str_calloc); }

Console:

PROJETO AGIT | PIC


Digite o numero de posies:6 Memria foi alocada com malloc!!!!! Memria foi alocada com calloc!!!!!

Uma vez que a memria foi liberada ela pode ser usada novamente pelo malloc ou calloc para uma nova alocao.

12.

Diretivas de Compilao

O compilador C examina o arquivo fonte e realizam certas modificaes baseando-se nas diretivas de compilao, estas diretivas podem ser identificadas por conter um # antes do comando. Esta seo ir abordar as diretivas #include e #define para verificar outras diretivas existentes vide anexo.

12.1. #include
Esta diretiva informa ao compilador que inclua um programa em outro, em tempo de compilao, desta forma podendo utilizar as funcionalidades do mesmo. Deve-se indicar o arquivo que se deseja incluir ento podemos usar ou <> o que difere ambos que caso seja usado o ser necessrio indicar o caminho completo do arquivo ou garantir que ele esteja no mesmo diretrio do arquivo sendo compilado. Caso o arquivo esteja no caminho pr-definido pelo compilador, ou seja, forem arquivos de sistema como, por exemplo: stdio.h, string.h, stdlib.h ou conio.h ento usamos o <>. Todas estas bibliotecas possuem apenas prottipos, pois esto previamente compiladas e so adicionadas no programa durante a linkagem(linkedio). Todos os cdigos exemplificados aqui neste documento usam a diretiva #include.

12.2. #define
A diretiva define nos permite indicar ao compilador que sempre que o nome do macro for encontrado o mesmo deve ser substitudo pela sequencia de caracteres associado a ele na diretiva. Isto possibilita que caso um valor seja necessrio inmeras vezes ento adicionamos o nome do macro e assim caso seja necessrio modificar isto ser feito em um nico ponto do cdigo e no em vrios lugares, isto torna o programa mais flexvel. importante ressaltar que #define no possibilita declarar apenas constantes, mas tambm outros tipos, por exemplo, um comando. Vamos alterar o cdigo da seo 9.2 para que comporte a diretiva #define.
#include<stdio.h> #include<stdlib.h> #define QTD_POS 10 #define MSG_ERR_MALLOC printf("Memria no foi alocada com malloc!!!!!\n");

PROJETO AGIT | PIC


#define MSG_ERR_CALLOC printf("Memria no foi alocada com calloc!!!!!\n"); #define MSG_SUC_MALLOC printf("Memria foi alocada com malloc!!!!!\n"); #define MSG_SUC_CALLOC printf("Memria foi alocada com calloc!!!!!\n"); #define FREE_MALLOC free(str_malloc); #define FREE_CALLOC free(str_calloc); void main(int argc, char** argv) { char *str_malloc, *str_calloc; int i; str_malloc = (char*)malloc(QTD_POS *sizeof(char)); str_calloc = (char*)calloc(QTD_POS,sizeof(char)); if(!str_malloc){MSG_ERR_MALLOC} else{MSG_SUC_MALLOC} if(!str_calloc){MSG_ERR_CALLOC} else{MSG_SUC_CALLOC} for(i=0; i< QTD_POS;i++){str_malloc[i] = i;} for(i=0; i< QTD_POS;i++){ str_calloc[i] = i;} FREE_MALLOC; FREE_CALLOC; }

Console:
Memria foi alocada com malloc!!!!! Memria foi alocada com calloc!!!!!

No cdigo acima a quantidade de posies que sero alocadas no ser mais digitada pelo usurio foi criado um define com o nome de macro QTD_POS e as 2 mensagens de erro caso as memorias com malloc e calloc no seja alocado com sucesso tambm foram adicionadas com a diretiva #define com o nome de macro MSG_ERR_MALLOC e MSG_ERR_CALLOC.

13.

Bibliotecas

J mencionamos que bibliotecas so um conjunto de funes j implementadas que podem ser utilizadas em qualquer programa que importe tal biblioteca em tempo de execuo por meio da diretiva #include. Uma biblioteca definida por um arquivo com extenso .h (header), o qual possui a assinatura de todas as funes da biblioteca.

13.1. Definidas pela linguagem

PROJETO AGIT | PIC Existem inmeras bibliotecas prontas em C. As principais, e suas funcionalidades esto descritas na tabela abaixo. Para maiores detalhes dos mtodos disponveis, bem como informaes de como utiliz-las, consulte manuais da Internet. Biblioteca string.h Funcionalidades Manipulao de strings Converso de tipo Gerao de sequencia aleatria Alocao e liberao de memria Controle de processos Ordenamento e procura Matemtica Operaes matemticas Manipulao de Tempo Manipulao de caracteres Manipulao de erros

stdlib.h

math.h time.h ctype.h errno.h

13.2. Definidas pelo usurio


Qualquer programador pode definir e utilizar suas prprias bibliotecas. Para isto, basta desenvolver os cdigos das funes normalmente, porm salv-los num arquivo .h. Suponha que voc tenha definido a biblioteca agit.h. Para utiliz-la em outro programa, bastar incluir a diretiva: #include agit.h no cdigo do outro programa. No se esquea de apontar o caminho completo para o arquivo.

14.

Prottipos

Todas as funes mencionadas neste documento possuem os padres aceitveis pelo compilador, estes padres so conhecidos como sintaxe. Aqui ser exibido os prottipos e suas sintaxe.

PROJETO AGIT | PIC

14.1. Declarao de variveis sem modificador


tipo_da_variavel nome_da_variavel

14.2. Declarao de variveis com modificadores


modificador tipo_da_variavel nome_da_variavel

14.3. Declarao de estrutura, union e enum 14.3.1. Estrutura


typedef struct { tipo_1 nome_1; tipo_2 nome_2; } nome_da_estrutura;

14.3.2.

Union

typedef union { tipo_1 nome_1; tipo_2 nome_2; } nome_da_union;

14.3.3.

Enum

typedef enum { lista_de_valores } nome_da_enumeracao;

14.4. Sada de dados


printf(string_de_controle, lista_de_argumentos);

14.5. Entrada de dados


scanf(string_de_controle, lista_de_argumentos);

14.6. Comando de controle de fluxo 14.6.1. If


if(condio) declarao;

14.6.2.

Switch

switch(condio){ case constante_1:

PROJETO AGIT | PIC declarao_1; break; case constante_2: declarao_2; break; case constante_3: declarao_3; break; case constante_n: declarao_n; break; defaut: Declarao_defaut; }

14.6.3.

for

for(inicializao; condio_de_parada;incremento){ declarao; }

14.6.4.

while

while (condio) { declarao; }

14.6.5.
do {

do-while

declarao; } while (condio);

14.6.6.

goto

nome_do_rotulo: ... goto nome_do_rotulo; ...

14.6.7.

exit

void exit(cdigo_de_retorno);

14.7. Vetores e Matrizes

PROJETO AGIT | PIC 14.7.1. Vetor unidimensional tipo_da_varivel nome_da_varivel[tamanho]; 14.7.2. Vetor bidimensional tipo_da_varivel nome_da_varivel[tamanho_1][ tamanho_2]; 14.7.3. Vetor multidimensional tipo_da_varivel nome_da_varivel[tamanho_1][ tamanho_2]...[tamanho_n];

14.8. Ponteiros
tipo_da_varivel *nome_do_ponteiro;

14.9. Funes
14.9.1. Declarao
tipo_de_retorno nome_da_funo(lista_de_parametro){ declarao; }

14.9.2.

return

return valor_de_retorno; ou return;

14.10. Alocao e liberao de memria 14.10.1. malloc


void *malloc(unsigned int num);

14.10.2. calloc
void *calloc(unsigned int num , unsigned int size);

14.10.3. realloc
void *realloc(void *ponteiro; unsigned int num);

14.10.4. free
void *free(void *ponteiro);

14.11. Diretivas de Compilao 14.11.1. #include

PROJETO AGIT | PIC #include nome_do_arquivo ou #include <nome_do_arquivo>

14.11.2. #define
#define nome_da_macro sequencia_de_caracteres

15.

Anexos

15.1. Tipos de dados definidos pelo C ANSI e suas faixas de valores


Todos os tipos dados associados a um modificador, ou no, precisam de uma quantidade especifica de bytes e comparta atribuies dentro de uma faixa de valor. Tipo
char unsigned char signed char int unsigned int signed int short int unsigned short int signed short int long int signed long int unsigned long int float double long double 1 1 1 4 4 4 2 2 2 4 4 4 4 8 10

Tamanho em Bytes

Faixa Mnima
-127 a 127 0 a 255 -127 a 127 -2.147.483.648 a 2.147.483.647 0 a 4.294.967.295 -2.147.483.648 a 2.147.483.647 -32.768 a 32.767 0 a 65.535 -32.768 a 32.767 -2.147.483.648 a 2.147.483.647 -2.147.483.648 a 2.147.483.647 0 a 4.294.967.295 Seis dgitos de preciso Dez dgitos de preciso Dez dgitos de preciso

15.2. Palavras reservadas definidas pelo padro ANSI


Toda linguagem de programao possui palavras reservadas que so as palavras que no podem ser usadas para outra funo que no seja sua funo original. Por exemplo, for um comando de repetio de fluxo de execuo sua funo realizar um loop at que uma condio seja satisfeita, ento no seria permitido que eu declarasse uma varivel ou funo com o nome for. Lembrando, que C case sensitive ento seria aceitvel que fosse declarado uma varivel For, mas por uma boa pratica de programao no recomendvel que faa

PROJETO AGIT | PIC isso, pois aps um longo prazo sem analisar o cdigo voc mesmo pode no lembrar que este For na verdade uma varivel ou funo e at mesmo outro desenvolvedor pode se confundir assim dificultando a compreenso do cdigo. Segue as palavras reservadas pelo padro ANSI:

Palavras reservadas

auto

double

int

struct

break

else

long

switch

case

enum

typedef

register

char

extern

return

union

const

float

short

unsigned

continue

for

signed

void

default

goto

sizeof

volatile

do

if

static

while

Este material no abordara todas as palavras reservadas aqui mencionadas, mas interessante que saibamos de sua existncia.

15.3. Outras diretivas de compilao existentes no ANSI C

Diretivas

#if

#ifdef

#ifndef

#else

#error

#pragma

#elif

#endif

#include

#define

#undef

#line

15.4. Modos de abertura de arquivos em C

PROJETO AGIT | PIC Modo de Abertura r r+ Arquivo existente Arquivo existente ou ser criado um novo Arquivo existente ou ser criado um novo Arquivo existente ou ser criado um novo Arquivo existente ou ser criado um novo Arquivo existente ou ser criado um novo O mesmo que r+, mas para arquivo binrio. O mesmo que w+, mas para arquivo binrio. O mesmo que a+, mas para arquivo binrio. O mesmo que w, mas para arquivo binrio. O mesmo que a, mas para arquivo binrio. Somente Leitura Leitura e Escrita

Somente Escrita Escrita e Leitura (Apaga o contedo existente no arquivo) Escrita no final do arquivo (No apaga o contedo existente no arquivo) Escrita no final do arquivo

w+

a+

r+b

w+b a+b

wb

ab

16.

Referencias

ftp://ftp.unicamp.br/pub/apoio/treinamentos/linguagens/c.pdf http://200.201.81.50/~guilherme/cursos/c.pdf http://www.tiexpert.net/programacao/c/index.php http://www.ccuec.unicamp.br/treinamento_int2004/lingc/index.htm

PROJETO AGIT | PIC

You might also like