Escolar Documentos
Profissional Documentos
Cultura Documentos
CENAPAD-SP
Abril de 2013
1 Sumrio
1 Introduo....................................................................................................................... 7
1.1 O Curso.................................................................................................................... 7
1.2 A tipografia usada na apostila:.................................................................................7
1.3 Linguagem de Programao C.................................................................................. 7
1.4 Princpios do padro C.............................................................................................. 9
1.4.1 Spirit of C.......................................................................................................... 9
1.4.2 Traduo: Spirit of C.......................................................................................... 9
2 Aula 1............................................................................................................................ 11
2.1 Primeiro Programa em C ........................................................................................ 11
2.1.1 O comando printf............................................................................................ 15
2.2 A linguagem de programao C............................................................................. 15
2.3 Tipo de dado em C................................................................................................. 17
2.4 Declarao de Variveis primitivas........................................................................19
2.5 Tipos de dados primitivos e variveis.....................................................................21
2.5.1 Numricos inteiros.......................................................................................... 21
2.5.2 Numricos ponto flutuante..............................................................................25
2.5.3 Caractere........................................................................................................ 27
2.6 Valores literais........................................................................................................ 29
2.6.1 Literal numrica inteira...................................................................................29
2.6.2 Literal numrica ponto flutuantes...................................................................29
2.6.3 Literal caractere e string................................................................................. 31
3 Aula 2............................................................................................................................ 33
3.1 Variveis derivadas................................................................................................ 33
3.2 Arrays..................................................................................................................... 33
3.2.1 Declarao de variveis array.........................................................................33
3.2.2 Inicializao de variveis Arrays.....................................................................35
3.2.3 Utilizao de variveis Array...........................................................................35
3.3 String...................................................................................................................... 37
3.4 Struct..................................................................................................................... 39
3.4.1 Declarao de struct....................................................................................... 39
3.4.2 Utilizao de struct.......................................................................................... 41
3.4.3 Inicializao de struct...................................................................................... 41
3.5 Union...................................................................................................................... 43
3.5.1 Declarao de union....................................................................................... 43
3.5.2 Utilizao de union.......................................................................................... 45
3.5.3 Inicializao de union...................................................................................... 47
3.6 Enum...................................................................................................................... 49
3.6.1 Declarao de enum....................................................................................... 49
3.6.2 Utilizao de enum.......................................................................................... 51
3.6.3 Inicializao de enum...................................................................................... 51
3.6.4 Typedef............................................................................................................ 53
3.7 Expresses............................................................................................................. 55
3.7.1 Operadores unrio, binrios e ternrios..........................................................55
3.7.1.1 Operadores aritmticos............................................................................55
3.7.1.2 Operadores relacionais.............................................................................57
3.7.1.3 Operadores lgicos................................................................................... 57
3.7.1.4 Operadores bit......................................................................................... 59
3.7.1.5 Operadores de atribuio.........................................................................59
3.7.1.6 Operador membro.................................................................................... 61
3.7.1.7 Operadores de gerenciamento de memria.............................................61
3.7.1.8 Operador condicional............................................................................... 63
3.7.1.9 Operador de converso............................................................................63
3.8 Precedncia de operadores:...................................................................................63
4 Aula 3............................................................................................................................ 67
4.1 Blocos..................................................................................................................... 67
4.2 Escopo.................................................................................................................... 67
4.3 Instruo de seleo.............................................................................................. 69
4.3.1 Instruo if...................................................................................................... 69
4.3.2 Instruo switch.............................................................................................. 71
4.4 Instruo de interao............................................................................................ 73
4.4.1 Instruo while................................................................................................ 73
4.4.2 Instruo do / while......................................................................................... 75
4.4.3 Instruo for.................................................................................................... 77
4.4.4 Instruo continue e break..............................................................................79
4.5 Instruo de salto goto........................................................................................... 79
4.6 Funes.................................................................................................................. 81
4.6.1 Declarao...................................................................................................... 83
4.6.2 Definio......................................................................................................... 83
4.6.3 Utilizao......................................................................................................... 85
5 Aula 4............................................................................................................................ 89
5.1 Gerenciamento de memria...................................................................................89
5.1.1 Ponteiro e endereo de memria....................................................................89
5.1.2 Alocao dinmica.......................................................................................... 91
5.1.3 Ponteiros para array........................................................................................ 93
5.1.4 Ponteiros para string....................................................................................... 95
5.1.5 Ponteiro para estruturas.................................................................................. 95
5.1.6 Ponteiros para funo...................................................................................... 97
5.1.7 Ponteiros como parmetros de funo............................................................97
5.2 Durao de armazenamento do objeto..................................................................99
5.3 Especificao de classe de armazenamento..........................................................99
5.3.1 Extern.............................................................................................................. 99
5.3.2 Static............................................................................................................. 101
5.3.3 Const............................................................................................................. 103
5.3.4 Register e restrict.......................................................................................... 103
6 Aula 5.......................................................................................................................... 105
6.1 Biblioteca padro C.............................................................................................. 105
6.2 Rotinas de entrada e sada................................................................................... 105
6.2.1 Arquivos........................................................................................................ 105
6.2.2 Entrada e sada............................................................................................. 107
6.2.2.1 Sada de dados formatada.....................................................................107
6.2.2.2 Entrada de dados formatada..................................................................107
6.2.3 Tratamento de erro........................................................................................ 107
6.2.3.1 Funes teis para o tratamento de erro...............................................109
6.2.4 Passagem de parmetros para o programa...................................................113
7 Material Extra.............................................................................................................. 115
1 Introduo
1.1 O Curso
O curso foi estruturado em cinco aulas sendo cada aula tendo uma parte terica e uma parte prtica com
exerccios e laboratrios. Os captulos seguem a sequencia das aulas.
1 Introduo
7 Material Extra:
Exemplo
if( <expresso lgica> ) <bloco>
[else <bloco>]
Exemplo:
if( 1 > 2 )
comando1();
else
comando2();
1.3 Linguagem de Programao C
Imperativa: o programa descreve uma sequencia lgica de passos que devem ser executados para
resolver o problema. Em oposio ao paradigma declarativo que se expressa o que se espera obter
e no os passos para se chegar nesse objetivo.
Alto nvel ( com acesso a baixo nvel): uma linguagem com um nvel de abstrao relativamente
elevado, longe do cdigo de mquina e mais prximo linguagem humana.
Compilada: o cdigo fonte em texto puro traduzido, ou seja compilado para uma linguagem de
mquina gerando um arquivo executvel.
Tipo de dado esttico: Todos os objetos em C tem um tipo definido seja uma varivel, literal,
funo, etc.. .Esse tipo no alterado durante a existencial do objeto.
1.4.1 Spirit of C
Confie no programador
Na primeira vez preencha hostname e saved session com cenapad.unicamp.br. Depois clica-se
save. Depois de salvo, clica-se open. Nas outras vezes somente clica-se na sesso salva, e depois
open.
3. No terminal preencha o login e password com as informaes da conta recebida no primeiro dia
de aula.
Para acessar o ambiente pelo linux, utilizamos o ssh. O usurio tem que ser substituindo usuario pelo
login passado no primeiro dia de aula.
#ssh usuario@cenapad.unicamp.br
Password:
2.1.2 Sobre o ambiente CENAPAD.
Os ambientes CENAPAD tem como sistema operacional o Linux ou Unix. No curso vamos ver alguns
comandos bsicos para poder editar os exemplos e exerccios.
Diretrio atual #pwd
Listar arquivos e pastas #ls
Entrar em uma pasta #cd pasta
#cd curso_c
Sair dessa pasta #cd ..
Copiar um arquivo #cp origem destino
#cp exemplo01.c teste.c
Renomear um arquivo #mv origem destino
#mv teste.c teste01.c
O ambiente CENAPAD no tem programas grficos para edio de arquivos. Os editores em linha de
comando so o vi e o nano. Para quem j conhece essas ferramentas poder escolher a que mais
confortvel. Quem est conhecendo agora, indicamos o nano pela facilidade nos comandos.
Editar um arquivo existente #nano arquivo
#nano teste01.c
Para navegar entre as linhas ou posies
utilize as teclas seta
Para sair do programa tecle Ctrl+X Se o arquivo no foi alterado, o programa sai
sem perguntar nada.
Se for um arquivo alterado, ele perguntar
Save modiffied buffer Digite Y. Ele
confirmar o nome do arquivo, apenas tecle
Enter.
exemplo01.c
1./*
2. * nome: exemplo01.c
3. * descrio: primeiro exemplo em C
4. * data: 17/08/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. // imprime Bom dia
10. printf(Bom dia\n);
11. return 0;
12.}
Um programa em C um texto com palavras em ingls e simbolos que tem regras lxicas e semnticas
distintas. Essas regras que formam a estrutura e as regras para escrever um programa na linguagem C.
Podemos comear a definir dois tipos bsicos de texto que podemos encontrar, textos da linguagem e
textos de comentrios. Textos da linguagem formam a estrutura do programa e comentrios servem para
documentar o programa e so ignorados pelo compilador.
Os comentrios podem ser de uma linha ou comentrios de mltiplas linhas. Comentrios de mltiplas
linhas comeam com /* e terminam com */ tudo que estiver entre esses smbolos considerado
comentrio. Comentrio de uma linha inicia com // e termina no final da linha.
Nesse exemplo podemos identificar comentrio de vrias linhas da linha 1 at a 5. Comentrio de uma
linha temos na linha 9.
exemplo01.c
13./*
14. * nome: exemplo01.c
15. * descrio: primeiro exemplo em C
16. * data: 17/08/2012
17. */
18.#include <stdio.h>
19.int main()
20.{
21. // imprime Bom dia
22. printf(Bom dia\n);
23. return 0;
24.}
exemplo01.c
1.
2.
3.
4.
5.
6.#include <stdio.h>
7.int main()
8.{
9.
10. printf(Bom dia\n);
11. return 0;
12.}
Se olharmos o cdigo fonte sem os comentrios, a primeira linha com algum comando a linha 6. Essa
linha que inicia com #, que indica um comando especial chamado de pr-processamento. Esse
comando, o include, recebe como parmetro um nome de arquivo que o compilador l o contedo e
coloca no exato lugar do comando.
Normalmente veremos o comando include com arquivos com extenso .h que tem o significado
de header ( cebealho ) que so arquivo de definies. Nesse caso o arquivo stdio.h um
arquivo da biblioteca padro C que define funes de entrada e sada de informaes ( printf na
linha 10 ).
Logo depois, na linha 7 int main() a definio de uma funo em C. Nesse caso a funo com o nome
main ( principal em ingls). Um programa pode ter vrias funes mas somente uma com o nome main
que indica aonde o programa iniciar quando for executado. Alias, o C case-sensetive e diferencia
letras minsculas de maisculas: main diferente de MAIN e diferente de Main.
A funo main tem uma palavra antes o int que uma palavra que define um tipo de dado em C que
representa inteiro. A funo main que por analogia da matemtica (y = f(x)) tem um valor de retorno,
valor de resultado da funo.
Programas tem uma funo main mas se estivermos programando bibliotecas que apenas
disponibilizam uma coleo de funes, no teramos a funo main e o programador que for
usar essa biblioteca que vai definir um main em seu programa.
A funo main inicia na linha 8 com o caractere { e termina na linha 12 com o caractere }. Toas as linhas
entre a 8 e 12 esto na funo main ou mais tecnicamente no escopo da funo main. Toda a linha de
comando em C termina com ;.
Na linha 11 temos uma outra funo a printf que como analogia a funes em matemtica ( y = f(x) ),
recebe como parmetro um texto Bom dia\n. A funo printf imprime na tela do usurio o que recebe
como parmetro ( Bom dia\n ).
Na linha 12 temos a linha return 0; que um comando especial que alm de sair da funo, e nesse caso
do programa, ela especifica o valor de retorno.
Funes retornam ao ponto que ela foi chamado. No caso de main, ela retorna para quem
executou o programa. A conveno que quando retornamos zero ( 0 ) num programa, quer dizer
que ele funcionou como esperado e se tiver valor diferente de zero, seria o nmero de algum erro.
Sada na tela:
Bom dia
Note que os caracteres \n no so exibidos porque essa sequencia representa o carcter de nova-linha.
Existem outras sequencias especiais que veremos durante o curso.
Durante o curso usaremos o printf como ferramenta nos nossos laboratrios. Agora apresentaremos o
bsico necessrio para os laboratrios e no ltimo dia veremos melhor a formatao de dados.
// formato do printf
printf(string formatao, [var, var, var,...]);
A string de formatao um texto que podemos escrever literalmente ou podemos indicar locais para a
incluso de variveis usando % e um qualificador que define o tipo e a formatao de sada de cada
item. Para cada % que achamos, ele ira usar uma varivel da lista de variveis.
printf(%d %d %d \n, 1 , 2 , 3 );
para cada %d o printf coloca o valor do prximo literal ou varivel
Letra Descrio
i ou d Inteiro
u Inteiro sem sinal
o Octal sem sinal
X ou x Hexadecimal sem sinal
F ou f Ponto flutuante.
E ou e Ponto flutuante notao cientifica.
G ou g Usar a melhor representao e ou f
A ou a Ponto flutuante em hexadecimal com sinal
c Caractere.
s String
p Ponteiro
Exemplo02.c
1./*
2. * nome: exemplo02.c
3. * descrio: Printf
4. * data: 08/04/2013
5. */
6.#include <stdio.h>
7.int main()
8.{
9. // O comando printf
10. printf("Bom dia\n");
11. printf("L11) 10 = %d,%i,%u,%o,%x\n",10,10,10,10,10);
12. printf("L12) -10 = %d,%i,%u,%o,%x\n",-10,-10,-10,-10,-10);
13. printf("L13) 0.10 = %f,%e,%g,%a,%x\n",0.10,0.10,0.10,0.10,0.10);
14. printf("L14) -0.10 = %f,%e,%g,%a \n" ,-0.10,-0.10,-0.10,-0.10);
15. printf("L15) char = %c string = %s\n", 'a' ,"Bom dia");
16. return 0;
17.}
2.2.2 Exerccio ambiente CENAPAD
3) Crie um programa em C com o nome nome.c. Esse programa imprimir o seu nome. Pode utilizar
como exemplo o programa exemplo01.c.
5) Execute ele.
O compilador C quando processa um arquivo ele separa o texto em elementos que chamamos de
toquem. Que so partes atmicas, que sozinho tem uma funo prpria no programa. Podemos classificar
os toquens em: palavra reservada, identificador, constantes, literal string e pontuao.
A linguagem de programao C tem poucas palavras reservadas comparado com outras linguagens de
programao e podemos listar elas:
auto enum restrict unsigned
break enum return void
case float return volatile
char for signed while
const goto sizeof _Bool
continue if static _Complex
default inline struct _Imaginary
do int switch
double long typedef
else register union
Identificador o nome que podemos dar ou identificar os objetos em C. Identificador pode ser uma
varivel, uma funo, uma tag, membro de uma estrutura ou unio, um nome typedef, um nome de label,
um parmetro de macro.
Podemos usar o mesmo identificador para tipos diferentes em pontos(escopos) diferentes do programa,
como podemos ter uma varivel com o mesmo nome de funo.
Constantes e literal string so como descrevo os valores no cdigo fonte. Por exemplo o valor numrico
10 ou o carcter 'a' ou no caso de constante string Bom dia.
Pontuao so smbolos usados tanto nas operaes matemticas ou lgicas ou para delimitar o escopo
ou final de linha.
2.4 Tipo de dado em C
Como a linguagem C de tipagem esttica, tanto os valores literais quanto variveis so de um tipo de
dado definido. Podemos separar esses tipos de dados em primitivos e derivados.
Esses grupos de tipos de dados so escalares podendo realizar todas as operaes matemticas, lgicas e
comparativas. Isso natural para nmeros mas o caractere a representao em bit de um valor
numrico e essa representao definida pela tabela ASCII ( letra 'a' o nmero 97).
Array: Estrutura que podemos agrupar valores em formato de vetores ou matrizes de vria
dimenses. Cada um pode ser referenciado pelo um ndice numrico.
Struct: Estrutura que podemos agrupar variveis de tipo diferente. Cada varivel componente
referenciada pelo nome dela.
Union: Estrutura anloga ao struct mas todas as variveis ocupam o mesmo espao na memria.
Usado para economizar memria.
Para usar variveis em C precisamos primeiramente declara-la informando o nome e o tipo dela.
<tipo> nome;
// Se formos declarar uma varivel do tipo int ( inteiro ).
int contador;
Podemos tambm declarar variveis do mesmo tipo na mesma linha separadas por virgula.
<tipo> var1, var2, varn;
// Se formos declarar x,y,z como int ( inteiro )
int x,y,z;
Para inicializar uma varivel atribumos algum valor neutro para essa varivel. Podemos aproveitar a
declarao da varivel para a inicializao dela.
<tipo> nome=valor;
int contador;
int x,y,z;
contador =1;
x=0;
y=z=0;
exemplo03.c
1./*
2. * nome: exemplo03.c
3. * descrio: Declarao e inicializao de variveis
4. * data: 11/02/2014
5. */
6.#include <stdio.h>
7.int main()
8.{
9. // Declarao e inicializao de variveis
10. int contador=0;
11. int x=1,y=1;
12. char c;
13. c='x';
14.
15. printf(Bom dia\n);
16. printf(contador=%d\n,contador);
17. printf(x=%d, y=%d\n,x,y);
18. printf(c=%c\n,c);
19.
20. return 0;
21.}
Essas definies de capacidade de varivel podem variar de acordo com a arquitetura do ambiente
computacional e se for preciso ter que ser tradada pelo programador (Faa a linguagem rpida, mesmo
que no tenha portabilidade).
A capacidade numrica calculada de acordo com a quantidade de bits, que proporcional a magnitude
numrica. Se o valor extrapolar esse limite pode ocorrer problemas overflow.
Por exemplo, se um short int x = 32767 e somarmos +1 ele ficar com -32767.
O padro do tipo de dado signed int mas podemos omitir a palavra signed. Declarar o tipo signed int
igual a int.
Tipo Capacidade
short int 16 bits ( -32767 ... +32767 )
unsigned short int 16 bits sem sinal ( 0 ... 65535 )
int 16 bits ( -32767 ... +32767 )
unsigned int 16 bits sem sinal ( 0 ... 65535 )
long int 32 bits ( -2147483647 ... +2147483647 )
unsigned long int 32 bits sem sinal ( 0 ... 4294967295 )
long long int 64 bits ( -9223372036854775807 ...
+9223372036854775807 )
unsigned long long int 64 bits sem sinal ( 0 ...
18446744073709551615 )
Um exemplo completo
exemplo04.c
1./*
2. * nome: exemplo04.c
3. * descrio: Declarao de variveis inteiras
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. short int km;
10. unsigned short int idade;
11. long int cm;
12. unsigned long int saldo_cc;
13. long long int mm;
14. unsigned long long int moleculas;
15. return 0;
16.}
Podemos verificar se o ambiente que estamos usando segue o padro C usando a funo sizeof. Essa
funo retorna a quantidade de bytes que so 8 bits.
exemplo05.c
1./*
2. * nome: exemplo05.c
3. * descrio: Declarao de variveis inteiras
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. printf(short int = %lu\n, sizeof(short int));
10. printf(unsigned short int = %lu\n, sizeof(unsigned short int));
11. printf(long int = %lu\n, sizeof(long int));
12. printf(unsigned long int = %lu\n, sizeof(unsigned long int));
13. printf(long long int = %lu\n, sizeof(long long int));
14. printf(unsigned long long int = %lu\n, sizeof(unsigned long
long int));
15. return 0;
16.}
No C nmeros de ponto flutuante pode ser representado por float ou double e suas variaes. Essas
variaes definem a capacidade de representao numrica. Quanto maior a quantidade de bits, maior a
capacidade de representao numrica. Se o valor extrapolar esse limite pode ocorrer problemas
overflow e underflow.
Overflow pode ser como o exemplo com nmeros inteiros. J o Undeflow quando um nmero to
pequeno como 0,000000000001 com 12 casas, mas o tipo somente aceitaria 10 e nesse caso ele seria
arredondado para zero.
Essas definies de capacidade de varivel podem variar de acordo com a arquitetura e do ambiente
computacional e se for preciso ter que ser tradada pelo programador (Faa a linguagem rpida, mesmo
que no tenha portabilidade).
Tipo Capacidade
float 16 bits
double 62 bits
long double 64 bits
exemplo06.c
1./*
2. * nome: exemplo06.c
3. * descrio: Declarao de variveis ponto flutuante.
4. * data: 08/04/2013
5. */
6.#include <stdio.h>
7.int main()
8.{
9. float km;
10. double cm;
11. long double mm;
12. return 0;
13.}
Podemos verificar se o ambiente que estamos usando segue o padro C usando a funo sizeof. Essa
funo retorna a quantidade de bytes que so 8 bits.
exemplo07.c
1./*
2. * nome: exemplo07.c
3. * descrio: Declarao de variveis inteiras
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. printf(float = %lu\n, sizeof(float));
10. printf(double = %lu\n, sizeof(double));
11. printf(long double = %lu\n, sizeof(long double));
12. return 0;
13.}
2.6.3 Caractere.
No C caractere representa uma letra somente que o tipo char. O char um tipo escalar porque cada letra
pode ser representada por um nmero como na tabela ASCII.
String em c no um tipo primitivo. String implementado como um vetor de char. Veremos esse
tipo na prxima aula.
Tipo Capacidade
char 1 byte
unsigned char 1 byte
wchar_t 4 bytes
exemplo08.c
1./*
2. * nome: exemplo08.c
3. * descrio: Declarao de variveis caractere.
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. char letra;
10. unsigned char nota;
11. wchar_t utf;
12. return 0;
13.}
Podemos verificar se o ambiente que estamos usando segue o padro C usando a funo sizeof. Essa
funo retorna a quantidade de bytes que so 8 bits.
exemplo09.c
1./*
2. * nome: exemplo09.c
3. * descrio: Declarao de variveis inteiras
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. printf(char = %lu\n, sizeof(char));
10. printf(unsigned char = %lu\n, sizeof(unsigned char));
11. printf(wchar_t = %lu\n, sizeof(wchar_t));
12. return 0;
13.}
Podemos representar valores inteiros em base decimal, octal e hexadecimal. Podemos tambm qualificar
o inteiro como long, long long ou unsigned.
// Nmeros na base 10
0 , 1 , 3 ... 10 , 11 ... , 100 , -100
Podemos representar literais ponto flutuante na notao decimal e na notao cientifica. Ambos as
notaes podem ser representadas na base decimal e hexadecimal. O qualificador padro signed float
mas podemos mudar para float ou para long double.
Para representar um numero ponto flutuante usamos o ponto para separar a parte inteira da frao. Se
no tiver a parte fracionada podemos colocar .0 ou apenas .
// Nmeros na base 10
0.5 , 5.0 , 5.
Literais caractere representam somente um caractere e representamos ele entre aspas simples '. A
linguagem C trabalha com string sendo um conjunto de caractere como um vetor. Caracteres so
escalares e podemos realizar todas as operaes.
// Letras
'a', 'b', 'c'
Para cada tipo de dado primitivo existe uma diretiva do printf e podemos listar elas
Letra Descrio
i ou d Inteiro
u Inteiro sem sinal
hu short int
lu long int
llu long long int
f double/float
Lf long double
2.8 Exerccios
1.#include <stdio.h>
2.____________________
3.{
4. printf(Bom dia\n)___
5. return___;
6.___
Cdigo B
1.#___ <stdio.h>
2.int main()
3.___
4. int a____;
5. float ___=2.1;
6. long ___ x=23.1L;
7. printf(a=%d\n,___);
8. printf(y=%f\n,y);
9. printf(x=%Ld\n___ x)___
10. ____;
11.}
b) char letra
b) letra = x
c) pi = 3.14159265358979323846
3.Faa a cpia do lab01.c com o nome lab01nc.c e altere todos os literais para notao cientfica, caso
possa ser aplicado.
3 Aula 2
Os tipos de dados derivados o programador que define o formato do dado e ele tambm deve
implementar rotinas ou funes que trabalhem com esse tipo de dado. A linguagem de programao no
fornece operadores nesses tipos de dados.
3.2 Arrays
O C padro 99 e posteriores aceita o formato VLA ( laviable-length array array de tamanho varivel ) que
quer dizer que podemos definir o tamanho do array na execuo do programa, diferente da alocao
esttica que definida na compilao. No confundir com alocao dinmica que poderia alterar
dinamicamente o tamanho do array em qualquer hora do cdigo. O C aceta array estatico e VLA mas no
array dinamico. Nesse caso podemos utilizar alocao dinamica de memoria.
// Array esttico
int vetor[10];
// Array VLA
n = argumento(1);
int vetor[n];
a
// Array dinmico, somente para exemplo, no existe no C
// int vetor[10];
// novo_tamanho(vetor,20);
Para declarar um array, precisamos definir o tipo de dado dos elementos e a quantidade.
<tipo> nome[tamanho]; // um vetor
<tipo> nome[tamanho1][tamanho2]; //matriz de duas dimenses.
Um erro comum declarar um vetor de tamanho x e usar a posio x. O C permitir mas isso seria
acesso indevido a memria e o efeito disso no pode ser previsto.
exemplo10.c
1./*
2. * nome: exemplo10.c
3. * descrio: Declarao de vetores e matrizes
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int idade;
10. int dataNascimento[3];
11. int matriz2D[10][10], matriz3D[10][10][10];
12. return 0;
13.}
Quando declaramos um vetor ou uma matriz a linguagem de programao no inicializa eles com algum
valor, ele apenas reserva memria suficiente para o vetor ou a matriz inteira e essa posio da memria
pode ter valores que outro programa que executou antes deixou na memria.
<tipo> vetor[tam];
vetor[0]=valor;
vetor[1]=valor; // at tam-1
exemplo11.c
1./*
2. * nome: exemplo11.c
3. * descrio: Declarao e inicializao de vetores e matrizes
4. * data: 13/02/2014
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int idade=34;
10.
11. int dataNascimento[3]={3,1,1978};
12.
13. int matriz2D[2][2] = { {0,1}, {10,11} };
14.
15. int outra2D[2][2] = { 0, 1, 10, 11 };
16.
17. int diasMes[] = {31,29,31,30,31,30,31,31,30,31,30,31};
18.
19. int naoC99[2];
20. naoC99[0]=10;
21. naoC99[1]=20;
22.
23. return 0;
24.}
Quando compomos um vetor ou uma matriz com um tipo primitivo, podemos usar as operaes que o C
implementa indicando item por item. No podemos usar o formato de literais compostos para atribuir
valores para matrizes.
<tipo> nome[tam];
nome[posio] = literal;
Um erro comum tentar usar uma posio fora do limite da array e pode gerar comportamentos
inesperados no programa. Podendo at parar a execuo atual (travar).
exemplo12.c
1./*
2. * nome: exemplo12.c
3. * descrio: Declarao e utilizao de vetores e matrizes
4. * data: 09/04/2013
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int idade=35;
10.
11. int dataNascimento[3];
12. dataNascimento[0]=3;
13. dataNascimento[1]=1;
14. dataNascimento[2]=1978;
15.
16. printf(Data de nascimento %d/%d/%d, idade = %d\n,
dataNascimento[0], dataNascimento[1],
17. dataNascimento[2], idade );
18.
19. return 0;
20.}
3.3 String
String em C implementado como um vetor de char que termina com um caractere especial '\0'. Se
tivermos uma string Texto ela teria 6 posies (mais a posio do caracter nlo) iniciando com 0 at 5.
T e x t o \0
Um erro comum tentar usar uma posio fora do limite da string e pode gerar comportamentos
inesperados no programa.
Um outro problema apagar o caractere de final de string '\0'. Se no tiver esse caractere uma
funo que trabalhe com string ir transpor o limite dela at que em alguma outra posio
aleatria da memria tiver um '\0' o que pode gerar acesso indevido a memria.
char string[tamanho];
char string[tamanho]=Texto;
char string[]=Texto;
String como vetor funciona como array, no pode-se alterar o tamanho dela automaticamente mas
podemos alterar caractere por caractere como se fosse um vetor. Podemos tambm utilizar funes que
tratam de string. A biblioteca padro do C tem vrias funes que trabalham com string.
char string[tamanho]=Texto;
string[0]='t';
exemplo13.c
1./*
2. * nome: exemplo13.c
3. * descrio: Declarao e utilizao de strings
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. char nome[]=Carlos Henrique Rebollo;
10. char profissao[9]=Analista;
11.
12. printf(Nome %s ( letra inicial %c) profisso %s \n, nome,
nome[0], profissao);
13.
14. return 0;
15.}
3.4 Struct
Struct so estrutura que agrupam variveis com tipos de dado diferente e sendo cada posio nomeada e
no indexada como vetores. Podemos compor structs com variveis do tipo primitivo ou com tipos
derivados at compor struct com struct.
Nesse caso:
nometipo: o nome desse tipo struct, podemos declarar variveis usando esse nome.
Na linha struct nometipo outrovar estamos declarando outra variavel do tipo struct nometipo que
j foi definido.
exemplo14.c
1./*
2. * nome: exemplo14.c
3. * descrio: Declarao de struct
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. struct data
10. {
11. int dia,mes,ano;
12. } hoje;
13.
14. struct data amanha;
15.
16. return 0;
17.}
3.4.2 Utilizao de struct
Para utilizar uma struct usamos cada varivel componente separadamente usando var.componente
struct nometipo
{
<tipo1> var1;
<tipo2> var2;
...
<tipon> varn;
} vstruct1,vstruct1;
vstruct.var1=valor1;
vstruct.var2=valor2;
exemplo15.c
1./*
2. * nome: exemplo15.c
3. * descrio: Declarao de struct
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. struct data
10. {
11. int dia,mes,ano;
12. } hoje;
13.
14. struct data amanha;
15.
16. hoje.dia=17;
17. hoje.mes=10;
18. hoje.ano=2012;
19.
20. // amanha = hoje + 1; // erro de compilao
21.
22. printf(Data de hoje %d/%d/%d\n, hoje.dia, hoje.mes, hoje.ano);
23. return 0;
24.}
3.4.3 Inicializao de struct
exemplo16.c
1./*
2. * nome: exemplo16.c
3. * descrio: Declarao, inicializao e utilizao de struct
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. struct data
10. {
11. int dia,mes,ano;
12. } hoje = { .dia = 17, .mes = 10, .ano = 2012 };
13.
14. struct data amanha;
15.
16. amanha.dia=hoje.dia+1;
17. amanha.mes=hoje.mes;
18. amanha.ano=amanha.ano;
19.
20. printf(Data de hoje %d/%d/%d\n, hoje.dia, hoje.mes, hoje.ano);
21. printf(Data de amanha %d/%d/%d\n, amanha.dia, amanha.mes,
amanha.ano);
22.
23. return 0;
24.}
3.5 Union
Union um tipo de estrutura anloga ao struct mas todas as variveis ocupam o mesmo espao na
memria. Usado para economizar memria. O tamanho total dessa estrutura o tamanho da maior
varivel componente.
3.5.1 Declarao de union
Nesse caso:
nometipo: o nome desse tipo union, podemos declarar variveis usando esse nome.
Na linha union nometipo outravar estamos declarando outra varivel do tipo union nometipo que
j foi definido.
exemplo17.c
1./*
2. * nome: exemplo17.c
3. * descrio: Declarao de union
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. union valor
10. {
11. int inteiro;
12. float real;
13. double big_real;
14. } val1;
15.
16. union valor val2;
17.
18. return 0;
19.}
Para utilizar uma union usamos cada varivel componente separadamente usando var.componente mas
ao contrrio da struct somente uma delas ter um valor significativo.
Um erro comum ao usar union definir uma varivel componente de um tipo e usar uma outra
varivel componente de outro tipo. Para a utilizao correta da union precisaria de uma varivel
auxiliar que indique qual a varivel que tem o valor significativo.
union nometipo
{
<tipo1> var1;
<tipo2> var2;
...
<tipon> varn;
} vunion1,vunion1;
vunion.var1=valor1;
vunion.var2=valor2;
exemplo18.c
1./*
2. * nome: exemplo18.c
3. * descrio: Declarao e utilizao de union
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. union valor
10. {
11. int inteiro;
12. float real;
13. double big_real;
14. } val1;
15.
16. val1.inteiro=10;
17.
18. printf("inteiro %d\n", val1.inteiro);
19. printf("real %f\n", val1.real);
20. printf("big_real %f\n", val1.big_real);
21.
22. val1.real=1.5;
23.
24. printf("inteiro %d\n", val1.inteiro);
25. printf("real %f\n", val1.real);
26. printf("big_real %f\n", val1.big_real);
27.
28. return 0;
29.}
Um exemplo aonde usa-se uniom com uma varivel auxiliar:
struct taggedunion {
enum {UNKNOWN, INT, LONG, DOUBLE, POINTER} code;
union {
int i;
long l;
double d;
void *p;
} u;
};
//referencia http://c-faq.com/struct/taggedunion.html
exemplo19.c
1./*
2. * nome: exemplo19.c
3. * descrio: Declarao, inicializao e utilizao de union
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. union valor
10. {
11. int inteiro;
12. float real;
13. double big_real;
14. } val1= { .inteiro=10 };
15.
16. union valor val2;
17.
18. val2.real = 1.5;
19.
20. printf("inteiro %d\n", val1.inteiro);
21. printf("real %f\n", val1.real);
22. return 0;
23.}
3.6 Enum
Enum um tipo de estrutura de dado aonde posso enumerar opes usando nomes. Esses nomes so
significativos para o C e representam constantes com o valor numrico. Cada constante da enumerao
tem um valor numrico e por padro inicia com 0 e incrementado para cada constante. Podemos alterar
esses valores.
Nesse caso:
nometipo: o nome desse tipo enum, podemos declarar variveis usando esse nome.
Na linha enum nometipo outravar estamos declarando outra varivel do tipo enum nometipo que
j foi definido.
exemplo20.c
1./*
2. * nome: exemplo20.c
3. * descrio: Declarao de enum
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. enum cores { vermelho, verde, azul } val1;
10.
11. enum estado_civil { solteiro=1, casado, viuvo=5, desquitado };
12.
13. enum estado_civil val2;
14.
15. return 0;
16.}
3.6.2 Utilizao de enum.
Para utilizar uma enum usamos cada varivel diretamente no cdigo fonte. Cada uma das opes ter um
nmero associado, enumerado.
enum nometipo { const1 ,const2, constm };
} venum1,venum2;
venum1=const1;
printf(%u %u\n,venum1, const2);
exemplo21.c
1./*
2. * nome: exemplo21.c
3. * descrio: Declarao e utilizao de enum
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. enum cores { vermelho, verde, azul } val1;
10.
11. enum estado_civil { solteiro=1, casado, viuvo=5, desquitado };
12.
13. enum estado_civil val2;
14.
15. val1=azul;
16. val2=casado;
17.
18. printf(cores %u %u %u\n, vermelho, verde, azul );
19. printf(variaveis %u %u \n, val1, val2 );
20.
21. return 0;
22.}
venum1=const1;
exemplo22.c
1./*
2. * nome: exemplo22.c
3. * descrio: Declarao, inicializao e utilizao de enum
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. enum cores { vermelho, verde, azul } val1=azul;
10.
11. enum estado_civil { solteiro=1, casado, viuvo=5, desquitado };
12.
13. enum estado_civil val2;
14.
15. val2=casado;
16.
17. printf(cores %u %u %u\n, vermelho, verde, azul );
18. printf(variaveis %u %u \n, val1, val2 );
19.
20. return 0;
21.}
3.6.4 Typedef
Typedef define tipos de dados definidos pelo programador que a linguagem de programao reconhece
como um tipo definido.
O tipo de dado novo dependedo como foi criado pode ser primitivo ou derivado e seguir as mesmas
regras seja na declarao, inicializao e utilizao.
nome_tipo var;
Um exemplo completo seria:
exemplo23.c
1./*
2. * nome: exemplo23.c
3. * descrio: typedef
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9.
10. typedef int inta, intb[2], intc[2][2];
11. typedef char chara, charb[];
12. typedef struct tipostruct { int x; } novo_tipo; // novo_tipo no
varivel
13.
14. inta ia = 10;
15. intb ib = { 1 , 2 };
16. intc ic = { {1 , 2} , {11 , 12} };
17. chara ca = 'a';
18. charb cb = Hello;
19. novo_tipo ta = { .x = 100 };
20. // ou declarar struct tipostruct ta = { .x = 100 };
21.
22. printf( ia=%d, ib[1]=%d, ic[1][1]=%d\n, ia, ib[1], ic[1][1]);
23. printf( ia=%c, ib=%s\n, ca, cb);
24. printf( ta.x=%d\n, ta.x );
25.
26. return 0;
27.}
3.7 Expresses
Uma expresso uma sequencia de operadores e operandos que resulta em um valor ou que resulta em
um objeto ou em uma funo, ou que resulte em uma atribuio, ou que faa um conjunto dessas aes.
Operadores podem ser classificado de acordo com a quantidade de operandos. Em C temos operadores
unrios, binrios e ternrios.
Esses operadores podem ser didaticamente classificados como: aritmticos, relacionais, lgicos,
condicionais, operador bit, atribuio, membro ( estruturas ) e gerenciamento de memria e converso.
Operadores aritmticos podem ser usados em qualquer tipo de dado escalar seja nmeros inteiros, reais e
caractere. Quando realizamos operaes com o mesmo tipo de dado o resultado do mesmo tipo. Se
forem do tipo diferente, a converso ser automtica e tentar converter para o tipo mais apropriado para
a operao.
o var tem que ser um lvalue, ou seja, uma varivel escalar e que possa ser atribudo valores ( no
constante).
A diferena do prefixo e sufixo que no prefixo o operador incrementa a varivel e depois fornece para a
expresso o valor dela. No caso do sufixo, ele fornece o valor atual dela e depois a varivel
incrementada.
exemplo24b.c
1./*
2. * nome: exemplo24b.c
3. * descrio: Operadores ++ e --
4. * data: 13/02/2014
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int x=1,y=3,z=5;
10. y=x++;
11. z=++x;
12. printf(x=%i, y=%i e z=%i\n, x, y, z );
13. return 0;
14.}
3.7.3 Operadores relacionais.
Os operadores binrios so: < (menor), > (maior), <= ( menor ou igual), > ( maior ou igual), == ( igual ) e !=
(diferente).
exemplo25.c
1./*
2. * nome: exemplo25.c
3. * descrio: Operadores relacionais binrios
4. * data: 10/04/2013
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int x=1,y=3,z=5;
10.
11. printf("x>y %i, x<z %i e y<=z %i\n", x>y, x<z, y<=z );
12.
13. printf("x==y %d e x!=z %d\n", x==y, x!=z );
14.
15. printf("%d\n", z > y > x);
16.
17. return 0;
18.}
Operadores lgicos binrios comparam dois valores lgicos e retornam um valor lgico. Podemos
comparar qualquer valor escalar e se o valor escalar for 0 ( zero ) ser falso caso contrario ser verdadeiro.
O resultado ser 0 ou 1. O nico operador lgico unrio negao (!).
Os operadores bit operam com dois valores em lgica binria e retornaria um escalar. No vamos detalhar
esses operadores nesse curso porque necessitaria de conhecimento de calculo binrio que foge o escopo
de curso bsico.
Os operadores binrios so: & ( e binrio ), | ( ou binrio ), ^ ( ou exclusivo), << ( shift para esquerda) e >>
shift para a direita.
lvalue o valor da esquerda que tem que ser um objeto modificvel como uma varivel.
Os operadores so: atribuio simples (=) e atribuio com operador +=, -=, *=, /=, %=, &=, |=, ^=, <<=,
>>=.
exemplo28.c
1./*
2. * nome: exemplo28.c
3. * descrio: Operadores de atribuio
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int x=0,y=0,z=10;
10.
11. x = 1;
12. y+= x+1;
13. z%=y;
14.
15. printf(x=%i, y=%i e z=%i\n, x, y, z );
16.
17. return 0;
18.}
Operadores membro so usados para acessar membros de estruturas struct e union. Existem dois
operadores o . ( ponto ) e o -> (trao ponto). O primeiro membro de estrutura e o segundo membro
de ponteiro que veremos mais adiante no curso.
exemplo29.c
1./*
2. * nome: exemplo29.c
3. * descrio: Operador membro
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. struct data
10. {
11. int dia,mes,ano;
12.
13. } hoje = { .dia = 17, .mes = 10, .ano = 2012 };
14.
15. printf(Data de hoje %d/%d/%d\n, hoje.dia, hoje.mes, hoje.ano);
16.
17. return 0;
18.}
3.7.8 Operadores de gerenciamento de memria
Vamos listar os operadores de gerenciamento de memria que veremos mais adiante no curso.
Operadores unrios: [] ( operador array), * ( ponteiro), & ( endereo de), -> ( membro de ponteiro para).
O operador avalia a expresso, se esse valor escalar for 0 ele falso e retorna o valor falso, caso contrrio o
verdadeiro. Ele seira um if/else em uma expresses.
exemplo30.c
1./*
2. * nome: exemplo30.c
3. * descrio: Operadores relacionais binrios
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int x=1,y=3,z=5;
10.
11. x = x>y ? x : y;
12. z = !z ? 10 : z+10;
13.
14. printf(x=%i,y=%i e z=%i \n, x, y, z );
15.
16. return 0;
17.}
Pomos usar essa converso para poder usar o / com variveis int.
int x=1,y=2;
float z=(float)x/y;
z=x/(float)z;
z=(float)x/(float)z;
3.8 Precedncia de operadores:
3.9 Exerccios
"Curso %x"
"Curso %x"
"Curso %x"
4 Aula 3
4.1 Blocos
Em C criamos blocos com os caracteres { e } que agrupam logicamente um conjunto de comandos seja
para formar um bloco de uma funo ou at um bloco annimo. Blocos tambm delimitam o escopo.
exemplo31.c
1./*
2. * nome: exemplo31.c
3. * descrio: Blocos em C
4. * data: 06/11/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9.
10. printf(Bom dia\n);
11.
12. {
13. printf(Dentro do bloco\n);
14. }
15.
16. return 0;
17.}
4.2 Escopo
Se lembrarmos que identificador pode ser um objeto, uma funo, uma tag, membro de estrutura,
membro de unio, ou enumerao, um nome typedef, um nome de label. O escopo define o limite aonde
um identificador pode ser visto, ou seja, ser usado. Podemos ter escopo de arquivo, bloco, funo e
declarao de funo.
Como podemos declarar objetos em qualquer parte do programa, podemos identificar se dois objetos
esto no mesmo escopo quando eles terminam no mesmo ponto. O nome do identificador tem que ser
nico no mesmo escopo. Se for de escopos diferentes, a declarao do escopo interno esconde a
declarao do escopo externa.
exemplo32.c
1./*
2. * nome: exemplo32.c
3. * descrio: Escopo em C
4. * data: 06/11/2012
5. */
6.
7.int var_a=10;
8.
9.#include <stdio.h>
10.int main()
11.{
12. int x=1;
13. {
14. char x='a'; // esse X sobrepe a declarao anterior
15. {
16. int x=20;
17. int var_b=20;
18. printf(Dentro do bloco interno %d\n,x);
19. printf(var_a=%d,var_b=%d\n,var_a,var_b);
20. }
21. printf(Dentro do bloco %c\n,x);
22. }
23. // int x=100; // no mesmo escopo
24. printf(var_a=%d\n,var_a);
25. // printf(var_b=%d\n,var_b);
26. printf(Fora do escopo %d\n, x);
27. return 0;
28.}
Instrues de seleo desviam o caminho lgico do programa que seria executar uma linha por vez de
cima para baixo. Dependendo da instruo e da condio executar um comando/bloco ou outro ou
nenhum.
4.3.1 Instruo if
A instruo if avalia a condio, caso seja verdadeira, ele executa o comando/bloco se no, o
comando/bloco ignorado. A instruo if tem os formatos:
if( condio ) comando;
if( condio )
{
//bloco do if
}
O comando if avalia se condio verdadeira, isso o resultado diferente de zero. Se sim executado o
comando ou o bloco do if. A condio pode ser um literal, uma varivel ou uma expresso.
Podemos usar o if em conjunto com o eles que seria o comando/bloco executado caso o teste seja falso.
if( condio )
{
//bloco do if
}
else
{
//bloco do else
}
//podemos tambm combinar os dois
//ou
if( condio )
{
//bloco do if
}
else comando else;
O comando if pode conter internamente outro if que chamamos if alinhados. Quando temos ifs
alinhado o indicado usar sempre blocos para no confundir qual if faz referencia com qual else.
4.3.2 Instruo switch
A instruo switch composta por uma expresso e vrios cases. Dependendo do valor da expresso, ele
passar a executar o case especfico. Seria uma sintaxe de vrios if-else seguidos. A instruo switch tem o
formato:
switch ( expresso )
{
case numero: comandos; break;
case outro_numero: comandos; break;
default: comandos; break;
}
A instruo switch avalia a expresso e realiza um salto para o case que tenha o mesmo valor.
Cada case nmero um seletor de salto e o C comea a executar o cdigo a partir desse ponto at
encontrar a instruo break que para a execuo ou o final do comando switch.
O default uma case que selecionado se nenhum outro case for selecionado.
Para teste, retire os comandos break do exemplo anterior e defina o x como 2. Compile, execute e
verifique o que impresso.
Instrues de interao desviam o caminho lgico do programa que seria executar uma linha por vez
somente uma vez para dependendo da instruo e de sua condio executar um comando/bloco uma
vez, vrias vezes ou nenhuma.
Um erro comum usar uma instruo de interao que nunca chega a condio de parada e fica
executado sem parar. Isso chamado de loop infinito.
O while avalia a condio e enquanto ela for verdadeira esse comando ou bloco executado. Essa
condio pode ser uma varivel ou uma expresso. Se o valor escalar for zero falso caso contrrio
verdadeiro.
No exemplo anterior o primeiro while exibiu quais valores para cont e o segundo while? Qual seria a
diferena no segundo while se usarmos --cont ou cont--? Teria alguma diferena?
4.4.2 Instruo do / while
A instruo do/while parecida com a while mas o teste de condio fica no final do comando/bloco e
independente da condio esse comando/bloco ser executado pelo menos uma vez.
No exemplo anterior o primeiro do/while exibiu quais valores para cont e o segundo do/while? Qual seria
a diferena no segundo do/while se usarmos --cont ou cont--? Teria alguma diferena?
4.4.3 Instruo for
O comando for tem trs expresses que didaticamente chamamos de inicializao, condio e expresso.
O for executa primeiramente e somente uma vez a inicializao, depois executa a condio, se ela for
verdadeira executa o comando/bloco. Nas prximas vezes, executa a expresso, avalia a condio e se for
verdadeira executa novamente o comando/bloco.
A expresso inicializao normalmente uma atribuio inicial a uma varivel contador mas pode ser
qualquer expresso ou pode ser omitida do comando. No C99 essa expresso pode ser a declarao de
uma varivel que ter o escopo de bloco for.
A expresso normalmente um incremento da varivel contador mas pode ser qualquer expresso ou
pode ser omitida.
exemplo37.c
1./*
2. * nome: exemplo37.c
3. * descrio: for
4. * data: 06/11/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int cont;
10.
11. for( cont=1 ; cont<=10 ; cont++)
12. printf(C1 cont=%d\n,cont);
13.
14. for( ; cont >=0 ; cont-- )
15. {
16. printf(C2 cont=%d\n,cont);
17. }
18.
19. for( ; cont<=10 ; )
20. printf(C3 cont=%d\n,cont++);
21.
22. for( int outro=1 ; outro<=10 ; outro++ )
23. printf(C4 outro=%d\n,outro++);
24.
25. for( int outro=10,cont=1 ; outro>=0 && cont<=10 ; outro--,cont++ )
26. printf(C5 cont=%d e outro=%d\n,cont, outro);
27.
28. return 0;
29.}
Compilando esse programa com -Wall tem o alerta declaration hides variable cont. Que isso quer dizer?
As instrues continue e break so usadas dentro das instrues de interao e no caso do break tambm
na instruo seleo switch.
O continue sendo executado dentro de uma instruo de interao, ele para a execuo normal do bloco,
e passa a executar a prxima interao. O break tambm para a execuo normal mas ele termina a
execuo de interao.
exemplo38.c
1./*
2. * nome: exemplo38.c
3. * descrio: while e do while
4. * data: 06/11/2012
5. */
6.#include <stdio.h>
7.int main()
8.{
9. int cont=1;
10. while( cont++ <=10 )
11. {
12. if( cont==3 ) continue;
13. if( cont==5 ) break;
14. printf(C1 cont=%d\n,cont);
15. }
16.
17. do
18. {
19. if( cont==3 ) continue;
20. if( cont==5 ) break;
21. printf(C2 cont=%d\n,cont);
22. } while( cont-- >= 0 );
23.
24. for( cont=1 ; cont <= 10 ; cont++)
25. {
26. if( cont==3 ) continue;
27. if( cont==5 ) break;
28. printf(C3 cont=%d\n,cont);
29. };
30. return 0;
31.}
A instruo de salto goto desvia o caminho lgico de execuo para outro ponto no cdigo que
definimos com um nome, um label.
4.6 Funes
Funes so estruturas que permite que o programa seja desenvolvido em blocos funcionais. A funo
em C como funes em matemtica, recebe parmetros e gera um valor de resultado. No C os parmetros
e o resultado so tipados.
Exemplo40.c
1./*
2. * nome: exemplo40.c
3. * descrio: funes
4. * data: 06/11/2012
5. */
6.#include <stdio.h>
7.int inc(int x)
8.{
9. x++;
10. return x;
11.}
12.int dec(int x)
13.{
14. x--;
15. return x;
16.}
17.
18.int main()
19.{
20.
21. int var=0;
22. printf("inc(var)=%d\n",inc(var));
23. printf("dec(var)=%d\n",dec(var));
24.
25. var=inc(var);
26.
27. printf("inc(var)=%d\n",inc(var));
28. printf("dec(var)=%d\n",dec(var));
29.
30. return 0;
31.}
4.6.1 Declarao
A declarao da funo opcional mas uma funo somente pode ser chamada depois de ser declarada
ou de ser definida. Se uma funo precisa chamar outra funo, essa outra funo deve estar definida ou
declarada anteriormente.
Normalmente colocamos as declaraes em arquivos header (.h) e inclumos ela no nosso cdigo fonte.
Nesse caso no precisaramos nos preocupar com a ordem de definio e ordem das chamadas de
funes.
O tipo pode ser qualquer um. Se a funo no for retornar valores, podemos indicar com void.
Os parmetros podem ser declaraes completas ou pode ser somente o tipo. Se a funo no recebe
parmetros podemos deixar os parentes vazio () ou indicar com (void)
Um exemplo seria:
exemplo41.h
1./*
2. * nome: exemplo41.h
3. * descrio: declarao de funes
4. * data: 06/11/2012
5. */
6.void inc(int x);
7.void dec(int );
8.int sum(int x, int y);
9.int sub(int, int);
O tipo void quer dizer que a funo no tem retorno. O C11 define tambm _Noreturn para indicar uma
funo que no retorna valor. _Noreturn no foi implementado em todos os compiladores.
4.6.2 Definio
Os parmetros agora tem que estar completamente declarados com o nome e tipo. Esses parmetros
criam identificadores que esto no escopo de declarao de funo. Essas variveis somente so visveis
dentro da funo.
Um exemplo seria:
exemplo42.c
1./*
2. * nome: exemplo42.c
3. * descrio: declarao de funes
4. * data: 10/04/2013
5. */
6.void inc(int x)
7.{
8. x++;
9.}
10.void dec(int x)
11.{
12. x--;
13.}
14.int sum(int x, int y)
15.{
16. return x + y;
17.}
18.int sub(int x, int y)
19.{
20. return x y;
21.}
4.6.3 Utilizao
Exemplo43.c
1.#include <stdio.h>
2.#include exemplo41.h
3.// incluir o contedo do arquivo exemplo42.c aqui pode isar o
include
4.int main()
5.{
6. int x=1,y=3;
7. inc(x);
8. dec(y);
9. printf(x=%d, y=%d\n,x,y);
10. x=sum(x,y);
11. printf(x=%d, y=%d\n,x,y);
12. return 0;
13.}
Quais os valores de x e y depois de chamada as funes inc e dec? Foi alterado os valores de x e y?
Na chamada da funo o que passado o valor dela. Isso quer dizer se alteramos dentro da funo o
valor de uma varivel, estamos alterando o valor da varivel que est no escopo da funo e no a
varivel usada na chamada da funo. No C podemos usar ponteiros para poder criar funes que alteram
as variveis passadas.
4.7 Exerccios
1. Crie os arquivo lab03.h ( declaraes somente) e lab03.c ( definies e a funo main ) contendo:
a) Uma funo int parImpar ( int num ) que imprimi se num par o impar. A funo tambm
retorna 0 para par e 1 para impar. ( x % 2 = 0 par e x % 2 = 1 impar )
b) Uma funo somatorio ( int num ) usando o comando while para retornar o somatrio de num
( num(1) = 1, num(2)=2+1, num(3)=3+2+1. A funo retorna o somatrio e tambm imprime:
Somatorio de %x = %res
c) Uma funo fatorial usando o comando for ( fatorial de 1!=1, 2!=2*1, 3!=3*2*1). A funo
retorna o fatorial e tambm imprime:
%x! = %x
d) Uma funo saltoPara ( inicio, fim, salta, para ) que executa um loop for com inicio e fim, se o
contador for igual a salta executar o continue e se for para executar o break. Se no for salta ou
para imprima o contador.
f) Na funo main faa pelo menos uma chamada de funo para cada funo do laboratrio.
5 Aula 4
Todos os programas ou o mesmo o sistema operacional quando executado, ele e lido para a memria e
depois comea a execuo. Todos os objetos como funo, varivel e constantes esto na memria na
execuo e cada um deles tem um endereo nico, o endereo de memria. O tamanho desse endereo
de memria depende da arquitetura 32bits ou 64 bits.
Todas as variveis tem algum valor seja numrico ou caractere mas o ponteiro e uma varivel especial que
o contedo dela um endereo de memria. Como o C fortemente e estaticamente tipado, o ponteiro
tambm tem um tipo definido e tambm precisamos declarar antes de usar.
tipo *ponteiro;
Antes de usar esse ponteiro, precisamos inicializar ele. Podemos inicializar ele estaticamente apontando
para uma varivel existente ou alocar dinamicamente uma regio. Faremos agora estaticamente.
ponteiro = &variavel;
outro_ponteiro = ponteiro;
O C permite que o programador aloque memria dinamicamente. Mas quando o programador aloca
memria, ele tem que gerenciar todas as etapas: alocao, inicializao, manter acessvel esse endereo
de memria em pelo menos uma varivel, desalocar a memria, garantir que no seja utilizado essa
memria desalocada.
A funo malloc retorna um ponteiro do tamanho do parametro tamanho). Podemos utilizar o funo
sizeof ( tipo ) para especificar o tamanho correto.
tipo *ponteiro = malloc( sizeof(tipo) );
A funao realloc executado passando um ponteiro existente para alterar o tamanho dele. O novo
ponteiro diferente do antigo que desalocado. O realloc retorna o novo ponteiro.
ponteiro = realloc( ponteiro, sizeof(tipo) * quantidade );
A funo free desaloca a memria. Mesmo tendo chamado malloc, calloc ou realloc no mesmo ponteiro
somente vou ter um comando free.
free( ponteiro );
ponteiro=NULL;
Quando desalocamos um ponteiro recomendvel atribuir NULL para a varivel. Primeiro para que a
memria desalocada no se possa ser usada por esse ponteiro e segundo, assegurado que no seja
executado o free com esse endereo desalocado que gera um erro de execuo parando a execuo do
programa.
Exemplo45.c
1.#include <stdio.h>
2.#include <stdlib.h>
3.int main()
4.{
5. int *px,*py;
6. int x=1,y=3;
7.
8. px=malloc(sizeof(int));
9. py=malloc(sizeof(int));
10.
11. *px=10;
12. *py=30;
13. *px=*px+*py;
14.
15. printf("x=%d, y=%d\n", x, y);
16. printf("*px=%d, *py=%d\n", *px, *py);
17. printf("px=%p, py=%p\n", px, py);
18. printf("&x=%p, &y=%p\n", &x, &y);
19.
20. free(px);
21. free(py);
22.
23. printf("Depois de free()\n");
24. printf("px=%p, py=%p\n", px, py);
25. px=py=NULL;
26. printf("px=%p, py=%p\n", px, py);
27.
28. free(px);
29. free(py);
30.
31. return 0;
32.}
Ponteiros e array na linguagem C so tipos diferentes mas as operaes e utilizaes so iguais. O C trata
arrays como ponteiros tendo a primeira posio que o elemento vetor[0] e calcula a posio no ensimo
elemento multiplicando pelo tamanho de cada elemento. Temos que pvetor[0] igual a *pvetor.
Alias como o ponteiro em si escalar, podemos somar ponteiros. Se precisamos usar o elemento ndice 10
podemos usar vetor[9], pvelor[9] ou *(pvetor+9). O C na expresso *(pvetor+9) no soma 9 bytes ou bits e
sim 9 * o tamanho de cada elemento.
Exemplo46.c
1.#include <stdio.h>
2.#include <stdlib.h>
3.int main()
4.{
5. int *parray;
6. parray=(int*)calloc(10,sizeof(int));
7. int *outroarray=(int*)calloc(10,sizeof(int));
8.
9. parray[0]=1;
10. parray[9]=10;
11.
12. printf("%d %p\n", parray[0], &parray[0]);
13. printf("%d %p\n", parray[9], &parray[9]);
14. printf("%d %p\n", *(parray), parray);
15. printf("%d %p\n", *(parray+9), (parray+9));
16.
17. parray=realloc(parray,sizeof(int)*20);
18. parray[19]=100;
19.
20. printf("%d %p\n", parray[0], &parray[0]);
21. printf("%d %p\n", parray[19], &parray[19]);
22. printf("%d %p\n", *(parray+19), (parray+19));
23.
24. free(parray);parray=NULL;
25. free(outroarray);outroarray=NULL;
26.
27. return 0;
28.}
No C string e ponteiros para string so relacionados como array e ponteiros para array. A direrena que a
string tem um caractere especial \0 que diz aonde indica o final da string.
exemplo47.c
1./*
2. * nome: exemplo47.c
3. * descrio: Ponteiros para strings
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.#include <stdlib.h>
8.int main()
9.{
10. char *nome=(char*)malloc(sizeof(char)*20);
11. nome[0]='C';
12. nome[1]='a';
13. nome[2]='r';
14. nome[3]='l';
15. nome[4]='o';
16. nome[5]='s';
17. nome[6]='\0';
18. printf("Nome %s ( letra inicial %c )(%%p %p)\n", nome, nome[0],
nome);
19. free(nome); nome=NULL;
20. return 0;
21.}
Porque no printf quando passamos ponteiro para int usamos *ponteiro e agora para string usamos
apenas ponteiro?
5.1.5 Ponteiro para estruturas
Ponteiros para estrutura se comportaria como um ponteiro regular. Somente o aceso ao contedo dele
que foi simplificado. Para acessar um item seria (*ponteiro).item, mas podemos usar o operador -> como
ponteiro->item.
exemplo48.c
1./*
2. * nome: exemplo48.c
3. * descrio: Declarao de struct
4. * data: 10/04/2013
5. */
6.#include <stdio.h>
7.int main()
8.{
9. struct data
10. {
11. int dia,mes,ano;
12. } dia = {.dia=17, .mes=10, .ano=2012};
13.
14. struct data *pdia=&dia;
15.
16. printf("Data de hoje %d/%d/%d\n", pdia->dia, (*pdia).mes,
dia.ano);
17.
18. return 0;
19.}
Funes como todo identificador no C pode ser acessado usando ponteiros. Vamos explicar o conseito
bsico de ponteiros para funo para reforar como est organizado o gerenciamento de memria no C.
No C os parmetros so passados por valor na chamada da funo. Para conseguir alterar o valor de uma
varivel na funo podemos passa um ponteiro. Tambm usa-se ponteiros para passar dados grandes
como estruturas porque no ser preciso realizar a cpia dos dados na chamada.
Exemplo50.h
1./*
2. * nome: exemplo50.h
3. * descrio: ponteiros como parmetros de funo
4. * data: 06/11/2012
5. */
6.void inc(int *x)
7.{
8. (*x)++;
9.}
10.void dec(int *x)
11.{
12. (*x)--;
13.}
Exemplo50.c
1.#include<stdio.h>
2.#include "exemplo50.h"
3.
4.int main()
5.{
6. int x=1, y=3;
7. printf("x=%d e y=%d\n",x,y);
8. inc(&x);
9. dec(&y);
10. printf("x=%d e y=%d\n",x,y);
11. return 0;
12.}
No exemplo anterior o incremento e decremento feito no formato (*x)++ e (*x--) porque no poderia ser
feito como *x++ e *x--?
A durao de armazenamento de um objeto est relacionado ao escopo dele e como e quando o objeto
vlido e pode ser acessado. Se desararmos uma varivel global, ela ficar disponvel durante a execuo
do programa e ser visvel em todo o programa. Se declarar uma varivel em um bloco, a durao e
visibilidade dele ficar restrita ao bloclo.
Quando declaramos um objeto como uma varivel ou uma funo podemos tambm especificar a classe
de armazenamento dela que pode ser extern, static e register.
5.3.1 Extern
Classifica os objetos com armazenamento externo. Se for uma varivel, ela far referencia a uma outra
varivel declarada em um arquivo header ou em outro programa. Se for uma funo, como toda as
funes j tem o escopo extern, isso seria redundante.
exemplo51.c
1./*
2. * nome: exemplo51.c
3. * descrio:
4. * data: 06/11/2012
5. */
6.int variavel=21;
exemplo52.c
1./*
2. * nome: exemplo52.c
3. * descrio:
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.
8.extern int variavel;
9.int main(){
10. printf("variavel externa=%d\n",variavel);
11. return 0;
12.}
Para compilar:
#icc -Wall -c exemplo51.c
#icc -Wall -c exemplo52.c
#icc -Wall exemplo51.o exemplo52.o -o exemplo51e52
#./exemplo51e52
5.3.2 Static
No escopo de funo a varivel inicializada somente uma vez e esse armazenamento dura toda a
execuo do programa mesmo que o escopo dela esteja limitado. O valor dela tambm conservado.
exemplo53.c
1./*
2. * nome: exemplo53.c
3. * descrio:
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.
8.int conta()
9.{
10. static int var=1;
11. return var++;
12.}
13.
14.int main()
15.{
16. printf("Conta=%d\n",conta());
17. printf("Conta=%d\n",conta());
18. printf("Conta=%d\n",conta());
19. return 0;
20.}
No escopo global, essa varivel ficaria como escopo interno e no poderia declarar uma outra varivel
como extern.
arquivo1.c
static int var=13;
arquivo2.c
extern int var; //isso no funcionaria
5.3.3 Const
O qualificador const especifica que o objeto no poder ser alterado depois da declarao.
const int var=10;
vara=20; //erro
Quando trabalhamos com ponteiros, podemos ter ponteiros para contantes , ponteiros contantes para
varivel e ponteiros constantes para contantes.
//ponteiro para constante
const int *ptr_to_constant=&var;
*ptr_to_constant=100; //erro
ptr_to_constant=&outrovar; //OK
Register qualifica uma varivel a ser otimizada o acesso a ela usando registradores da prpria CPU
evitando o acesso memria RAM. O compilador pode ignorar isso se no puder realizar essa otimizao.
Restrict um qualificador de ponteiros que diz para o compilador que o programador no usar outro
ponteiro como acesso alternativo para essa varivel. Com essa restrio o compilador pode otimizar o
cdigo.
5.4 Exerccios
a) Variveis:
int num=10;
int data[3]={19,4,2013};
char hello=Hello;
num=%d \n
data=%d \n
hello=%s \n
a) Defina
struct ponto
num=%d \n
data=%d \n
hello=%s \n
3. Crie o lab04s.c com uma funo acumulador( init num ). Use uma varivel static. A funo imprime
acumulou %d\n.
4. Crie:
b) lab04e.c com include de lab04e.h e o corpo da funo acumulador( init num ){}
c) lab04i.c com include de lab04e.h. Na funo main realize chamadas para acumulador
A biblioteca padro C ou C standard library a biblioteca padro definido pela ISO para que todo
compilador C deve fornecer.
A biblioteca padro C fornece macros, definio de tipos e funes para lidar com strings, computao
matemtica, processamento de entrada/sada, alocao de memria e muitas outras funes para os
servios do sistema operacional.
J vimos o comando printf e a parte de alocao de memria, agora iremos ver sobre processamento de
entrada e sada.
O C abstrai todas as rotinas de entrada e sada com arquivos. Quando usamos o printf, o comando envia
informao para um arquivo que o C define como stdout ou seja sada padro. Existem outros como
stderr para sada de erro e stdin para entrada padro (teclado).
6.2.1 Arquivos
O C define o tipo FILE para tratar arquivos. Para trabalhar com arquivos precisamos, declarar uma varivel
FILE, abrir o arquivo, escrever ou ler, fechar o arquivo.
A biblioteca padro C define entrada e sada formatada, caractere e direta. Iremos usar as rotinas de
entrada e sada formatada no curso por ser considerada mais didtica.
A bliblioteca padro C define vrias funes para tratar sada formatada, iremos tratar da printf e da
fprintf.
O arquivo pode ser um que declaramos e abrimos anteriormente ou pode ser um que o C define como :
stdout ou stderr.
A biblioteca padro C define vrias funes para tratar entrada formatada, iremos tratar da scanf e da
fscanf.
Quando lidamos com entrada e sada pode ocorrer erros seja de acesso, permisso ou nome de arquivo
ou no formato do dado. Para esses problemas, o programador precisa tratar isso no cdigo fonte.
6.2.3.1 Funes teis para o tratamento de erro
feof retorna verdadeiro para final de arquivo, caso contrrio retorna falso.
ferror retorna zero quando no h erro, caso retorne um nmero, esse nmero o cdigo do erro.
fscanf(fp,"%s",&var);
if( errno ) perror("Erro com a funcao fscanf");
exemplo56.c
1./*
2. * nome: exemplo55.c
3. * descrio:
4. * data: 03/10/2012
5. */
6.#include <stdio.h>
7.#include <stdlib.h>
8.#include <errno.h>
9.
10.int main(int argc, char *argv[])
11.{
12. for( int cont=0 ; cont<argc ; cont++)
13. printf("argv[%d]=\"%s\"\n", cont, argv[cont]);
14. return 0;
15.}
Para executar:
./exemplo56
./exemplo56 par1 par2 1 2 3
b) O lab05r.c faa um loop while lendo do arquivo os nmeros, teste fim de arquivo.
2. Crie o arquivo lab05wp.c que abre o arquivo que recebe como parmetro na linha de comando e
acrescente no final do arquivo lab05.txt. Converter os parmetros para inteiro antes de gravar.
3. A biblioteca C padro fornece muitas funes interessantes que no poderia abordar aqui no
curso mas se olhar na documentao dessas funes, poder com facilidade utilizar ela em algum
programa. No Linux padro essas funes so documentadas com o man.
man pow
man sqrt
b) Escolha uma das funes e escreva o programa lab05rf.c como cpia do lab05r.c e a cada
nmero lido imprima pow(%d) = %f ou sqrt(%d)=%f.
c) De acordo com a documentao, precisa colocar um header a mais e uma linha a mais na
compilao (link).
7 Material Extra
Esse curso teve como referencia o padro como um curso introdutrio. O
padrao C11 apresenta outros recursos como threads, usso de estruturas
genricas, entre outros.
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
https://www.securecoding.cert.org/confluence/display/seccode/CERT+C+Secu
re+Coding+Standard
Duvidas frequentes:
http://c-faq.com/