Baixe o app para aproveitar ainda mais
Prévia do material em texto
Curso de Programação C Prof. Monteiro 2018/1 Parte 3 1 Variáveis compostas homogêneas • Variáveis compostas homogêneas são conhecidas como arrays ou vetores. • Vetores são estruturas de dados que armazenam uma coleção de dados de um mesmo tipo. • As variáveis compostas podem ser: – Unidimensionais (arrays ou vetores) – Bidimensionais (matrizes) – Tridimensionais (3D) 2 Arrays em C • Um array ou vetor, é uma série de variáveis do mesmo tipo, referenciadas por um único nome, onde cada variável é diferenciada da outra através de um valor chamado “índice” que fica entre colchetes no fim do nome da variável. • Um array é um conjunto de valores com um único nome, onde cada elemento é distinto através de um índice ou posição. • Sintaxe: nome[valor] • Exemplo: nota[0], nota[1], . . . nota[4], nota[5] 3 Declarando arrays • Sintaxe: tipo nome[tamanho]; • Onde: tipo: define o tipo de dados do array nome: define o nome do array tamanho: define a quantidade de elementos • Exemplos: int x[10]; double y[20]; • Nos exemplos acima seriam criados um array inteiro x com 10 elementos e um array double y com 20 elementos. 4 Estrutura de um array • A estrutura de um array na memória é formada por um conjunto finito de posições contíguas, ou seja: • Array x com 14 elementos: • As posições de um array em C começam em zero. No exemplo acima, temos que: x[0] = 4 x[4] = -6 x[8] = 27 z = x[5] + x[9] z = 15 4 12 23 0 -6 8 20 56 27 7 12 20 5 5 0 1 2 3 4 5 6 7 8 9 10 11 12 13 5 Arrays em C • Vejamos o array notas: • Vamos preencher o array notas: • Notas: 5, 8, 7, 4.5, 10, 9.5, . . . • Complete as notas: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 6 Inicializando um array • Definindo um array notas com 5 elementos: float notas[5]; notas[0] = 5; notas[1] = 8.5; notas[2] = 7; notas[3] = 3.5; notas[4] = 10; printf(“%.1f %.1f %.1f %.1f %.1f”, nota[0], nota[1], nota[2], nota[3], nota[4]); 7 Inicializando arrays em C • Podemos também definir e inicializar um vetor da seguinte maneira: int x[10] = {11, 32, 20, 2, 5, 13,-2, 18, 6, 44}; ou int x[] = {11, 32, 20, 2, 5, 13,-2, 18, 6, 44}; O tamanho nesse caso pode ser omitido. • A linguagem C não verifica se você está utilizando índice inválido! Caso se use um índice fora dos limites, a tendência é acessar um espaço inválido ou de outra variável, o que resultará normalmente numa pane do programa. 8 Entrada e saída de um array • Entrando com os valores de um array: • Pensemos num array x com n elementos: for (i=0; i < n; i++) scanf(“%d”, &x[i]); • Exibindo os valores de um array: for (i=0; i < n; i++) printf(“%d ”, x[i]); 9 Manipulando os elementos do vetor • Manipulando o vetor x com n elementos: • Exemplo 1: s = 0; // soma dos elementos do vetor for (i=0; i<n; i++) s = s + x[i]; • Exemplo 2: s = 0; // soma dos valores maiores que 10 for (i=0; i<n; i++) if (x[i] > 10) s = s + x[i]; 10 Exercício 2.01 Escrever um programa para ler um array com N elementos e calcular a soma de seus valores. Mandar imprimir o array lido e o resultado obtido. O valor de N deve ser lido. 11 Resolução do exercício 2.01 #include <stdio.h> main(){ int i, n, s = 0; int x[20]; printf("Digite o valor de n:\n"); scanf("%d", &n); printf("Digite os valores de x:\n"); i = 0; do { scanf("%d", &x[i]); s = s + x[i]; i++; } while (i < n); printf("Soma = %d\n", s); system("pause"); } 12 Respostas do 2.01 Digite o valor de n: 3 Digite os valores de x: 6 7 4 Soma = 17 Press any key to continue . . . 13 Exercício 2.03 Escrever um programa para ler um array com N elementos e determinar a quantidade de valores pares e a de impares. Mandar imprimir o array lido e os resultados obtidos. O valor de N deve ser lido. 14 Resolução do exercício 2.03 #include <stdio.h> main(){ int i, n, qp = 0, qi = 0; int x[30]; printf("Digite o valor de n:\n"); scanf("%d", &n); printf("Digite os valores de x:\n"); for (i=0; i<n; i++){ scanf("%d", &x[i]); if (x[i] % 2 == 0) qp++; else qi++; } printf("Quant. pares = %d\n", qp); printf("Quant. impares = %d\n", q i); system("pause"); } 15 Respostas do 2.03 Digite o valor de n: 6 Digite os valores de x: 12 7 9 8 6 11 Quant. pares = 3 Quant. impares = 3 Press any key to continue . . . 16 Exercício 2.04 Escrever um programa para ler um array com N elementos e determinar o maior e o menor valor do array. Mandar imprimir o array e os resultados obtidos. O valor de N deve ser lido. 17 Resolução do 2.04 main(){ int i, n, ma, me; int x[50]; printf("Digite o valor de n:\n"); scanf("%d", &n); printf("Digite os valores do array:\n"); for (i=0; i<n; i++) scanf("%d", &x[i]); printf("Array lido:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); printf("\n"); 18 Resolução do 2.04 ma = me = x[0]; for (i=1; i < n; i++) if (x[i] > ma) ma = x[i]; else if (x[i] < me) me = x[i]; printf("Maior = %d\tMenor = %d\n", ma, me); getch(); } 19 Resposta do 2.04 Digite o valor de n: 10 Digite os valores do array: 5 12 56 32 4 19 10 21 33 29 Array lido: 5 12 56 32 4 19 10 21 33 29 Maior = 56 Menor = 4 20 Função time() • A função time() retorna um inteiro com o número de segundos passados desde às 00:00 horas de 1 de janeiro de 1970 até o momento. • Quando esta função é chamada, ela produz um valor aleatório na faixa entre 0 e a constante RAND_MAX (no caso 32767). O valor desta constante encontra-se definido no arquivo stdlib.h. • Acontece que para a função rand funcionar ela precisa de um valor inicial chamado de “semente”. Se nenhum valor for passado, rand assume um valor constante. No caso a função assume 1. Como este valor, ou seja 1, é assumido sempre no programa, a sequência gerada será a mesma para cada execução. 21 Exercício geraVetor Gerar um vetor randômico com N elementos contendo valores positivos menores ou iguais a 100. Imprimir o vetor. Mandar ler N. 22 Exercício geraVetor main(){ int i, n; int x[50]; printf("Digite o valor de n:\n"); scanf("%d", &n); srand(n); for (i=0; i<n; i++) x[i] = rand() % 100 + 1; printf("Array criado:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); printf("\n"); getch(); } 23 Exercício geraVetor Digite o valor de n: 15 Array criado: 88 6 57 39 2 63 85 45 49 28 36 62 46 1 41 24 Exercício trocaValores2 Dado um vetor com 10 valores, comparar os 5 elementos iniciais e trocá-los com seus correspondentes finais em caso de serem maiores. Fazer a correspondência do primeiro com o último, do segundo com o penúltimo, etc. 25 Resolução de trocaValores2 main(){ int i, k, aux, n=10; int x[10] = {5, 8, 12, 7, 30, 22, 14, 18, 3, 9};printf("Vetor dado:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); printf("\n\n"); k = n-1; for (i=0; i<n/2; i++){ if (x[i] > x[k]){ aux = x[i]; x[i] = x[k]; x[k] = aux; } k--; } printf("Vetor final:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); getch(); } 26 Resposta de trocaValores2 Vetor dado: 5 8 12 7 30 22 14 18 3 9 Vetor final: 5 3 12 7 22 30 14 18 8 9 27 Exercício insereValor Dado um vetor ordenado finalizado pelo valor -999, ler um valor y e inserir esse valor no vetor dado mantendo a ordenação existente. Imprimir o vetor dado e o vetor após a inserção. 28 Situação equivalente • O problema pode ser comparado à seguinte situação: • Um deficiente visual tem como uma de suas tarefas manter uma prateleira de medicamentos em ordem alfabética. As caixas têm o nome também em braile. Ele precisa inserir um medicamento na prateleira. • A parte final da prateleira tem espaço para ampliação. • O cego precisa rearrumar a prateleira afastando os últimos medicamentos para abrir o espaço necessário para incluir o novo medicamento e procurar a posição certa para a inclusão. • Após a colocação do medicamento termina a tarefa. 29 Pensando a lógica • Procurar a posição de inserção do valor: Quando x[i] < valor, insere depois • Enquanto não achar a posição de inserção vai copiando o elemento uma posição depois; • Quando achar a posição de inserção coloca o valor na posição; • Após a inserção termina o processo; • Caso o valor não tenha sido inserido, faz a inserção no início. 30 Resolução de insereValor main(){ int i=0, y, sit=0; int x[30] = {4, 7, 12, 17, 20, 23, 25, 30, 34, 41, -999}; printf("Vetor dado:\n"); while (x[i] != -999) printf("%d ", x[i++]); x[i+1]= x[i]; // nova posição do -999 i--; // índice do último elemento atual printf("\nDigite o valor de Y:\n"); scanf("%d", &y); while (i >= 0){ if (sit == 1) break; if (x[i] > y){ x[i+1] = x[i]; i--; 31 Resolução de insereValor } else if (sit == 0){ x[i+1] = y; sit = 1; } } if (sit == 0) x[0] = y; // inclui o novo elemento no início printf("\nVetor modificado:\n"); i=0; while(x[i] != -999) printf("%d ", x[i++]); getch(); } 32 Resposta de insereValor Vetor dado: 4 7 12 17 20 23 25 30 34 41 Digite o valor de Y: 19 Vetor modificado: 4 7 12 17 19 20 23 25 30 34 41 33 Exercício 2.05 Escrever um programa para ler um array com N elementos e colocar os seus valores em ordem crescente. Mandar imprimir o array na forma original e após a ordenação. O valor de N deve ser lido. 34 Resolução do exercício 2.05 // Método da seleção #include <stdio.h> main(){ int i, j, n, aux; int x[50]; printf("Digite o valor de n:\n"); scanf("%d", &n); printf("Digite os valores do array:\n"); for (i=0; i<n; i++) scanf("%d", &x[i]); printf("Array lido:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); printf("\n"); for (i=0; i<n-1; i++) for (j=i+1; j<n; j++) if (x[j] < x[i]){ aux = x[i]; x[i] = x[j]; x[j] = aux; } printf("Array ordenado:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); getch(); } 35 Resultados do 2.05 Digite o valor de n: 6 Digite os valores do array: 12 5 23 8 2 11 Array lido: 12 5 23 8 2 11 Array ordenado: 2 5 8 11 12 23 36 Método da Bolha • O método de ordenação da bolha é menos eficiente, a lógica seria: for (i=0; i<n; i++) for (j=0; j<n; j++){ if (x[i] < x[j]){ aux = x[i]; x[i] = x[j]; x[j] = aux; } } • O número de operações é o dobro do método da seleção. 37 Exercício 2.09 Escrever um programa para ler um array X com N elementos e criar um array Y com os elementos de X na ordem inversa. Mandar imprimir os dois arrays. O valor de N deve ser lido. 38 Resolução do 2.09 main(){ int i, k, n; int x[30], y[30]; printf("Digite o valor de n: \n"); scanf("%d", &n); printf("Digite os valores do array:\n"); for (i=0; i<n; i++) scanf("%d", &x[i]); printf("Array lido:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); k = n-1; for (i=0; i<n; i++){ y[k] = x[i]; k--; } printf("\nArray invertido:\n"); for (i=0; i<n; i++) printf("%d ", y[i]); printf("\n"); system("pause"); } 39 Resposta do 2.09 Digite o valor de n: 7 Digite os valores do array: 78 6 9 4 23 12 33 Array lido: 78 6 9 4 23 12 33 Array invertido: 33 12 23 4 9 6 78 Press any key to continue . . . 40 Exercício 2.10 Escrever um programa para ler um array X com N elementos e inverter a ordem dos elementos de X sem a ajuda de outro array. Mandar imprimir o array X nas duas situações. O valor de N deve ser lido. 41 Resolução do 2.10 main(){ int i, k, n, t, aux; int x[30]; printf("Digite o valor de n:\n"); scanf("%d", &n); printf("Digite os valores do array:\n"); for (i=0; i<n; i++) scanf("%d", &x[i]); printf("Array lido:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); printf(“\n”); k = n-1; t = n/2; // inverte a metade for (i=0; i<t; i++){ aux = x[i]; x[i] = x[k]; x[k] = aux; k--; } printf("Array invertido:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); printf("\n"); system("pause"); } 42 Resposta do 2.10 Digite o valor de n: 7 Digite os valores do array: 78 6 9 4 23 12 33 Array lido: 78 6 9 4 23 12 33 Array invertido: 33 12 23 4 9 6 78 Press any key to continue . . . 43 Exercício 2.14 Escrever um programa para ler um array com N elementos e eliminar os valores nulos desse array. Usar apenas o array lido. Mandar imprimir o array nas duas situações. O valor de N deve ser lido. 44 Resolução do 2.14 main(){ int i, k, n; int x[30]; printf("%Digite o valor de n: \n"); scanf("%d", &n); printf("Digite os valores do array:\n"); for (i=0; i<n; i++) scanf("%d", &x[i]); printf("Array lido:\n"); for (i=0; i<n; i++) printf("%d ", x[i]); k = 0; for (i=0; i<n; i++) if (x[i] != 0){ x[k] = x[i]; // confirma valor k++; } printf("\nNovo array:\n"); for (i=0; i<k; i++) printf("%d ", x[i]); printf("\n"); getch(); } 45 Resposta do 2.14 Digite o valor de n: 8 Digite os valores do array: 7 0 0 9 3 12 0 23 Array lido: 7 0 0 9 3 12 0 23 Novo array: 7 9 3 12 23 46 Arrays bidimensionais • Arrays bidimensionais ou matrizes, são estruturas de dados homogêneos armazenados em forma de linhas e colunas. • Notação: nome_array [linha][coluna] • Exemplos: a[i][j], a[1][3], mat[i+1][j] • Definindo uma matriz: tipo nome[num_linhas][num_colunas]; • Exemplo:int a[5][4]; float ma[3][6]; • Indica que a matriz a tem limite de 5 linhas e 4 colunas. 47 Matrizes • Definindo e inicializando uma matriz: int ma [3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; • Onde ma está sendo inicializada com 1, 2, 3 e 4 na linha 1, com 5, 6, 7 e 8 na linha 2, e com 9, 10, 11 e 12 na linha 3. int ma [ ][2] = { 1,2,3,4,5,6,7,8,9,10 }; • Nesse caso como são 2 colunas, serão preenchidos 2 valores por linha, usando 5 linhas: linha 1: 1, 2 linha 2: 3, 4 linha 3: 5, 6 linha 4: 7, 8 linha 5: 9, 10 48 Matrizes • Lendo uma matriz a com m linhas e n colunas: for (i=0; i<m; i++) for (j=0; j<n; j++) scanf(“%d”, &a[i][j]); • Imprimindo uma matriz a com m linhas e n colunas: for (i=0; i<m; i++){ for (j=0; j<n; j++) printf(“%d ”, a[i][j]); printf(“\n“); // muda de linha } 49 Matrizes • Manipulando uma matriz a com m linhas e n colunas: int somaPares = 0; for (i=0; i<m; i++) for (j=0; j<n; j++) if (a[i][j] % 2 == 0) somaPares = somaPares + a[i][j]; 50 Exercício 3.01 Escrever um programa para ler uma matriz A com M linhas e N colunas, e copiar os seus elementos, linha por linha, em um array X. Mandar imprimir a matriz A e o array X. O valor de M e o de N devem ser lidos. 51 Resolução do exercício 3.01 #include <stdio.h> main(){ int i, j, m, n, k=0; int ma[5][5], x[25]; printf("Digite os valores de m e de n:\n"); scanf("%d %d", &m, &n); for (i=0; i<m; i++){ printf("Digite os valores da linha %d\n", (i+1)); for (j=0; j<n; j++) scanf("%d", &ma[i][j]); } 52 Resolução do exercício 3.01 printf("Matriz lida:\n"); for (i=0; i<m; i++){ for (j=0; j<n; j++){ printf("%d ", ma[i][j]); x[k++] = ma[i][j]; } printf("\n"); } printf("Vetor obtido:\n"); for (i=0; i<m*n; i++) printf("%d ", x[i]); printf("\n"); system("pause"); } 53 Resposta do 3.01 Digite os valores de m e de n: 3 2 Digite os valores da linha 1 9 5 Digite os valores da linha 2 4 8 Digite os valores da linha 3 5 2 Matriz lida: 9 5 4 8 5 2 Vetor obtido: 9 5 4 8 5 2 Press any key to continue . . . 54 Exercício 3.07 Escrever um programa para criar uma matriz A com M linhas e N colunas, usando números randômicos com valores no intervalo de 1 a 20, e determinar o maior valor de cada linha da matriz. Mandar imprimir a matriz A e os resultados obtidos. Mandar ler M e N. 55 Resolução do exercício 3.07 #include <stdio.h> #include <stdlib.h> main(){ int i,j,m,n,maior; int a[10][10]; printf("Digite os valores de m e de n:\n"); scanf("%d %d", &m, &n); // Gerando os valores for (i=0; i<m; i++){ for (j=0; j<n; j++) a[i][j] = rand() % 20 + 1; } 56 Resolução do exercício 3.07 // Imprimindo a matriz printf("Matriz criada:\n"); for (i=0; i<m; i++){ for (j=0; j<n; j++) printf("%d\t", a[i][j]); printf("\n"); } // Determinando o maior valor de cada linha for (i=0; i<m; i++){ maior = a[i][0]; // Inicializando com o primeiro da linha i for (j=1; j<n; j++){ if (a[i][j] > maior) maior = (a[i][j] ; 57 Resolução do exercício 3.07 printf(“Maior valor da linha %d = %d\n”, i, maior); } getch(); } 58 Separando palavras • Ler uma string e imprimir as palavras existentes. main(){ int i, k, n; //Um texto muito bom, eh aquele que possui muitas palavras. char str[81], pa[10]; printf("Digite uma string: \n"); fgets(str,81,stdin); n = strlen(str); // tamanho da string printf("String lida:\n"); for (i=0; i<n; i++) printf("%c", str[i]); printf("\n"); 59 Separando palavras k=0; for (i=0; i<n; i++) if (str[i] != ' ' && str[i] != ',' && str[i] != '.') // separadores pa[k++] = str[i]; else if (k > 0) { pa[k]='\0'; printf("%s\n",pa); k = 0; } getch(); } 60 Separando palavras Digite uma string: Um texto bem simples, eh aquele que possui muitas palavras. String lida: Um texto bem simples, eh aquele que possui muitas palavras. Palavras separadas: Um texto bem simples eh aquele que possui muitas palavras 61 Exercício trocaValoresMatriz Ler uma matriz A com M linhas e N colunas, sendo N ímpar, trocar os elementos da coluna do meio pelo maior valor da linha. Imprimir a matriz antes e depois das trocas. Mandar ler M e N. 62 Resolução de trocaValoresMatriz main(){ int i, j, m, n, aux; int a[10][10]; while (1){ printf("Digite os valores de M e de N (N impar):\n"); scanf("%d %d", &m, &n); if (n % 2 != 0) break; } for (i=0; i<m; i++){ printf("Digite os valores da linha %d:\n", i+1); for (j=0; j<n; j++) scanf("%d", &a[i][j]); } 63 Resolução de trocaValoresMatriz printf("Matriz lida:\n"); for (i=0; i<m; i++){ for (j=0; j<n; j++) printf("%d\t", a[i][j]); printf("\n"); } for (i=0; i<m; i++) for (j=0; j<n; j++) if (a[i][n/2] < a[i][j]){ aux = a[i][n/2]; a[i][n/2] = a[i][j]; a[i][j] = aux; } 64 Resolução de trocaValoresMatriz printf("Matriz final:\n"); for (i=0; i<m; i++){ for (j=0; j<n; j++) printf("%d\t", a[i][j]); printf("\n"); } getch(); } 65 Resposta de trocaValoresMatriz Digite os valores de M e de N (N impar): 3 4 Digite os valores de M e de N (N impar): 3 6 Digite os valores de M e de N (N impar): 4 5 Digite os valores da linha 1: 3 8 4 5 6 Digite os valores da linha 2: 9 12 4 6 9 Digite os valores da linha 3: 2 3 5 10 6 Digite os valores da linha 4: 8 2 9 6 4 66 Resposta de trocaValoresMatriz Matriz lida: 3 8 4 5 6 9 12 4 6 9 2 3 5 10 6 8 2 9 6 4 Matriz final: 3 4 8 5 6 4 9 12 6 9 2 3 10 5 6 8 2 9 6 4 67 Exercício diagonal1 Dada uma matriz quadrada A com M linhas e M colunas, substituir os elementos da diagonal principal pela soma dos elementos fora da diagonal em cada linha. 68 Resolução de diagonal1 main(){ int i, j, m, s; int a[][3]={{5, 16, 2}, {10, 15, 12}, {7, 14, 8}}; m = 3; printf("Matriz dada:\n"); for (i=0; i<m; i++){ for (j=0; j<m; j++) printf("%d\t", a[i][j]); printf("\n"); } 69 Resolução de diagonal1 for (i=0; i<m; i++){ s = 0; for (j=0; j<m; j++) if (j != i) s += a[i][j]; a[i][i] = s; } printf("\nMatriz final:\n"); for (i=0; i<m; i++){ for (j=0; j<m; j++) printf("%d\t", a[i][j]); printf("\n");} getch(); } 70 Resposta de diagonal1 Matriz dada: 5 16 2 10 15 12 7 14 8 Matriz final: 18 16 2 10 22 12 7 14 21 71 Exercício 3.13 Escrever um programa para ler um array com K elementos e montar uma matriz A com M linhas e N colunas. Completar os elementos da última linha com zeros se necessário. Mandar ler M, N, K e os valores do array. Imprimir o array e a matriz criada. 72 Resolução do 3.13 main(){ int i,j,m,n,k,p; // k -> número de elementos de X int a[5][5], x[25]; printf("Digite os valores de k, m e n:\n"); scanf("%d %d %d", &k, &m, &n); printf("Digite os valores do vetor:\n"); for (i=0; i<k; i++){ scanf("%d", &x[i]); } printf("Vetor lido:\n"); for (i=0; i<k; i++) printf("%d ", x[i]); printf("\n"); p=0; // índice do vetor for (i=0; i<m; i++) for (j=0; j<n; j++) if (p >= k) a[i][j] = 0; else a[i][j] = x[p++]; printf("Matriz obtida:\n"); for (i=0; i<m; i++){ for (j=0; j<n; j++){ printf("%d\t", a[i][j]); } printf("\n"); } getch(); } 73 Resposta do 3.13 Digite os valores de k, m e n: 10 4 3 Digite os valores do vetor: 7 2 4 8 9 10 6 12 3 5 Vetor lido: 7 2 4 8 9 10 6 12 3 5 Matriz obtida: 7 2 4 8 9 10 6 12 3 5 0 0 74 Exercício 3.14 Escrever um programa para ler uma matriz com M linhas e N colunas e calcular a média aritmética dos valores de cada coluna da matriz. Mandar imprimir a matriz A e os resultados obtidos. Mandar ler M e N. 75 Resolução do exercício 3.14 #include <stdio.h> main(){ int i,j,m,n,s; int a[5][5]; float med; printf("Digite os valores de m e de n:\n"); scanf("%d %d", &m, &n); for (i=0; i<m; i++){ printf("Digite os valores da linha %d\n", (i+1)); for (j=0; j<n; j++) scanf("%d", &a[i][j]); } printf("Matriz lida:\n"); 76 Resolução do exercício 3.14 for (i=0; i<m; i++){ for (j=0; j<n; j++){ printf("%d\t", a[i][j]); } printf("\n"); } // manipulando por coluna for(j=0; j<n; j++){ s = 0; for(i=0; i<m; i++) s = s + a[i][j]; med = (float)s/m; printf("Media da coluna %d %.1f\n", j+1, med); } system("pause"); } 77 Respostas do 3.14 Digite os valores de m e de n: 3 4 Digite os valores da linha 1 5 13 9 3 Digite os valores da linha 2 15 9 10 8 Digite os valores da linha 3 14 8 9 33 Matriz lida: 5 13 9 3 15 9 10 8 14 8 9 33 Media da coluna 1 = 11.3 Media da coluna 2 = 10.0 Media da coluna 3 = 9.3 Media da coluna 4 = 14.7 Press any key to continue . . . 78 Matriz de Nomes • Criar uma matriz de caracteres, onde em cada linha deverá ter uma string. main(){ char nomes[50][41]; int i, n; printf("Digite o valor de N\n"); scanf("%d%*c",&n); printf("Digite %d nomes\n",n); for(i=0; i<n; i++) gets(nomes[i]); printf("\nNomes lidos:\n"); for(i=0; i<n; i++) printf("%s\n",nomes[i]); getch(); } 79 Exercício 3.12 Escrever um programa para ler os dados de N alunos, cada aluno com a idade e sexo, e fazer uma tabulação dos dados. Mandar ler N. Usar as faixas de idade: 0 a 20, 21 a 30, 31 a 40, acima de 40. Totalizar por faixa e por sexo. Usar sexo: 1 - Masculino, 2 - Feminino. 80 Tabela do 3.12 Mas Fem Total Até 20 0 0 0 De 21 a 30 0 0 0 De 31 a 40 0 0 0 Acima de 40 0 0 0 Total 0 0 0 81 Layout da tabela do 3.12 | Mas | Fem | Total --------------------------------------------- Ate 20 | 0 | 0 | 0 --------------------------------------------- De 21 a 30 | 0 | 0 | 0 --------------------------------------------- De 31 a 40 | 0 | 0 | 0 --------------------------------------------- Acima de 40 | 0 | 0 | 0 --------------------------------------------- Total | 0 | 0 | 0 82 Resolução do 3.12 main(){ int id, sx, i, j, k, n; int a[5][3]; for (i=0; i<5; i++) for (j=0; j<3; j++) a[i][j] = 0; printf("Digite a quantidade de alunos:\n"); scanf("%d", &n); for (k=0; k<n; k++){ printf("Digite idade e sexo(1 ou 2):\n"); scanf("%d %d", &id, &sx); if (id <= 20) i = 0; else if (id > 20 && id <= 30) i = 1; else if (id > 30 && id <= 40) i = 2; else i = 3; if (sx==1) j=0; else j=1; a[i][j]++; a[i][2]++; a[4][j]++; a[4][2]++; } char brancos[12]=""; // reservar uma posição para '\0' 83 Resolução do 3.12 char msg[5][12]= {"Ate 20","De 21 a 30","De 31 a 40", "Acima de 40","Total"}; printf("\n%11s | Mas | Fem | Total\n", brancos); for (i=0; i<5; i++){ printf("-------------------------------\n"); printf("%11s | %3d | %3d | %3d \n", msg[i],a[i][0],a[i][1],a[i][2]); } getch(); } 84 Resposta do 3.12 Digite a quantidade de alunos: 3 Digite idade e sexo(1 ou 2): 20 1 Digite idade e sexo(1 ou 2): 32 2 Digite idade e sexo(1 ou 2): 41 1 85 Resposta do 3.12 | Mas | Fem | Total --------------------------------------------- Ate 20 | 1 | 0 | 1 --------------------------------------------- De 21 a 30 | 0 | 0 | 0 --------------------------------------------- De 31 a 40 | 0 | 1 | 1 --------------------------------------------- Acima de 40 | 1 | 0 | 1 --------------------------------------------- Total | 2 | 1 | 3 86 Variáveis compostas heterogêneas • Variáveis compostas heterogênas em C são conhecidas sob o nome de “struct” (estrutura). • Uma struct em C é um tipo estruturado, equivalente a um registro em outras linguagens (record), que contém uma série de varáveis de tipos diferentes. • Definindo uma struct: • Sintaxe: struct nome { tipo variável_1; tipo variável_2; /* outras variáveis */ }; 87 Estruturas (structs) • As estruturas são utilizadas para agrupar diferentes tipos de variáveis sob um mesmo nome. • Uma estrutura deve ser definida (declarada) antes da rotina main. • Exemplo: struct data { int dia; int mes; int ano; }; • Deve-se usar "; "para finalizar a definição da struct. 88 Exercício struct01 /* Escrever um programa para definir uma estrutura contendo uma data com dia, mês e ano. Imprimir a data. */ #include <stdio.h> struct data { int dia; int mes; int ano; }; main (){ struct data hoje; hoje.dia = 23; hoje.mes = 9; hoje.ano = 2012; 89 Exercício struct01 printf("Hoje eh %d/%d/%d \n", hoje.dia, hoje.mes, hoje.ano); system ("pause"); } Resultados obtidos: Hoje eh 23/9/2012Press any key to continue . . . 90 Comando typedef • O comando typedef permite ao programador definir um novo nome para um determinado tipo. • Sintaxe: typedef nome_atual novo_nome; • Exemplo: typedef int inteiro; • Dessa forma em vez de int podemos usar inteiro. Exemplo: inteiro x, y; // em lugar de int x, y; 91 Exemplo typedef #include <stdio.h> // O typedef tem de ser usado antes do main typedef int inteiro; typedef float decimal; main (){ inteiro x = 1; decimal y = 1.5; printf("%d %.1f\n", x, y); system ("pause"); } 92 Usando typedef com struct • Exemplo: typedef struct data { int dia; int mes; int ano; } Data; // novo nome da struct data • Assim podemos usar em main: Data hoje; // dispensa o uso da palavra struct 93 Exercício struct03 Escrever um programa para criar um array contendo as informações de N produtos. Cada produto terá as seguintes informações: código, nome e preço. Listar os N produtos. 94 Alocação na memória • Vejamos como deverá ficar a distribuição dos dados na memória: • Cada elemento do vetor a ser criado deverá ter os três sub-campos: código, nome e preço. 95 Código Nome Preço Código Nome Preço Código Nome Preço ... itens[0] itens[1] itens[2] ... Exercício struct03 #include <stdio.h> typedef struct { int codigo; char nome[20]; float preco; } Produto; main(){ int i, n; Produto itens[20]; printf("Digite o valor de n:\n"); scanf("%d", &n); for (i=0; i<n; i++){ printf("\nDigite o codigo: "); scanf("%d%*c", &itens[i].codigo); // eliminar o ‘\n’ do buffer 96 Exercício struct03 printf("Digite o nome: "); gets(itens[i].nome); printf("Digite o preco: "); scanf("%f", &itens[i].preco); } printf("\nLista dos produtos:\n"); for (i=0; i<n; i++) printf("%d \t%s \t%.2f\n", itens[i].codigo, itens[i].nome, itens[i].preco); system("pause"); } 97 Respostas de struct03 Digite o valor de n: 2 Digite o codigo: 111 Digite o nome: batata Digite o preco: 4.50 Digite o codigo: 222 Digite o nome: tomate Digite o preco: 3.55 Lista dos produtos: 111 batata 4.50 222 tomate 3.55 Press any key to continue . . . 98 Exercício struct04 Ler os dados necessários para a criação de um array de estruturas para N alunos, onde para cada aluno tem: matrícula, nome e as notas de 5 avaliações. Imprimir para cada aluno, seus dados, suas notas e a média obtida. 99 Exercício struct04 #include <stdio.h> typedef struct{ int mat; char nome[20]; float nota[5]; float med; } Aluno; main(){ int i, j, n; float s; Aluno alu[10]; printf("Digite o valor de n:\n"); scanf("%d", &n); for (i=0; i<n; i++){ printf("Digite a matricula: "); scanf("%d%*c", &alu[i].mat); printf("Digite o nome: "); gets(alu[i].nome); printf("Digite as notas: "); s = 0; for (j=0; j<5; j++){ scanf("%f", &alu[i].nota[j]); s = s + alu[i].nota[j]; } alu[i].med = s / 5; } 100 Exercício struct04 printf("\nMedias obtidas:\n"); for (i=0; i<n; i++) printf("%d %s \t%.1f\n", alu[i]. mat, alu[i].nome, alu[i].med); printf("\n"); system("pause"); } 101 Resposta do struct04 Digite o valor de n: 2 Digite a matricula: 1111 Digite o nome: Pedro da Silva Digite as notas: 5 8 7 3.5 9 Digite a matricula: 2222 Digite o nome: Maria Silva Digite as notas: 7 8 5.5 9 4 Medias obtidas: 1111 Pedro da Silva 6.5 2222 Maria Silva 6.7 Press any key to continue . . . 102 Ponteiros • Um ponteiro nada mais é do que uma variável que guarda o endereço de uma outra variável. • A declaração de ponteiros é feita da seguinte forma: tipo_variável *nome_ponteiro; • Onde: tipo_variável: define o tipo de variável cujo endereço deverá ser armazenado. *: indica que se trata de um ponteiro. nome_ponteiro: define o nome do ponteiro. • Exemplos: int *p; float *v; 103 Ponteiros • Um ponteiro não pode armazenar um valor qualquer a não ser um endereço de memória. • Para se atribuir um endereço de variável a um ponteiro, usa-se o operador &. • Exemplo: int *p1, x; x = 15; p1 = &x; // p1 recebe o endereço de x printf(“%d %d”,x, *p1); // imprime 15 15 • Obs.: int *p; // p não contém um endereço 104 Ponteiros • Um ponteiro (= apontador = pointer) é um tipo especial de variável que armazena endereços. Um ponteiro pode ter o valor especial NULL que não é o endereço de lugar algum. A constante NULL está definida no arquivo cabeçalho “stdlib.h” e seu valor é 0 na maioria dos computadores. • O significado de *p é o valor da variável apontado por p. • A definição de um ponteiro não atribui um endereço. • Por exemplo, se x é uma variável e o conteúdo de p é igual a &x então *p é o mesmo que x. 105 Exemplo: ponteiroInicial main(){ int *z, u; z = &u; printf("Digite um valor inteiro\n"); scanf("%d", z); printf("Valor digitado = %d\n", *z); printf("Valor de U = %d\n", u); u = 7; printf("Valor de U = %d\n", *z); getch(); } /* Digite um valor inteiro 50 Valor digitado = 50 Valor de U = 50 Valor de U = 7 */ 106 Ponteiros • Podemos manipular uma variável com o uso do seu nome ou com o uso de um ponteiro que aponta para ela. • Exemplo: int *t, x = 5; t = &x; // t aponta para x x = x + 3; // manipula x usando o nome // x = 8 *t = *t * 2; // manipula x através do ponteiro t // x = 16 107 Ponteiros • Existem diversos tipos de ponteiros. Para cada tipo de variável existe um tipo de ponteiro específico. • Exemplos: int x=2, y=5, c; // definindo variáveis para esse exemplo int *p; // ponteiro para inteiro float *p1; // ponteiro para float char *t; // ponteiro para char int **q; // q é um ponteiro para um ponteiro de inteiro p = &x; // p aponta para x q = &p; // q aponta para p e *p aponta para x c = **q + y; // equivale c = x + y; 108 Ponteiros • Manipulando ponteiros: x y int x[10] = {4, 12, 23, 5, -6, 8, 20, 26, 14, 7}; int y[9] = {17, 6, 18, 9, 10, 15, 8, 20, 3}; int *p1, *p2; p1 = &x[0]; p2 = &y[0]; p1 += 2; // p1 avança 2 posições p1 = p2; // p1 passa a apontar para o vetor y 4 12 23 0 -6 8 20 56 27 7 0 1 2 3 4 5 6 7 8 9 109 17 6 18 9 10 15 8 20 3 Ponteiros • Manipulando ponteiros: x y int *p1, *p2; p1 = &x[0]; p2 = &y[0]; *p1 = *p1 + *p2; // x[0] = x[0] + y[0] p1++; // p1 avança uma posição x[1] *p1 += 3; // x[1] = x[1] + 3; 4 12 23 0 -6 8 20 56 27 7 0 1 2 3 4 5 6 7 8 9 110 17 6 18 9 10 15 8 20 3 Usando Ponteiros // Usando scanf com ponteiros main(){ int x, y, *p1, *p2; p1 = &x; p2 = &y; printf("Digite 2 valores\n"); scanf("%d %d", p1, p2); printf("x = %d y = %d\n", x, y); getch(); } 111 Ponteiro e Referência• Uma referência consiste em um nome alternativo para uma variável, ela tem o mesmo endereço de memória. Ela é identificada com o operador & na frente do nome da variável. Em C++ existe um uso mais ampliado de referência. No caso de C usa-se referência na chamada de funções como no caso de scanf e na captura de endereços de variáveis. • Apesar dos programadores em geral reconhecerem nos ponteiros o principal ponto de dificuldade no aprendizado da linguagem C, sua utilidade é incontestável. Com ponteiros o programador pode otimizar o gerenciamento da memória, reutilizando espaços alocados para variáveis, compartilhando espaço entre variáveis e solicitando ou liberando memória dinamicamente. Além disso, muitas aplicações têm sua performance otimizada em termos de velocidade quando se usam ponteiros (Profª Isabel Harb Manssour). 112 Exercício ponteiro01 // ponteiro01 // imprimir uma variável através de um ponteiro. #include <stdio.h> main(){ int *p, x; x = 5; p = &x; printf("Valor = %d\n", *p); getch(); } 113 Resposta de ponteiro01 Valor = 5 114 Ponteiros e arrays • Como os elementos de um array têm endereços consecutivos e como um ponteiro para esse array aponta para o primeiro elemento do array, podemos percorrer esse array da seguinte maneira: int *p; int i; int x[10] = {14, 5, 3, 4, 20, 7, -8, 12, 15, 2}; p = &x[0]; // endereço do primeiro elemento for (i = 0; i < 10; i++){ printf(“%d “, *p); // imprime o valor apontado por p p++; // incrementa o ponteiro para a próxima posição } // inteira 115 Exercício ponteiro02 /* Definir um vetor e usar um ponteiro para imprimir o mesmo. */ #include <stdio.h> main(){ int *p, i; int x[10] = {14, 5, 3, 4, 20, 7, -8, 12, 15, 2}; p = &x[0]; printf("Array dado:\n"); for (i = 0; i < 10; i++){ printf("%d ", *p); p++; } getch(); } 116 Resposta de ponteiro02 Array dado: 14 5 3 4 20 7 -8 12 15 2 117 Exercício ponteiro03 // Definir um array e usando // ponteiro, imprimir o mesmo. main(){ int *p; int i; int x[10] = {14, 5, 3, 4, 20, 7, -8, 12, 15, 2}; p = &x[0]; printf("Array dado:\n"); for (i = 0; i < 10; i++) printf("%d ", p[i]); getch(); } Resposta obtida: Array dado: 14 5 3 4 20 7 -8 12 15 2 118 Ponteiros e arrays • Obtendo o endereço de um array: int *p1; int pontos[4] = {7, 3, 10, 8}; p1 = &pontos[0]; // pega o endereço ou então: p1 = pontos; // atribui o endereço do array • O uso do nome do array é uma referência ao mesmo, funciona como um ponteiro, porém não é igual, funciona como uma constante contendo o endereço do array. • Assim, podemos dizer que o nome de um vetor é um ponteiro de endereço constante. 119 Aritmética de ponteiros • A aritmética de ponteiros está limitada a quatro operadores: soma, subtração, incremento e decremento. • Outra limitação é que, no caso de soma, o outro operando além do ponteiro deve ser uma expressão (ou variável ou constante) inteira. • A subtração de dois ponteiros para um mesmo tipo de dado é uma operação válida, retornando o número de elementos entre os dois ponteiros. • A comparação entre dois ponteiros também é uma operação legal. 120 Aritmética de ponteiros • Se p1 e p2 são ponteiros do mesmo tipo: • p1 = p2; – Então, p1 aponta para o mesmo endereço apontado por p2. • *p1 = *p2; – Então, o conteúdo apontado por p1 passa a ser igual ao conteúdo apontado por p2. • p1++; // Faz p1 apontar para o endereço seguinte. • P1--; // Faz p1 apontar para o endereço anterior. 121 Aritmética de ponteiros • *(p1)++; // Incrementa o ponteiro e acessa *p1 • Exemplo de caso: • int x[] = {5, 3, 8, 2, 11, 10, 7}; • int *p = &x[0]; // ????? • *p++; // O operador ++ tem maior prioridade que *, // mas por estar depois, acessa *p e depois // incrementa o ponteiro. • (*p)++; // Incrementa o conteúdo apontado por p • *(p++); Acessa *p e depois incrementa o ponteiro. O ++ está colocado depois. 122 Exercício ponteiro06 main(){ int x[10] = {4, 12, 23, 5, -6, 8, 20, 26, 14, 7}; int *p1, i; p1 = &x[0]; printf("Vetor inicial:\n"); for (i=0; i<10; i++) printf("%d ", x[i]); printf("\n"); printf("p1 = &x[0]\n"); printf("\nInicio: \t\tx[0] = %d \t*p1 = %d", x[0],*p1); *(p1)++; // incrementa o ponteiro e depois imprime o // conteúdo apontado por p1 123 Exercício ponteiro06 printf("\nTeste 1 [*(p1)++]: \tx[0] = %d \t*p1 = %d", x[0],*p1); *p1++; // incrementa o ponteiro e depois imprime o conteúdo printf("\nTeste 2 [*p1++]: \tx[1] = %d \t*p1 = %d", x[1],*p1); (*p1)++; // incrementa o conteúdo apontado por p1 printf("\nTeste 3 [(*p1)++]: \tx[2] = %d \t*p1 = %d", x[2],*p1); getch(); } 124 Exercício ponteiro06 Testes efetuados: Vetor inicial: 4 12 23 5 -6 8 20 26 14 7 p1 = &x[0] Inicio: x[0] = 4 *p1 = 4 Teste 1 *(p1)++ x[0] = 4 *p1 = 12 Teste 2 *p1++ x[1] = 12 *p1 = 23 Teste 3 (*p1)++ x[2] = 24 *p1 = 24 125 Exercício ponteiro04 /* Fazer uma variável ser incrementada através de um ponteiro. */ #include <stdio.h> main(){ int *p, i, a; a = 5; p = &a; printf("Valores obtidos:\n"); for (i = 0; i < 10; i++){ printf("%d ", *p); *p += 2; } getch(); } Resposta obtida: Valores obtidos: 5 7 9 11 13 15 17 19 21 23 126 Referências • Apostila de Programação C (Internet) – CRUZ, Adriano Joaquim de Oliveira – UFRJ, 1997. • Curso de Linguagem C da UFMG (site - http://www.ead.eee.ufmg.br/cursos/C/). • Francisco A. C. Pinheiro, Elementos de Programação em C, Bookman, 2012. 127 Fim da parte 3 128
Compartilhar