Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
1 LINGUAGEM E TÉCNICA DE PROGRAMAÇÃO I Profa. Gisele Busichia Baioco gisele@ft.unicamp.br Modularização de Programas Subprogramas em C Parte 3 – Parâmetros: Vetores e Estruturas 1 Vetores como Parâmetros Seja o seguinte vetor: int meuvetor[50]; Para passar o vetor vet como parâmetro real em uma função C, por exemplo, da função func(), tem-se que ter o parâmetro formal de func() declarado de uma das três maneiras apresentadas a seguir: void func(int vet[50]) ou void func(int vet[]) ou void func(int* vet) Nos três casos, tem-se em func() um int* chamado vet. Ao passar um vetor para uma função, na realidade se está passando um ponteiro. Nesse ponteiro é armazenado o endereço do primeiro elemento do vetor. Isto significa que não é feita uma cópia, elemento a elemento do vetor. Isso faz com que se possa alterar o valor dos elementos do vetor dentro da função. A chamada da função func() fica: func(meuvetor); No caso de strings vale a mesma regra de vetores, uma vez que uma string em C é um vetor de char. Um exemplo pode ser a implementação da função StrCpy(), mostrado a seguir: 2 #include <stdio.h> void StrCpy(char*, char*); main() { char str1[100], str2[100], str3[100]; printf ("Entre com uma string: "); gets (str1); StrCpy(str2, str1); StrCpy(str3,"Voce digitou a string "); printf ("\n%s%s", str3, str2); } void StrCpy (char* destino, char* origem) { while (*origem != '\0') { *destino=*origem; origem++; destino++; } *destino='\0'; } 2 Estruturas como Parâmetros 2.1 Passando membros de uma estrutura para funções Ao passar um membro de uma variável estrutura como parâmetro real para uma função, está-se passando o valor do membro. Seja a seguinte estrutura: struct { char x; int y; float z; char s[10]; } aba; Supondo a existência das funções func1(), func2(), func3(), func4() e func5(), pode- se passar cada elemento para uma função, da seguinte maneira: func1(aba.x); /* passa o valor do caractere x */ func2(aba.y); /* passa o valor do inteiro y */ func3(aba.z); /* passa o valor do float z */ func4(aba.s); /* passa o endereço da string s */ func5(aba.s[2]); /* passa o valor do caractere s[2] */ Supondo a existência das funções func6(), func7(), func8(), func9() e func10(), pode- se também passar o endereço de um membro individual de uma estrutura, de modo a obter uma passagem de parâmetro por referência, da seguinte maneira: func6(&aba.x); /* passa o endereço do caractere x */ func7(&aba.y); /* passa o endereço do inteiro y */ func8(&aba.z); /* passa o endereço do float z */ func9(aba.s); /* passa o endereço da string s */ func10(&aba.s[2]); /* passa o endereço do caractere s[2] */ 3 Deve-se notar que o operador & precede o nome da variável estrutura e não o nome do membro individual. Além disso, observa-se que o nome s do membro string já significa um endereço, de modo que o operador & não é necessário naquela linha de código. 2.2 Passando estruturas inteiras para funções Quando uma variável estrutura é usada diretamente como parâmetro real de uma função, C passa a estrutura inteira usando o método padrão da chamada por valor. Exemplo: #include <stdio.h> /* definição do tipo estrutura */ struct exemplo { int a, b; char c; }; void f(struct exemplo); main() { struct exemplo meuex; meuex.a = 1000; f(meuex); } void f(struct exemplo ex) { printf("%d", ex.a); } Este programa imprimirá 1000 na tela. Como foi dito anteriormente a passagem da estrutura é feita por valor, ou seja, a estrutura que está sendo passada vai ser copiada, membro por membro, para o parâmetro formal da função. Isso Mais uma vez pode-se conseguir uma passagem de parâmetro por referência usando ponteiros e passando para a função um ponteiro para a estrutura. 2.3 Ponteiros para estruturas Declara-se ponteiros para estruturas colocando um * na frente do nome da variável estrutura. Exemplo: struct ender { char nome[30]; char rua[40]; char cidade[20]; char estado[3]; unsigned long int cep; }; struct ender* ender_ponteiro; 4 Desse modo, declara-se ender_ponteiro como sendo um ponteiro para a estrutura ender. Os ponteiros para uma estrutura funcionam como os ponteiros para qualquer outro tipo de dados no C. Para usá-lo, haveria duas possibilidades: 1) Apontar para um variável estrutura já existente: para obter o endereço de uma variável de estrutura, coloca-se o operador & antes do nome da variável estrutura. Considerando o exemplo anterior: struct ender meuender; struct ender* ender_ponteiro; A linha de código seguinte coloca o endereço de meuender dentro de ender_ponteiro, ou seja, ender_ponteiro passa a apontar para meuender: ender_ponteiro = &meuender; 2) Alocar memória dinamicamente: usando a função malloc() pode-se alocar memória para a estrutura ponteiro e depois utilizar free() para liberar a memória. Considerando o exemplo anterior, a linha de código seguinte aloca memória para a variável estrutura ender_ponteiro: ender_ponteiro = (struct ender*) malloc (sizeof(struct ender)); Para alocar memória para vários endereços, ou seja, supondo um vetor de endereços, para 10 endereços faz-se: ender_ponteiro = (struct ender*) malloc (10 * sizeof(struct ender)); Para liberar a memória alocada, faz-se: free(ender_ponteiro); Em qualquer uma das possibilidades de uso de ponteiros para estruturas apresentadas anteriormente, para fazer referência ao elemento cep de ender_ponteiro, escreve-se: (*ender_ponteiro).cep; Os parênteses são necessários em torno do ponteiro, porque o operador de seleção (.) tem prioridade mais alta que o operador *. Para evitar confusão existe um operador especial chamado membro de ponteiro de estrutura ou flecha ->. Esse operador tem a mesma prioridade que o operador de seleção. Assim, a expressão anterior poderia ser escrita com a seguir: ender_ponteiro -> cep Em funções, para obter a passagem de parâmetro por referência, basta declarar o parâmetro formal como ponteiro: func(struct ender* ender_ponteiro); E chamar a função usando o operador &: 5 struct ender meuender; func(&ender); Exemplo: #include <stdio.h> /* definição do tipo estrutura */ struct exemplo { int a, b; char c; }; void f(struct exemplo*); main() { struct exemplo meuex; meuex.a = 1000; f(&meuex); } void f(struct exemplo* ex) { printf("%d", ex->a); } Este programa imprimirá 1000 na tela. 3 Exercícios de Fixação 1. Fazer um programa C que, a partir de um vetor de 100 inteiros, possibilite: • a digitação dos valores no vetor; • imprimir o valor do somatório de seus itens; • imprimir a média dos valores fornecidos; • substituir por zero todos os valores negativos; • imprimir a quantidade de número negativos; • imprimir a quantidade de número positivos. Para cada funcionalidade do programa deve ser implementada uma função. 2. Fazer um programa C que realiza o cadastro de contas bancárias com as seguintes informações: número da conta, nome do cliente e saldo. O banco permitirá o cadastramento de apenas 15 contas e não pode haver mais de uma conta com o mesmo número. Criar o menu de opções a seguir: 1. Cadastrar contas 2. Visualizar todas as contas de um determinado cliente 3. Excluir a conta com o menor saldo (supondo a não existência de saldos iguais) 4. Sair As opções 1, 2 e 3 devem ser implementadas utilizando funções. Verificar a possibilidade de criar funções para outras funcionalidades que sejam utilizadas em mais de um local no programa, por exemplo, função para buscar uma conta.