Arranjos. David Déharbe 1 1
Roteiro da aula Exercícios motivadores para arranjos; Motivação; Definição; Arranjos em C; Arranjos e ponteiros; Exemplos. 2 2
Exercícios. Escreva um programa que lê cinco números inteiros, e imprime eles em ordem inversa. 3 3
Exercícios Escreva um programa que lê 1000 números inteiros, e imprime eles em ordem inversa. Escreva um programa que lê n, a quantidade de números inteiros, seguida de uma linha com n números inteiros, e imprime eles em ordem inversa. 4 4
Motivação Não é prático utilizar variáveis simples quando um programa precisa processar muitos dados e que todo o resultado depende de todos esses dados. Não é viável utilizar variáveis simples quando um programa precisa processar uma quantidade de dados variável e não limitada. 5 5
Definição Variáveis arranjos (ou vetores) armazenam um número fixo de valores de um mesmo tipo. A capacidade do arranjo é definida quando a variável é criada. O tipo dos valores do arranjo é definido no código fonte do programa. Cada valor do arranjo pode ser lida ou escrita individualmente. Em C, um arranjo de N valores do tipo T é um bloco de memória composto por N locações contíguas, cada uma armazenando um valor do tipo T. As locações são identificados por um número inteiro. Esse identificador é chamado índice. Os índices válidos vão de 0 até N-1. (ATENÇÃO: PERIGO!!!) 6 6
Arranjos em C: declaração Sintaxe para declarar uma variável arranjo: T a [ N ]; onde: a é o nome do arranjo N é a capacidade do arranjo T é o tipo de valores armazenadas no arranjo. Exemplo: int v [1000]; 7 7
Arranjos em C: declaração com inicialização Sintaxe para declarar e inicializar uma variável arranjo: T a [ N ] = {t1, t2,... tn; exemplo: float notas[4] = {4.5, 6.2, 3.7, 8.8; Inicialização parcial: as posições não inicializadas são zeradas. exemplo: float notas[5] = {4.5, 6.2; neste caso, há zeros nas posições 2, 3 e 4. exemplo: int n [1000] = {0; // todas as posições zeradas. Inicialização por posição: indica quais posições inicializar (exótico) int n [1000] = { [43] = 1, [2] = 7; neste caso, há 1 na posição 43, 7 na posição 2, e zeros nas demais. Se a capacidade é omitida, o compilador infere ela do tamanho da inicialização: int v [ ] = {2, 3, 5, 7; 8 // v tem tamanho 4 8
Exemplo 1: espelho de 1000 valores Escreva um programa que lê 1000 números inteiros, e imprime eles em ordem inversa. 9 9
Exemplo 1: solução Criar um arranjo de 1000 inteiros; Leitura da entrada no arranjo; Impressão da saída a partir do arranjo. 10 10
Exemplo 1: solução Criar um arranjo de 1000 inteiros, digamos a; Leitura da entrada em a; Impressão da saída a partir de a. 11 11
Exemplo 1: solução Criar um arranjo de 1000 inteiros, digamos a; int a [1000]; Leitura da entrada em a; Impressão da saída a partir de a. 12 12
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: Repetir 1000 vezes ler um inteiro e guardar na próxima posição não usada do arranjo Impressão da saída a partir do arranjo. 13 13
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: Repetir 1000 vezes (seja i o contador da repetição). ler um inteiro e guardar na próxima posição não usada do arranjo. Impressão da saída a partir do arranjo. 14 14
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; /* contador de repetições */ for (i = 1; i <= 1000; ++i) { ler um inteiro e guardar na próxima posição não usada do arranjo. Impressão da saída a partir do arranjo. 15 15
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; /* contador de repetições */ for (i = 1; i <= 1000; ++i) { ler um inteiro, digamos v, e guardar na próxima posição não usada do arranjo, digamos p. Impressão da saída a partir do arranjo. 16 16
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes int p; // proxima posicao livre de a for (i = 1, p = 0; i <= 1000; ++i) { int v; // guarda um valor de entrada ler um inteiro, digamos v, e guardar na próxima posição não usada do arranjo, digamos p. i = i + 1; Impressão da saída a partir do arranjo. 17 17
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes int p; // proxima posicao livre de a for (i = 1, p = 0; i <= 1000; ++i) { int v; // guarda um valor de entrada // ler um inteiro v, scanf("%i", &v); // e guardar na posição p do arranjo a. a[p]=v; p += 1; // atualizar p Impressão da saída a partir do arranjo. 18 18
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes int p; // proxima posicao livre de a for (i = 1, p = 0; i <= 1000; ++i) { int v; // guarda um valor de entrada // ler um inteiro v, scanf("%i", &v); // e guardar na posição p do arranjo a. a[p]=v; p = p + 1; // atualizar p Impressão da saída a partir do arranjo. 19 19
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes int p; // proxima posicao livre de a for (i = 1, p = 0; i <= 1000; ++i) { scanf("%i", &a[p]); p = p + 1; // atualizar p Impressão da saída a partir do arranjo. 20 20
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes int p; // proxima posicao livre de a for (i = 1, p = 0; i <= 1000; ++i) { scanf("%i", &a[p]); p = p + 1; // atualizar p Impressão da saída a partir do arranjo. 21 21
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes for (i = 0; i < 1000; ++i) { scanf("%i", &a[i]); Impressão da saída a partir do arranjo. 22 22
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes for (i = 0; i < 1000; ++i) { scanf("%i", &a[i]); Impressão da saída a partir do arranjo. 23 23
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes for (i = 0; i < 1000; ++i) { scanf("%i", &a[i]); Impressão da saída a partir do arranjo. 24 24
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i; // contador de repeticoes for (i = 0; i < 1000; ++i) { scanf("%i", &a[i]); Impressão do arranjo da última até a primeira posição: repetição. 25 25
Exemplo 1: solução Criar um arranjo de 1000 inteiros; int a [1000]; Leitura da entrada em a: int i = 1; // contador de repeticoes while (i <= 1000) { scanf("%i", &a[i-1]); i = i + 1; Impressão do arranjo da última até a primeira posição: repetição. for (i = 999; i>= 0; --i) printf("%i ", a[i]); printf("\n"); 26 26
Exemplo 1: implementação #include <stdio.h> /* para printf, scanf */ int main () { int a[1000]; int i; // contador de repeticoes for (i = 0; i < 1000; ++i) { scanf("%i", &a[i]); for (i = 999; i >= 0; --i) { printf("%i", a[i]); return 0; 27 27
Exemplo 1: implementação #include <stdio.h> /* para printf */ int main () { int tamanho = 1000; int a[tamanho]; int i; for (i = 0; i < tamanho; ++i) { scanf("%i", &a[i-1]); for (i = tamanho-1; i >= 0; --i) { printf("%i", a[i]); return 0; 28 28
Exercícios motivadores Escreva um programa que lê n, a quantidade de números inteiros, seguida de uma linha com n números inteiros, e imprime eles em ordem inversa. 29 29
Solução #include <stdio.h> /* para printf */ int main () { int n; scanf("%i", &n); int a[n]; int i; for (i = 0; i < n; ++i) { scanf("%i", &a[i-1]); for (i = n-1; i >= 0; --i) { printf("%i", a[i]); return 0; 30 30
Exercício: soma dos elementos de um arranjo Escreva uma sub-rotina que tem como parâmetro um arranjo de 1000 floats e retorna a soma dos elementos do arranjo. interface: float soma_arranjo_float (float v[1000]); 31 31
Exercício: maior elemento de um arranjo Escreva uma sub-rotina que tem como parâmetro um arranjo de 1000 floats e retorna o maior deles. interface: float max_arranjo_float (float v[1000]); 32 32
Exercício: busca em um arranjo Escreva uma sub-rotina que tem como parâmetros um arranjo a de 1000 ints e um int i, e retorna 1 se i é elemento de a, e 0 caso contrário. interface: int busca_arranjo_int (int a[1000], int i); 33 33
Exercício: posição de um valor em um arranjo Escreva uma sub-rotina que tem como parâmetros um arranjo a de 1000 ints e um int i, e retorna a menor posição de a que contem o valor i ou -1 se a não contem o valor i. interface: int pos_arranjo_int (int a[1000], int i); 34 34
Exercício: contagem de ocorrências Escreva uma sub-rotina que tem como parâmetros um arranjo a de 1000 ints e um int i, e retorna o número de posições de a que contem com o valor i. interface: int num_arranjo_int (int a[1000], int i); 35 35
Exercício: teste de ordem Escreva uma sub-rotina que tem como parâmetros um arranjo a de 1000 ints e retorna 1 se os valores de a estão em ordem estritamente crescente, e 0 caso contrário. interface: int arranjo_crescente (int a[1000]); 36 36
Exercício: teste de simetria Escreva uma sub-rotina que tem como parâmetros um arranjo a de 1000 ints e retorna 1 se o conteúdo de a é simétrico, e 0 caso contrário. interface: int arranjo_simétrico (int a[1000]); O conteúdo de um arranjo é dito simétrico quando o valor na primeira posição é igual ao valor na última posição, o valor na segunda posição é igual ao valor na penúltima posição, etc. 37 37
Exercício: maior subsequência crescente Uma subsequência de um arranjo é uma faixa de posições. Escreva uma sub-rotina que tem como parâmetros um arranjo a de 1000 ints e retorna o tamanho da maior subsequência estritamente crescente de a. interface: int arranjo_msc (int a[1000]); 38 38