Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
Ambos lados da revisão anterior Revisão anterior Próxima revisão | Revisão anterior | ||
c:vetores [2023/08/16 14:23] – [Declaração] maziero | c:vetores [2024/10/01 17:30] (atual) – maziero | ||
---|---|---|---|
Linha 1: | Linha 1: | ||
+ | ====== Vetores e matrizes ====== | ||
+ | |||
+ | Neste módulo veremos a foma como são declarados, inicializados e utilizados vetores e matrizes em C. | ||
+ | |||
+ | ===== Vetores ===== | ||
+ | |||
+ | Como em outras linguagens de programação, | ||
+ | |||
+ | As principais características de vetores em C são: | ||
+ | |||
+ | * os valores são acessíveis individualmente através de índices | ||
+ | * As entradas do vetor ocupam posições contíguas de memória | ||
+ | * Os vetores têm tamanho predefinido e fixo | ||
+ | * Os vetores sempre iniciam na posição 0 | ||
+ | |||
+ | ==== Declaração ==== | ||
+ | |||
+ | Um vetor é declarado da seguinte forma em C: | ||
+ | |||
+ | < | ||
+ | |||
+ | Alguns exemplos: | ||
+ | |||
+ | <code c> | ||
+ | int | ||
+ | float temperatura[24]; | ||
+ | char digito[10] ; // vetor de 10 caracteres | ||
+ | </ | ||
+ | |||
+ | Uma prática recomendada é definir a dimensão do vetor usando uma **macro** de preprocessador, | ||
+ | |||
+ | <code c> | ||
+ | #define MAXVET 1000 | ||
+ | |||
+ | float v[MAXVET] ; | ||
+ | |||
+ | for (i = 0; i < MAXVET; i++) | ||
+ | v[i] = 0.0 ; | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Inicialização ==== | ||
+ | |||
+ | Os elementos de um vetor podem ser inicializados durante sua declaração, | ||
+ | |||
+ | <code c> | ||
+ | short int valor[5] = { 32, 475, 58, 119, 7442 } ; | ||
+ | |||
+ | float temperatura[24] = | ||
+ | { | ||
+ | 17.0, 18.5, 19.2, 21.4, 22.0, 23.5, | ||
+ | 24.1, 24.8, 25.8, 26.9, 27.1, 28.9, | ||
+ | 29.5, 31.0, 32.3, 33.7, 34.9, 36.4, | ||
+ | 37.0, 38.5, 39.6, 40.5, 42.3, 44.2 | ||
+ | } ; | ||
+ | |||
+ | char digito[10] = { ' | ||
+ | </ | ||
+ | |||
+ | ==== Acesso ==== | ||
+ | |||
+ | O acesso aos elementos de um vetor se faz de forma similar a outras linguagens: basta indicar o nome do vetor e a posição (índice) que se deseja acessar. | ||
+ | |||
+ | <note important> | ||
+ | Em C, o índice de um vetor sempre **inicia na posição 0** e termina na posição // | ||
+ | </ | ||
+ | |||
+ | Exemplos: | ||
+ | |||
+ | <code c> | ||
+ | short int valor[5] ; | ||
+ | |||
+ | valor[0] = 73 ; | ||
+ | valor[3] = valor[2] + 10 ; | ||
+ | valor[4]++ ; | ||
+ | |||
+ | for (i = 0; i < 24; i++) // " | ||
+ | temperatura[i] = 20 + i/2 ; | ||
+ | </ | ||
+ | |||
+ | Os elementos de um vetor **sempre** ocupam posições contíguas e de mesmo tamanho na memória. Por exemplo, o vetor '' | ||
+ | |||
+ | <code c> | ||
+ | short int valor[5] = { 32, 475, 58, 119, 7442 } ; | ||
+ | </ | ||
+ | |||
+ | ^ Endereço | addr | addr+2 | ||
+ | ^ Entrada | '' | ||
+ | ^ Conteúdo | 32 | 475 | 58 | 119 | 7442 | | ||
+ | |||
+ | Para gerar um código executável eficiente, o compilador não faz **nenhuma verificação de índices** de vetores nem gera código para essas verificações durante a execução. Por exemplo, uma escrita em '' | ||
+ | |||
+ | <note important> | ||
+ | É **responsabilidade do programador** garantir que os índices acessados em um vetor estejam sempre dentro dos limites alocados ao mesmo. | ||
+ | </ | ||
+ | |||
+ | Finalmente, deve-se observar que não é possível atribuir um vetor a outro diretamente; | ||
+ | |||
+ | <code c> | ||
+ | #define SIZE 10 | ||
+ | |||
+ | int v1[SIZE], v2[SIZE] ; | ||
+ | |||
+ | v1 = { 2, 3, 4, 7, 2, 1, 9, 2, 3, 4 } ; | ||
+ | |||
+ | // NÃO FUNCIONA... | ||
+ | v2 = v1 ; | ||
+ | |||
+ | // FUNCIONA! | ||
+ | for (int i = 0; i < SIZE; i++) | ||
+ | v2[i] = v1[i] ; | ||
+ | |||
+ | // usando cópia de memória (mais rápida) | ||
+ | memcpy (v2, v1, SIZE * sizeof(int)) ; | ||
+ | </ | ||
+ | |||
+ | ==== Vetores de tamanho variável ==== | ||
+ | |||
+ | No padrão C89, o compilador precisa saber qual o tamanho do vetor para poder reservar memória para ele durante a compilação. Por isso, o número de elementos do vetor deve ser uma constante ou uma expressão/ | ||
+ | |||
+ | <code c> | ||
+ | #define MAX 10 | ||
+ | |||
+ | int vet1[MAX} ; // válido em C89, pois MAX é constante | ||
+ | int vet2[100] ; // válido em C89, pois 100 é constante | ||
+ | |||
+ | int func (int size) | ||
+ | { | ||
+ | int vet3[size]; | ||
+ | |||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | O padrão C99 introduziu a definição de vetores de tamanho variável, ou VLA - [[https:// | ||
+ | |||
+ | Algumas observações importantes sobre VLAs: | ||
+ | |||
+ | * VLAs não podem ser variáveis globais ou estáticas, somente variáveis locais. | ||
+ | * VLAs são alocados na área de memória chamada "pilha de execução", | ||
+ | * VLAs são fontes potenciais de bugs de segurança e **devem ser evitados** quando possível. | ||
+ | |||
+ | ===== Matrizes ===== | ||
+ | |||
+ | A linguagem C não oferece um tipo //matriz// nativo. Em vez disso, matrizes são implementadas como vetores de vetores. | ||
+ | |||
+ | ==== Declaração ==== | ||
+ | |||
+ | A forma geral de declaração de uma matriz com N dimensões é a seguinte: | ||
+ | |||
+ | < | ||
+ | |||
+ | Alguns exemplos: | ||
+ | |||
+ | <code c> | ||
+ | char tabuleiro[8][8] ; // matriz de 8x8 posições (caracteres) | ||
+ | float cf[2][3] ; // matriz de 2x3 coeficientes reais | ||
+ | int | ||
+ | </ | ||
+ | |||
+ | Similarmente aos vetores, as matrizes também podem ser inicializadas durante sua declaração: | ||
+ | |||
+ | <code c> | ||
+ | float coef[2][3] = | ||
+ | { | ||
+ | { -3.4, 2.1, -1.0 }, | ||
+ | { 45.7, -0.3, 0.0 } | ||
+ | } ; | ||
+ | </ | ||
+ | |||
+ | A matriz '' | ||
+ | |||
+ | A alocação de uma matriz na memória é feita de forma linear e contígua, ou seja, com um elemento imediatamente após o outro. Por exemplo, a matriz '' | ||
+ | |||
+ | ^ Endereço | addr | addr + 3*sizeof(float) | ||
+ | ^ Entrada | '' | ||
+ | ^ Conteúdo | [ -3.4, 2.1 , -1.0 ] | [ 45.7, -0.3, 0.0 ] | | ||
+ | |||
+ | Ou, mais detalhadamente: | ||
+ | |||
+ | ^ Endereço | addr | addr+4 | ||
+ | ^ Entrada | '' | ||
+ | ^ Conteúdo | -3.4 | 2.1 | -1.0 | | ||
+ | |||
+ | Deve-se ter cuidado especial na declaração de matrizes, pois o espaço de memória ocupado por uma matriz cresce exponencialmente com o número de dimensões. Por exemplo: | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ==== Acesso ==== | ||
+ | |||
+ | O acesso aos valores de uma matriz se faz de forma similar ao vetor: | ||
+ | |||
+ | <code c> | ||
+ | int matriz[5][5] ; | ||
+ | |||
+ | matriz[0][3] = 73 ; | ||
+ | </ | ||
+ | |||
+ | ou | ||
+ | |||
+ | <code c> | ||
+ | #define DIM 8 | ||
+ | |||
+ | char tabuleiro[DIM][DIM] ; | ||
+ | |||
+ | // " | ||
+ | for (i = 0; i < DIM; i++) | ||
+ | for (j = 0; j < DIM; j++) | ||
+ | tabuleiro[i][j] = ' ' ; | ||
+ | </ | ||
+ | |||
+ | ===== Exercícios ===== | ||
+ | |||
+ | Escrever programas em C para: | ||
+ | |||
+ | - Leitura e escrita: | ||
+ | - ler um número N e um vetor de N inteiros | ||
+ | - Escrever o vetor na saída no formato '' | ||
+ | - Inverter o vetor e imprimi-lo: '' | ||
+ | - Cálculo da média: | ||
+ | - ler um número N e um vetor de N inteiros | ||
+ | - calcular a **média dos valores lidos** | ||
+ | - imprimir essa média | ||
+ | - imprimir os elementos do vetor que forem maiores que a média calculada | ||
+ | - Ordenação I: | ||
+ | - ler um número N e um vetor de N inteiros | ||
+ | - ordenar o vetor lido usando a técnica de **ordenação da bolha** | ||
+ | - imprimir os elementos do vetor ordenado | ||
+ | - Melhorar o programa anterior, percorrendo o vetor nos dois sentidos e evitando percorrer as pontas (ou seja, valores já ordenados) | ||
+ | - Ordenação II: | ||
+ | - ler um número N e um vetor de N inteiros | ||
+ | - ordenar o vetor lido usando a técnica de **ordenação por seleção** | ||
+ | - imprimir os elementos do vetor ordenado | ||
+ | - Ler uma matriz, calcular e imprimir sua **transposta** | ||
+ | - Ler duas matrizes, calcular e imprimir sua **multiplicação** | ||