Programação Aula 24 Ponteiros, vetores e structs Prof. Laura Silva de Assis Engenharia de Computação 2 o Período CEFET/RJ - Centro Federal de Educação Tecnológica Celso Suckow da Fonseca UnED Petrópolis 2 o semestre - 2015
1 Sumário 1 2 3
2 Quando declaramos uma variável do tipo vetor, é alocado uma quantidade de memória contigua cujo tamanho é especificado na declaração (e também depende do tipo do vetor); int a[5]; - Serão alocados 5 2 bytes de memória associadas a a. Uma variável vetor, assim como um ponteiro, armazena um endereço de memória: o endereço de início do vetor; Por este motivo, quando passamos um vetor como argumento para uma função, seu conteúdo pode ser alterado dentro da função (pois estamos passando na realidade o endereço inicial do espaço alocado para o vetor).
3 #include <stdio.h> void zeravet( int vet [], int tam){ int i ; for ( i = 0; i < tam; i++) vet [ i ] = 0; int main(){ int vetor [] = {1, 2, 3, 4, 5; int i ; zeravet(vetor, 5) ; printf ( Vet = [ ) ; for ( i = 0; i <5; i++) printf ( %d, vetor [ i ]) ; printf ( ]\n ) ; return (0) ;
4 Tanto é verdade que uma variável vetor possui um endereço, que podemos atribuí-la para uma variável ponteiro: int a [] = {1, 2, 3, 4, 5; int p; p = a; E podemos usar p como se fosse um vetor. for ( i = 0; i <5; i++) p[ i ] = i i ;
5 Uma variável vetor possui um endereço fixo (diferente de ponteiro); Não podemos atribuir um endereço para uma variável do tipo vetor. #include <stdio.h> int main(){ int a [] = {1, 2, 3, 4, 5; int b[5], i ; b = a; for ( i=0 ; i <5; i++) printf ( %d, b[ i ]) ; return (0) ; Erro de compilação!!!
6 Se b for declarado como um ponteiro, então não há problema; #include <stdio.h> int main(){ int a [] = {1, 2, 3, 4, 5; int b, i ; b = a; for ( i=0 ; i <5; i++) printf ( %d, b[ i ]) ; return (0) ;
7 - vetores Relembrando... Para passar vetores como parâmetros de funções, sempre declaramos o tipo do parâmetro como um apontador para o tipo do vetor. O C não tem como saber o tamanho do vetor. Se for preciso, temos que passar o tamanho em um parâmetro separado.
8 - vetores Relembrando... Há uma estreita relação entre ponteiros e matrizes: char str [80], p; p = str ; p foi inicializado com o endereço do primeiro elemento da matriz str. Maneiras de acessar o quinto elemento: str [4] //ou (p1+4)
9 - vetores multidimensionais são vetores de vetores; int M[3][4];
Matrizes dinamicamente alocadas Em alguns problemas será necessário usar a alocação de memória com funções de alocação dinâmica (malloc(), calloc(), realloc()), e operar na memória usando matriz, ou seja, criar uma matriz dinamicamente alocada; //Aloca espaco para uma string dinamicamente, solicita a ao usuá rio e imprime de trás para frente #include <stdio.h> #include <stdlib.h> #include <string.h> void main(){ char s ; int t ; s = (char ) malloc(80 sizeof (char )) ; if (! s){ printf ( Falha na solicitacao de memória \n ) ; exit (1) ; printf ( Digite uma string\n ) ; gets (s) ; printf ( \nstring invertida \n ) ; for (t=strlen (s) 1; t >=0; t ) putchar(s [ t ]) ; printf ( \n\n ) ; free (s) ; 10
11 Matrizes dinamicamente alocadas Resultado execução Digite uma string Aula de C String invertida C ed alua
12 - matrizes Acessar a memória alocada como se fosse uma matriz unidimensional não é complicado, porém matrizes dinâmicas multidimensionais possuem algumas particularidades; Como as dimensões da matriz não foram definidas no programa, não se pode indexar diretamente um ponteiro como se fosse uma matriz multidimensional; Para conseguir alocar matrizes dinamicamente deve-se passar o ponteiro como um parâmetro de uma função, dessa forma a função pode definir as dimensões do parâmetro que recebe o ponteiro, permitindo a indexação normal da matriz.
13 - matrizes Exemplo: //Apresenta as pontências dos numeros de 1 a 10 #include <stdio.h> #include <stdlib.h> // constroi a tabela de potencias void table ( int p[10][4]) { int i, j ; for ( i =1; i< 11; i++) for ( j=1; j <5; j++) p[ i 1][ j 1] = pot(i, j ) ; //exibe a tabela de potencias inteiras void show( int p [10][4]) { int i, j ; printf ( %10s %10s %10s %10s\n, N, Nˆ2, Nˆ3, Nˆ4 ) ; for ( i =1; i <11; i++){ for ( j=1; j <5; j++) printf ( %10d, p[ i 1][ j 1]) ; printf ( \n ) ;
14 - matrizes Exemplo: //eleva um inteiro a potencia especificada int pot( int a, int b){ int t=1, i ; for ( i =0; i<b; i++) t = t a; return (t) ; void main(){ int p; p = malloc(40 sizeof ( int )) ; if (!p){ printf ( Falha na alocação de memória \n ) ; exit (1) ; table (p) ; show(p) ; free (p) ;
15 - matrizes Resultado execução N Nˆ2 Nˆ3 Nˆ4 1 1 1 1 2 4 8 16 3 9 27 81 4 16 64 256 5 25 125 625 6 36 216 1296 7 49 343 2401 8 64 512 4096 9 81 729 6561 10 100 1000 10000
16 - matrizes A alocação dinâmica de memória para matrizes é realizada de forma semelhante que para vetores, com a diferença que tem-se um ponteiro apontando para outro ponteiro que aponta para o valor final;
17 - matrizes Cada linha da matriz é representada por um vetor independente; A matriz é representada por um vetor de vetores, ou vetor de ponteiros, sendo que cada elemento armazena o endereço do primeiro elemento de cada linha;
18 - matrizes Forma de se criar matrizes dinamicamente Crie um ponteiro para ponteiro; Associe um vetor de ponteiros dinamicamente com este ponteiro de ponteiro. O tamanho deste vetor é o número de linhas da matriz; Cada posição do vetor será associado com um outro vetor do tipo a ser armazenado, cada um destes vetores é uma linha da matriz, então seu tamanho é o número de colunas; No final toda a memória alocada deve ser desalocada.
19 - matrizes Exemplo #include <stdio.h> #include <stdlib.h> float alocarmatreal( int n, int m){ float V; //ponteiro para matriz int i ; // variavel auxiliar if (n < 1 m < 1){ printf ( ERRO!!! Par metros invá lidos \n ) ; return (NULL) ; //aloca as linhas da matriz V = ( float ) calloc (n, sizeof ( float )) ; if (V = = NULL){ printf ( Memó ria insuficiente!\n ) ; return (NULL) ; //continua...
20 - matrizes Exemplo //continuacao... //aloca as colunas da matriz for ( i =0; i< n; i++){ V[ i ] = ( float ) calloc (m, sizeof ( float )) ; if (V[ i ] = = NULL){ printf ( Memória insuficiente!\n ) ; return (NULL) ; return (V) ; float liberamatreal( int n, int m, float V){ int i ; if (V = = NULL) return (NULL) ; if (n < 1 m < 1){ printf ( ERRO!!! Par metros invá lidos \n ) ; return (NULL) ; //continua...
21 - matrizes Exemplo //continuacao... for ( i =0; i<n; i++) free (V[ i ]) ; free (V) ; V = NULL; return (V) ; int imprime( float V, int n, int m){ int i, j ; if (V == NULL){ printf ( Imposs í vel imprimir matriz vazia\n ) ; return (0) ; if (n < 1 m < 1){ printf ( ERRO!!! Par metros invá lidos \n ) ; return (0) ; //continua...
- matrizes Exemplo //continuacao... printf ( Imprimindo matriz %d X %d\n,n, m) ; for ( i =0; i<n; i++){ for ( j=0; j<m; j++) printf ( %3.f\t,V[ i ][ j ]) ; printf ( \n ) ; printf ( \n\n ) ; void main(){ float mat; //declaracao da matriz int lin, col, i, j ; printf ( Digite a dimensão da matriz quantidade de linhas e colunas \n ) ; scanf ( %d, &lin ) ; scanf ( %d, &col ) ; mat = alocarmatreal( lin, col ) ; // lendo informacoes da matriz printf ( \ndigite os dados para preencher a matriz %dx%d\n, lin, col ) ; for ( i =0; i<lin ; i++) for ( j=0; j<col ; j++) scanf ( %f,&mat[ i ][ j ]) ; //continua... 22
23 - matrizes Exemplo //continuacao... imprime(mat, lin, col ) ; // elevando elmentos da matriz ao quadrado for ( i =0; i<lin ; i++) for ( j=0; j<col ; j++) mat[ i ][ j ] = mat[ i ][ j ]; imprime(mat, lin, col ) ; liberamatreal( lin, col, mat) ;
24 - matrizes Resultado da execução Digite a dimensão da matriz quantidade de linhas e colunas 3 4 Digite os dados para preencher a matriz 3X4 1 5 6 3 2 0 1 1 2 3 3 3 Imprimindo matriz 3 X 4 1 5 6 3 2 0 1 1 2 3 3 3 Imprimindo matriz 3 X 4 1 25 36 9 4 0 1 1 4 9 9 9
25 Ponteiros para struct Ponteiros para struct Ao criarmos uma variável de um tipo struct, esta é armazenada na memória como qualquer outra variável, e portanto possui um endereço; é possível então criar um ponteiro para uma variável de um tipo struct! #include <stdio.h> struct Coordenada{ double x ; double y ; ; typedef struct Coordenada Coordenada ; int main(){ Coordenada c1, c2, c3; c3 = &c1 ;...
26 Ponteiros para struct Ponteiros para struct
27 Ponteiros para struct Ponteiros para struct Exemplo1: #include <stdio.h> struct Coordenada{ double x; double y; ; typedef struct Coordenada Coordenada ; int main(){ Coordenada c1, c2, c3 ; c3 = &c1; printf ( end de c1 %ld\n, (long )c3) ; c1.x = 1; c3 >y = 1.5; printf ( Coordenadas de c1: (%lf,%lf )\n,c1.x, c1.y) ; c3 = &c2; printf ( \nend de c2 %ld\n, (long )c3) ; c2.x = 2.5; c3 >y = 5; printf ( Coordenadas de c2: (%lf,%lf )\n\n,c2.x, c2.y) ; return (0) ;
28 Ponteiros para struct Ponteiros para struct Exemplo1: Resultado da execução end de c1 140730517871072 Coordenadas de c1: ( 1.000000, 1.500000) end de c2 140730517871088 Coordenadas de c2: (2.500000, 5.000000)
29 Ponteiros para struct Ponteiros para struct Exemplo 2: #include <stdio.h> struct Coordenada{ double x; double y; ; typedef struct Coordenada Coordenada ; int main(){ Coordenada c1, c2, c3 ; c3 = &c1; c1.x = 1; c1.y = 1.5; c2.x = 2.5; c2.y = 5; c3 = c2; printf ( Coordenadas de c1: (%lf,%lf )\n,c1.x, c1.y) ; return (0) ; O que será impresso?
Ponteiros para struct Ponteiros para struct Para acessarmos os campos de uma variável struct via um ponteiro, podemos utilizar o operador juntamente com o operador.: Coordenada c1, c3 ; c3 = &c1; ( c3).x = 1.5; ( c3).y = 1.5; Podemos usar o operador, para acessar campos de uma estrutura via um ponteiro: Coordenada c1, c3 ; c3 = &c1; c3 >x = 1.5; c3 >y = 1.5; Resumindo: PonteiroEstrutura->campo (*PonteiroEstrutura).campo 30
Ponteiros para struct Ponteiros para struct Exemplo 3: #include <stdio.h> struct Coordenada{ double x; double y; ; typedef struct Coordenada Coordenada ; int main(){ Coordenada c1, c2, c3, c4; c3 = &c1; c4 = &c2; c1.x = 1; c1.y = 1.5; c2.x = 2.5; c2.y = 5; ( c3).x = 1.5; ( c3).y = 1.5; c4 >x = 1; c4 >y = 1; printf ( Coordenadas de c1: (%lf,%lf )\n,c1.x, c1.y) ; printf ( Coordenadas de c2: (%lf,%lf )\n,c2.x, c2.y) ; return (0) ; O que será impresso? 31
32 1 C Completo e Total, Herbert Schidt; Pearson Makron Books; 3a. Ed., 1997. 2 Linguagem C, Luís Damas, LTC, 10a. Ed.2014. 3 Notas de aula pro. Falcão, Unicamp, 2015.