XXIV Curso de Especialização em Teleinformática e Redes de Computadores
www.teleinfo.ct.utfpr.edu.br
Prof. Gustavo B. Borba/Prof. Humberto R. Gamba
TEL45 - Linguagem C e MATLAB
C parte 2
Abr.2014
2
Estrutura de um programa C ◦ #include<>, main(), declaração de variáveis
Tipos de dados ◦ char (1B), int (4B), short (2B), long (4B), float
(4B), double (8B), qualificador unsigned
Operadores ◦ Atribuição = ◦ Aritméticos +, -, /, *, % ◦ Aritméticos de atribuição +=, -=, *=, /=, ++, -- ◦ Relacionais ==, !=, <, >, <=, >= ◦ Lógicos &&, ||, ! ◦ Ternário epx?expT:expF ◦ Bitwise &, |, ^, ~, >>, <<
3
printf( ), scanf( ), sizeof( )
Chamada de função, formatos de impressão, leitura formatada, operador &
if
while
IDE
Funções ◦ Protótipo, declaração, parâmetros de
entrada e saída, return.
4
controle de fluxo = tomada de decisão
loop = repetição
Usados junto de expressões relacionais (comparações).
Exemplos do uso de operadores relacionais:
Stephen Prata, C Primer Plus, 5th Ed.
while (num < 6)
{
printf(“O numero é baixo.\n”);
scanf(“%d”, &num);
}
while (ch != ‘s’)
{
count++;
scanf(“%c”, &ch);
}
1. 2.
5 Stephen Prata, C Primer Plus, 5th Ed.
#include <stdio.h>
#include <conio.h>
int main(void)
{
int true_val, false_val;
true_val = (10 > 2); /* value of a true relationship */
false_val = (10 == 2); /* value of a false relationship */
printf("true = %d; false = %d \n", true_val, false_val);
return 0;
}
true = 1; false = 0
Imprime:
6
#include <stdio.h>
#include <conio.h>
int main(void)
{
int n = 3;
while (n)
printf("%2d is true\n", n--);
printf("%2d is false\n", n);
n = -3;
while (n)
printf("%2d is true\n", n++);
printf("%2d is false\n", n);
return 0;
}
Stephen Prata, C Primer Plus, 5th Ed.
7
#include <stdio.h>
#include <conio.h>
int main(void)
{
int n = 3;
while (n)
printf("%2d is true\n", n--);
printf("%2d is false\n", n);
n = -3;
while (n)
printf("%2d is true\n", n++);
printf("%2d is false\n", n);
return 0;
}
Stephen Prata, C Primer Plus, 5th Ed.
3 is true
2 is true
1 is true
0 is false
-3 is true
-2 is true
-1 is true
0 is false
Imprime:
Em C: • Diferente de 0 é considerado true. • Apenas o 0 é reconhecido como falso.
Pós-decremento: primeiro utiliza o valor e depois faz o decremento.
8 Stephen Prata, C Primer Plus, 5th Ed.
Forma 1 if(expressão){
instrução
}
A instrução é executada se a expressão for verdadeira
Forma 2 if(expressão){
instrução1
}
else{
instrução2
}
Se expressão for verdadeira, a instrução1 é executada. Caso contrário, a instrução2 é executada.
Forma 3 if(expressão1){
instrução1
}
else if (expressão2){
instrução2
}
else{
instrução3
}
Se expressão for verdadeira, a instrução1 é executada. Se a expressão1 for falsa mas a expressão2 for verdadeira, a instrução2 e é executada. Caso contrário, se ambas expressões forem falsas, a instrução3 é executada.
if
9 Stephen Prata, C Primer Plus, 5th Ed.
while(expressão){
instrução
}
A instrução é executada enquato expressão for verdadeira
OBS. while é um entry-condition loop: a decisão de entrar no loop é feita antes da entrada. Então, há a possibilidade do loop nunca ser executado.
while
Estrutura
Um ciclo é chamado de iteração
10 Stephen Prata, C Primer Plus, 5th Ed.
A decisão de sair ou continuar no loop só acontece quando a condição é avaliada.
Prog03 Saída do loop
#include <stdio.h>
#include <conio.h>
int main(void)
{
int n = 5;
while (n < 7)
{
printf(“n = %d\n”, n);
n++;
printf(“Agora n = %d\n”, n);
}
printf(“Saiu do loop.\n”);
return 0;
}
11 Stephen Prata, C Primer Plus, 5th Ed.
A decisão de sair ou continuar no loop só acontece quando a condição é avaliada.
Prog03 Saída do loop
#include <stdio.h>
#include <conio.h>
int main(void)
{
int n = 5;
while (n < 7)
{
printf(“n = %d\n”, n);
n++;
printf(“Agora n = %d\n”, n);
}
printf(“Saiu do loop.\n”);
return 0;
}
n = 5
Agora n = 6
n = 6
Agora n = 7
Saiu do loop.
Imprime:
Não imprimiu n = 7
porque avaliou a
condição, o
resultado foi falso
então saiu do loop.
12 Stephen Prata, C Primer Plus, 5th Ed.
for (inicialização ; teste ; atualização){
instrução
}
1. A inicialização é feita apenas uma vez, na entrada do loop. 2. A condição teste é avaliada a cada potencial iteração. Quando a condição for falsa o loop é terminado. 3. A atualização é executada ao final de cada iteração.
OBS. for é um entry-condition loop.
for
for(count=1; count<=number; count++)
printf(“Be my Valentine!\n”);
1.
2. 3.
Estrutura
13 Stephen Prata, C Primer Plus, 5th Ed.
#include <stdio.h>
#include <conio.h>
int main(void)
{
int num;
printf(" n n^2\n");
for (num = 1; num <= 6; num++)
printf("%5d %5d\n", num, num*num);
printf(“\n Ao sair num=%d", num);
return 0;
}
n n^2
1 1
2 4
3 9
4 16
5 25
6 36
Ao sair num=7
Imprime:
for
Exemplo
14 Stephen Prata, C Primer Plus, 5th Ed.
1. Decrementar ao invés de incrementar
for Variações
for (cont = 5; cont > 0; cont--)
2. Contar em outras quantidades ao invés de 1 em 1
for (cont = 0; cont <= 100; cont += 10)
3. Testar outra condição ao invés do número de iterações
for (num = 1; num*num <= 36; num++)
Faz o mesmo que o exemplo do slide anterior.
15 Stephen Prata, C Primer Plus, 5th Ed.
4. Omitir parâmetros. Os ; são obrigatórios. Ex: Soma os inteiros de 1 a 10:
for Variações
i=1;
soma = 0;
for ( ; i <= 10 ; i++)
soma += i;
5. O primeiro parâmetro não precisa ser um inicialização. Ex: Só sai do loop quando o usuário entra o número 6:
int n = 0;
for (printf(“Vai digitando numeros!\n”) ; n != 6 ; )
scanf(“%d”, &n);
i=1;
soma = 0;
for ( ; i <= 10 ; )
{
soma += i;
i++;
}
16 Stephen Prata, C Primer Plus, 5th Ed.
do{
instrução
}while(expressão);
OBS. do while é um exit-condition loop. A condição é testada após a iteração do loop. O loop sempre é executado pelo menos uma vez.
do while
Estrutura
A instrução é executada enquanto expressão for verdadeira
17 Stephen Prata, C Primer Plus, 5th Ed.
do while
#include <stdio.h>
#include <conio.h>
int main(void)
{
int senha = 13;
int senhaIn;
do
{
printf("Entre a senha: ");
scanf("%d", &senhaIn);
} while (senha != senhaIn);
printf("Senha confere.\n");
return 0;
}
Exemplo
Permanece no loop lendo a entrada e só sai quando o usuário digita 13.
18 Stephen Prata, C Primer Plus, 5th Ed.
switch
switch (inteiroOUchar)
{
case inteiroOUchar_1: //constante
instrução
break //pula para o fim
case inteiroOUchar_2: //constante
instrução
break //pula para o fim
case inteiroOUchar_3: //constante
instrução
break //pula para o fim
default:
instrução
} //fim
Usado para múltipla escolha.
Vai para o case correspondente ao conteúdo do switch.
19
switch
#include <stdio.h>
#include <conio.h>
int main(void)
{
float a, b;
char op;
printf("Entre a operacao: ");
scanf("%c", &op);
printf("Entre o numero a: ");
scanf("%f", &a);
printf("Entre o numero b: ");
scanf("%f", &b);
Exemplo switch(op)
{
case 'a':
printf("a+b = %f\n", a+b);
break;
case 's':
printf("a-b = %f\n", a-b);
break;
case 'm':
printf("a*b = %f\n", a*b);
break;
case 'd':
printf("a/b = %f\n", a/b);
break;
default:
printf(“Op. invalida");
}
return 0;
}
20
switch Facilita a implementação de múltipla escolha. Mas não elimina a necessidade do if-if else-if pois o switch não avalia:
Float Não é permitido, por exemplo: float a;
switch(a)
{...
Expressão Não é permitido, por exemplo: int a;
switch(a)
{
case a>10:
...
21
Prog04 Loops aninhados
#include <stdio.h>
#include <conio.h>
int main(void)
{
int cont=0, i, j, k, n=7;
for (i=0; i<=n; i++)
for (j=0; j<=n; j++)
for (k=0; k<=n; k++)
if ( (i+j+k) == n )
{
cont++;
printf("%d %d %d\n", i, j, k);
}
printf("cont = %d", cont);
return 0;
}
Imprime todas possibiliades do resultado da soma de 3 inteiros entre 1 e 7 ser igual a 7.
Os loops são resolvidos a partir do mais interno.
IDE Run to cursor: F4 Next line: F7 Add Watch: Debug Edit watches Add
22 Stephen Prata, C Primer Plus, 5th Ed.
break e continue Normalmente, após entrar em um loop, todas as instruções do corpo do loop são executadas antes do próximo teste ser feito.
A instrução break permite sair do loop:
A instrução continue permite pular parte do loop:
23
Prog05 break #include <stdio.h>
#include <conio.h>
int main(void)
{
int count, loop=0;
for(int t=0; t<100; t++)
{
count = 1;
for(;;)
{
printf("%d", count);
count++;
if(count==10)
break;
}
loop++;
}
printf(" %d", loop);
return 0;
}
O que será impresso?
Em loops aninhados, sai apenas do loop mais interno.
24
Prog05 break #include <stdio.h>
#include <conio.h>
int main(void)
{
int count, loop=0;
for(int t=0; t<100; t++)
{
count = 1;
for(;;)
{
printf("%d", count);
count++;
if(count==10)
break;
}
loop++;
}
printf(" %d", loop);
return 0;
}
123456789123456789123456
789123456789123…12345678
9123456789 100
Imprime ‘123456789’ 100 vezes :
25
Prog06 continue
#include <stdio.h>
#include <conio.h>
int main(void)
{
for(int x=0; x<100; x++)
{
if(x%2)
continue;
printf("%d ", x);
}
return 0;
}
O que será impresso?
Interrompe o loop e devolve o controle
para o for.
26
Prog06 continue
#include <stdio.h>
#include <conio.h>
int main(void)
{
for(int x=0; x<100; x++)
{
if(x%2)
continue;
printf("%d ", x);
}
return 0;
}
0 2 4 6 8 … 98
Imprime os números pares entre 0 e 99:
27
Um ponteiro é um tipo de variável que armazena endereço de memória.
p
Como o conteúdo de uma variável ponteiro é um endereço de memória e esse endereço de memória contém o valor de uma outra variável qualquer, pode-se fazer a analogia com uma seta direcionada ao endereço da variável. Graficamente, pode-se imaginar um ponteiro da seguinte forma:
5 Endereço qualquer de memória.
int i=5, *p;
variável do tipo int
variável do tipo ponteiro para int
i
28
Permite referenciar um ponteiro a uma variável, isto é, fazer um ponteiro apontar para uma variável. Este procedimento também é chamado de inicialização do ponteiro.
b
?
Endereços de memória
p = &a;
a
?
Operador & (reference)
p
? int a, b, *p;
330 334 400
a = b = 7;
b
7
a
7
p
?
330 334 400
b
7
a
7
p
330
330 334 400
29
Após inicializar o ponteiro - fazer o ponteiro apontar para uma variável - pode-se agora usar o ponteiro para acessar o conteúdo desta variável.
Isto é feito através do operador *
p = &a;
Operador * (dereference)
int a, b, *p;
a = b = 7;
printf(“*p = %d”, *p); Imprime *p = 7
O valor direto de p é uma posição de memória.
O valor de *p é o conteúdo do endereço de memória apontado por p.
Portanto:
30
Não acessar o conteúdo de um ponteiro
que ainda não foi inicializado.
Atenção
int *pt; //um ponteiro não inicializado
*pt = 5; //isso não se faz!
Stephen Prata, C Primer Plus, 5th Ed.
31
Prog07 Ponteiros #include <stdio.h>
#include <conio.h>
int main(void)
{
int a=3, b=7, *p1=&b;
int n=5, x, y, *p2;
int z, *p3=&z;
printf("b = %d\n", b);
*p1 = 2 * *p1 - a;
printf("b = %d\n", b);
p2 = &n;
x = *p2;
printf("x = %d\n", x);
y = *&n;
printf("y = %d\n", y);
printf("entre um inteiro: ");
scanf("%d", p3);
printf("vc digitou %d", z);
return 0;
}
b = imprime
x = imprime
y = imprime
32
Um array é um conjunto de dados do mesmo tipo.
Um array de uma dimensão é um vetor.
tipo nome[tamanho]; //declaração de um vetor
Exemplo
int pots[8];
Os colchetes [] caracterizam pots como um vetor.
pots é um vetor de 8 elementos do tipo int.
O acesso a cada elemento do vetor é feito através do índice i da seguinte forma: pots[i]
O primeiro elemento é pots[0] e o último é pots[7]
33
Inicialização de um array
float x[7] = {-1.1,0.2,33.0,4.4,5.05,0.0,7.7};
x[0] = -1.1
x[1] = 0.2
x[2] = 33.0
x[3] = 4.4
x[4] = 5.05
x[5] = 0.0
x[6] = 7.7
seqüência de valores separados por vírgula. Resulta em:
É possível omitir o número de elementos. O compilador utiliza o número de elementos do inicializador:
float x[] = {-1.1,0.2,33.0,4.4,5.05,0.0,7.7};
34
Prog08 Array
#include <stdio.h>
#include <conio.h>
#define MESES 12
int main(void)
{
int dias[MESES] = {31,28,31,30,31,30,31,31,30,31,30,31};
int i;
for (i = 0; i < MESES; i++)
printf("Mes %2d tem %d dias.\n", i+1, dias[i]);
return 0;
}
Testando...
Porque o primeiro índice do array é 0
35
Prog09 Array
#include <stdio.h>
#include <conio.h>
#define MESES 12
int main(void)
{
int dias[MESES] = {31,28,31,30,31,30,31,31,30,31,30,31};
int i;
for (i = 0; i <= MESES; i++)
printf("Mes %2d tem %d dias.\n", i+1, dias[i]);
return 0;
}
Testando...
O compilador não verifica o limite do array.
36
Um ponteiro é uma variável que recebe endereços como valores.
int a=20,*p; ?
p
20
a
100
100
p
20
a
100
p = &a;
printf(“%d %d”, *p, a); Imprime 20 20
37
Um array é um endereço fixo e pode ser considerado como ponteiro para um endereço fixo.
7 11 16 8 23
1000
0 1 3 4 2
int a[5];
a
No caso de um vetor: o conteúdo 1000 do ponteiro do vetor a não pode ser alterado pelo programador.
38
Ao declarar: tipo nomeArray[tam]
1. O compilador calcula o número de bytes necessário para armazenar este array:
tam x sizeof(tipo);
2. O compilador reserva esse espaço de memória. 3. O compilador cria um ponteiro com o nome nomeArray e direciona-o para o primeiro elemento do array. Logo as seguintes notações são equivalentes:
nomeArray[i] *(nomeArray + i)
39
5
….
…
1000
1004
1008
1012
1016
1020
1024
1028
1000
xxxx
int a[tam]
tam x sifeof(int)
a[2] = 5
*(a+2) = 5
Internamente: *(1000 + 2 x sizeof(int)) = 5
Obs: O compilador sabe que deve avançar 4 bytes pois a variável foi declarada como do tipo int
a[0]
a[1]
a[2]
a[tam-1]
a
40
Aritmética de ponteiros
p = a + 1; p = &a[1]; p = a + 2; p = &a[2];
300
304
308
300
304
308
p = a; p = &a[0];
300
304
308
a[] p a[] p a[] p
Após a instrução p=a; (ou p=&a[0];) pode-se acessar todos os elementos do vetor a através do ponteiro p;
41
Prog10 Aritmética de ponteiros
#include <stdio.h>
#include <conio.h>
#define N 4
int main(void)
{
int a[N] = {1,2,3,4}, *p;
int soma = 0;
for (p=a; p < &a[N]; p++)
soma += *p;
printf("soma = %d", soma);
return 0;
}
p = a; assinala a p o endereço base do array, ou seja, o endereço de a[0];
p++; os incrementos sucessivos de p são equivalentes a &a[0],&a[1],...,&a[N-1]
42
Prog11 Ponteiros
#include <stdio.h>
#include <conio.h>
int main(void)
{
int y, *p, x;
y = 0;
p = &y;
x = *p;
x = 4;
(*p)++;
x--;
(*p)+=x;
printf("y = %d", y);
return 0;
}
Qual o valor de y ao final do programa?
43
Uma string é uma seqüência de caracteres que
termina com o caractere nulo (‘\0’).
char s[] = “abc”;
char s[] = { ‘a’ , ‘b’ , ‘c’ , ‘\0’ } ;
a b c \0
s
44
Para ler uma string do teclado pode-se usar a função gets() definida na biblioteca stdio.h. gets() lê caracteres até encontrar um <enter>.
45
O caractere nulo (‘\0’) é interpretado como o final da string.
46
Prog12 Determina quantidade de letras maiúsculas
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i=0, cont=0;
char str[256], c;
printf("Digite uma string: ");
gets(str);
c = str[i];
while(c != '\0')
{
if((c >= 65) && (c <= 90))
cont++;
i++;
c = str[i];
}
printf("A string possui %d letras maiusculas\n", cont);
return 0;
}
Caractere : ‘0’ ‘1’ ‘2’ ... ‘9’
Valor ASCII: 48 49 50 ... 57
Caractere : ‘A’ ‘B’ ‘C’ ... ‘Z’
Valor ASCII: 65 66 67 ... 90
Caractere : ‘a’ ‘b’ ‘c’ ... ‘z’
Valor ASCII: 97 98 99 ... 122
47
Um array não é passado para uma função por valor, mas sim por referência, também denominada passagem por ponteiro. ◦ C faz isso para privilegiar a eficiência. Não é
necessário alocar memória e copiar o array.
◦ A função trabalha com o array ‘original’: não se garante a integridade dos dados.
◦ Para garantir a integridade (proteger o array) há a palavra-chave const.
Stephen Prata, C Primer Plus, 5th Ed.
48 Stephen Prata, C Primer Plus, 5th Ed.
#include <stdio.h>
#include <conio.h>
float soma(float *, int); //protótipo
int main(void)
{
float prec[] = {10.5, 3.1, 50.3};
float s;
s = soma(prec, 3); //chamada
printf("%.2f\n", s);
return 0;
}
//definição
float soma(float *vec, int n)
{
int i;
float sum=0;
for(i=0; i<n; i++)
sum += vec[i];
return sum;
}
tamanho
Funções, arrays e
ponteiros
49
Funções, arrays e
ponteiros
Na declaração dos parâmetros formais é possível usar as seguintes formas:
float soma(float *vec, int n);
float soma(float *, int n);
float soma(float vec[], int n);
float soma(float [], int n);
Protótipo
float soma(float *vec, int n)
{
...
}
float soma(float vec[], int n)
{
...
}
Definição
Na definição não é possível omitir os nomes dos parâmetros.
Stephen Prata, C Primer Plus, 5th Ed.
50
#include <stdio.h>
#include <conio.h>
void somaUm(float [], int); //protótipo
int main(void)
{
float prec[3] = {10.5, 3.1, 50.3};
int i, tam=3;
somaUm(prec, tam); //chamada
for(i=0; i<tam; i++)
printf(“%.2f ”, prec[i]);
return 0;
}
//definição
void somaUm(float vec[], int n)
{
for(int i=0; i<n; i++)
vec[i]++;
}
Funções, arrays e
ponteiros
Já que a função trabalha com o array ‘original’, é possível alterar o seu conteúdo.
51
#include <stdio.h>
#include <conio.h>
//protótipo
float soma(const float v[], int t);
int main(void)
{
float prec[] = {10.5, 3.1, 50.3};
float s;
s = soma(prec, 3); //chamada
printf("%.2f\n", s);
return 0;
}
//definição
float soma(const float vec[], int n)
{
int i;
float sum=0;
for(i=0; i<n; i++)
sum += vec[i];
return sum;
}
Funções, arrays e
ponteiros
O compilador apresenta uma mensagem de erro caso exista a tentativa de mudar o conteúdo do array. Por exemplo: vec[i]++
52
Um ponteiro para constante pode receber o endereço de uma variável constante ou não constante. Por exemplo:
Stephen Prata, C Primer Plus, 5th Ed.
Um ponteiro normal só pode receber o endereço de uma variável não constante. Por exemplo:
double rates[4] = {88.9, 100.12, 59.45, 340.5};
const double locked[3] = {0.08, 0.075, 0.07};
const double *pc = rates; //válido
pc = locked; //válido
pc = &rates[2]; //válido
double rates[4] = {88.9, 100.12, 59.45, 340.5};
const double locked[3] = {0.08, 0.075, 0.07};
double *pnc = rates; //válido
pnc = locked; //não válido
pnc = &rates[2]; //válido
Funções, arrays e
ponteiros
53
Exemplo:
◦ O objetivo é armazenar o volume chuva
de cada mês, para 5 anos.
◦ As possibilidades são:
60 variáveis, uma para cada mês – não faz sentido!
Um array de 60 elementos – tudo bem, mas seria melhor poder saparar cada ano.
5 arrays de 12 elementos – inadequado, especialmente se houver a necessidade de armazenar 50 anos, p.ex.
Stephen Prata, C Primer Plus, 5th Ed.
54
SOLUÇÃO: um array de arrays ◦ ‘Array principal’: 5 elementos, um para cada ano. ◦ Cada um desses 5 elementos: um array de 12
elementos, um para cada mês.
Stephen Prata, C Primer Plus, 5th Ed.
float rain[5][12]; //array de 5 arrays de 12 floats
//matriz
55
Esta declaração pode ser vista da seguinte forma:
Stephen Prata, C Primer Plus, 5th Ed.
float rain[5][12];
rain é um array de 5 elementos
float rain[5][12];
Cada um desses 5 elementos é um array de 12 floats
56
Então:
◦ rain[0], o primeiro elemento de rain, é um array de 12 valores float (assim como rain[1], rain[2], ...).
◦ Se rain[0] é um array, seu primeiro elemento é rain[0][0], o segundo elemento é rain[0][1] e assim por diante.
Stephen Prata, C Primer Plus, 5th Ed.
float rain[5][12]; //rain é um array de 5 elementos
float rain[5][12]; //cada elemento é um array de 12 floats
57 Stephen Prata, C Primer Plus, 5th Ed.
58 Stephen Prata, C Primer Plus, 5th Ed.
Fazer um programa para calcular e mostrar na tela: ◦ O volume de chuva total de cada ano. ◦ O volume de chuva total de cada mês.
Apenas função main(), i.e, não criar funções.
A inicialização de rain é dada:
const float rain[YEARS][MONTHS] = {
{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
{8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
{9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
{7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
{7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
};
59 Stephen Prata, C Primer Plus, 5th Ed.
#include <conio.h>
#define YEARS 5
#define MONTHS 12
int main(void)
{
const float rain[YEARS][MONTHS] = matriz rain aqui
float totalano, totalmes;
int i, j;
//para cada linha, varre todas as colunas
for(i=0; i < YEARS; i++) //varre as linhas
{
totalano = 0;
for(j=0; j < MONTHS; j++) //varre as colunas
totalano += rain[i][j];
printf("Total ano %d = %.2f\n", i+1, totalano);
}
//para cada coluna, varre todas as linhas
for(j=0; j < MONTHS; j++) //varre as colunas
{
totalmes = 0;
for(i=0; i < YEARS; i++) //varre as linhas
totalmes += rain[i][j];
printf("Total mes %d = %.2f\n", j+1, totalmes);
}
return 0;
}
Prog15 array 2d
60 Stephen Prata, C Primer Plus, 5th Ed.
int z[4][2] = { {2,4}, {6,8}, {1,3}, {5,7} };
2 4
6 8
1 3
5 7
z é o endereço do array 2d z[0] é o endereço do primeiro array 1d *z é o endereço do primeiro array 1d
z,z[0],*z contém o mesmo endereço, que é o endereço do primeiro elemento: &z[0][0]
Apesar disso, há uma diferença:
z + 1 anda 2 ints (comprimento do array 1d) z[0] + 1 anda 1 int *z + 1 anda 1 int
Para acessar o conteúdo do array 2d:
z[0][0] é o conteúdo de Z00
*z[0] é o conteúdo de Z00
**z é o conteúdo de Z00
z[2][1] é o conteúdo de Z21
*(z[2] + 1) é o conteúdo de Z21
*(*(z+2) + 1) é o conteúdo de Z21
61 Stephen Prata, C Primer Plus, 5th Ed.
#include <stdio.h>
#include <conio.h>
int main(void)
{
int z[4][2] = { {2,4}, {6,8}, {1,3}, {5, 7} };
printf(" z = %p, z + 1 = %p\n", z, z+1);
printf("z[0] = %p, z[0] + 1 = %p\n", z[0], z[0]+1);
printf(" *z = %p, (*z)+1 = %p\n", *z, (*z)+1);
printf("z[0][0] = %d\n", z[0][0]);
printf(" *z[0] = %d\n", *z[0]);
printf(" **z = %d\n", **z);
printf(" z[2][1] = %d\n", z[2][1]);
printf(" *(z[2] + 1) = %d\n", *(z[2] + 1));
printf("*(*(z+2) + 1) = %d\n", *(*(z+2) + 1));
printf("*z[0] + 5 = %d\n", *z[0] + 5);
return 0;
}
2 4
6 8
1 3
5 7
62 Stephen Prata, C Primer Plus, 5th Ed.
As regras de escopo de uma linguagem determinam se um trecho do código tem ou não acesso a um outro trecho de código.
Existem três lugares onde as variáveis podem ser declaradas:
1) Fora de todas as funções existentes no programa: ◦ São chamadas GLOBAIS já que podem ser utilizadas por qualquer
função.
2) No início de um { bloco }: ◦ São chamadas de LOCAIS já que só existem para esse bloco.
3) Na lista de ( parâmetros formais ) de uma função: ◦ Estas variáveis são conhecidas apenas pela função onde são
declaradas.
63 Stephen Prata, C Primer Plus, 5th Ed.
Varíaveis dentro de um {bloco} ◦ São locais ◦ Só podem ser referenciadas pelos comandos que estão
dentro do bloco na qual estão declaradas.
Variávies globais ◦ São declaradas fora de qualquer função e qualquer
expressão contida em qualquer função pode acessá-las.
Fazer um programa simples para testas as variáveis em um bloco e as globais.
#include <conio.h>
void somaUm(void); //protótipo
int G = 12; //variável global
int main(void)
{
int z = 1;
printf("G antes de chamar somaUm() = %d\n", G);
printf("z da main() = %d\n", z);
{
int z = 2;
printf("z do bloco {} = %d\n", z);
}
somaUm();
printf("G depois de chamar somaUm() = %d\n", G);
return 0;
}
//definição
void somaUm(void)
{
G++;
}
65
Exemplo: cálculo do fatorial
#include <stdio.h>
#include <conio.h>
int fat(int); //protótipo
int main(void)
{
int num;
printf("Digite um inteiro: ");
scanf("%d", &num);
printf("\n%d! = %d", num, fat(num));
return 0;
}
int fat(int n) //definição
{
int resposta;
if (n==0) return 1;
resposta = fat(n-1)*n;
return resposta;
}
66
67
Uma estrutura é uma coleção de variáveis referenciadas por um nome. É uma maneira conveniente de agrupar dados relacionados.
Para definir (template) uma estrutura e para alocar uma estrutura: palavra-chave struct.
Herbert Schildt, C Completo e Total, 3a Ed.
68
struct addr { char name[30]; char street[40]; char city[20]; char state[3]; unsigned long int zip; }; struct addr addr_info;
Estruturas
Herbert Schildt, C Completo e Total, 3a Ed.
Outras possibilidades
struct { char name[30]; char street[40]; char city[20]; char state[3]; unsigned long int zip; } addr_info;
Define a estrutura
Aloca na memória uma variável tipo addr com o nome addr_info
Quando for usar apenas uma variável struct (addr_info)
struct addr { char name[30]; char street[40]; char city[20]; char state[3]; unsigned long int zip; } addr_info,binfo,cinfo;
Define e aloca três variáveis do tipo addr:
addr_info, binfo, cinfo
69
Estruturas
#include <stdio.h>
#include <conio.h>
struct addr //define um tipo de estrutura
{
char name[30];
char state[3];
unsigned long int zip;
};
int main(void)
{
struct addr addr_info; //aloca
printf("Entre o nome.\n");
gets(addr_info.name);
printf("Entre o estado.\n");
gets(addr_info.state);
printf("Entre o cep sem traço.\n");
scanf("%u", &addr_info.zip ); printf("Nome: %s\n", addr_info.name);
printf("Estado: %s\n",addr_info.state);
printf("CEP: %u\n", addr_info.zip);
return 0;
}
Para acessar os campos de uma struct: operador ponto
addr_info.name addr_info.state addr_info.zip
Herbert Schildt, C Completo e Total, 3a Ed.
70
Estruturas
A definição da estrutura é global, para que todas as partes do programa possam usá-la.
Herbert Schildt, C Completo e Total, 3a Ed.
#include <stdio.h>
#include <conio.h>
struct struct_type //define um tipo de estrutura
{
int a, b;
char ch;
};
void f1(struct struct_type param); //prototipo
void main()
{
struct struct_type arg;
arg.a = 1000;
f1(arg);
return 0;
}
void f1(struct struct_type param)
{
printf("%d", param.a);
}
O tipo de argumento deve coincidir com o tipo de parâmetro. Ambos são uma estrutura struct_type: ok!
71
struct dim { float largura1; float largura2; float altura; char modelo[80]; }mesa; ... struct dim *p; p = &mesa; p -> altura;
Estruturas
Herbert Schildt, C Completo e Total, 3a Ed.
Define a estrutura
Declara um ponteiro para a estrutura
Inicializa o ponteiro p com o endereço da estrutura mesa
O acesso aos elementos da estrutura é feito usando o operador seta
72
Estruturas
Herbert Schildt, C Completo e Total, 3a Ed.
#include <stdio.h>
#include <conio.h>
#define DELAY 1000000
struct my_time{
int hours;
int minutes;
int seconds;
};
void display(struct my_time *t);
void update(struct my_time *t);
void delay(void);
int main()
{
struct my_time systime;
systime.hours = 0;
systime.minutes = 0;
systime.seconds = 0;
for(;;) {
update(&systime);
display(&systime);
}
return 0;
}
void update(struct my_time *t){
t -> seconds++;
if(t->seconds==60){
t->seconds = 0;
t->minutes++;
}
if(t->minutes==60){
t->minutes = 0;
t->hours++;
}
if(t->hours==24)
t->hours = 0;
delay();
}
void display(struct my_time *t) {
printf("%02d: ", t->hours);
printf("%02d: ", t->minutes);
printf("%02d\n: ", t->seconds);
}
void delay(void) {
long int t; for(t=1; t<DELAY; t++);
}