• Nenhum resultado encontrado

Aula06-Modularização–ParteII

N/A
N/A
Protected

Academic year: 2021

Share "Aula06-Modularização–ParteII"

Copied!
6
0
0

Texto

(1)

Modularização – Parte II

Escopo de Variáveis

Escopo: conjunto de regras que determinam o uso e a validade das variáveis nas diversas partes do problema.

Na linguagem C, cada função é um bloco de código que pode ser acessado por qualquer declaração. Uma função pode chamar outras funções, mas o código que compreende o corpo de uma função (bloco entre {}) está escondido do resto do programa, ele não pode afetar nem ser afetado por outras partes do programa, a não ser que o código use variáveis globais.

Tipos básicos:

• Variáveis Locais • Parâmetros formais • Variáveis Globais

Variáveis Locais

São variáveis declaradas dentro de uma função ou de um bloco de código e seus escopos estão restritos ao bloco onde foram declaradas. Toda variável declarada entre um bloco { } só podem ser referenciadas dentro deste bloco e existem apenas durante a execução deste bloco.

As variáveis locais são criadas na entrada e destruídas na saída de um código. Exemplo: void func1() { int X; X=10; } void func2() { int X; X=-15; }

A variável X foi declarada duas vezes, uma em cada função e O X em func1() não tem relação com o X em func2(), pois cada X conhecido somente dentro do código que foi declarado.

Exemplo:

void linha(int x ); //protótipo da função linha void main()

{

int tamanho,i=100; // variável local da função main() printf("Digite o tamanho: ");

scanf("%d",&tamanho);

linha(tamanho); // chamada da função linha() system("pause");

}

void linha(int x) // definição da função linha() {

int i; // variável local da função linha() for(i=0;i<=x;i++)

printf("A"); // imprime o caracter “A” X vezes }

A variável i na função main() não é reconhecida pela função linha

Como as variáveis locais são criadas e destruídas a cada entrada e saída de um bloco, os seus conteúdos são perdidos quando o bloco é deixado. Isso significa que variáveis locais não podem reter os seus valores entre chamadas.

(2)

Parâmetros formais

Se uma função usa argumentos, ela deve declarar as variáveis que receberão valores daqueles argumentos. Estas variáveis são chamadas de parâmetros formais das funções e comportam-se como quaisquer outras variáveis locais dentro da função.

Exemplo:

void linha(int x) // definição da função linha() {

int i; // variável local da função linha() for(i=0;i<=x;i++)

printf("A"); // imprime o caracter “A” X vezes }

A variável x é declarada como inteiro no cabeçalho da função linha.

Variáveis globais

São conhecidas por todo programa e podem ser usadas em qualquer parte do código. Permanecem com seu valor durante toda execução do programa. São armazenadas em uma região fixa da memória própria para esse fim. Normalmente, são criadas declarando-as fora de qualquer função e podem ser acessadas por qualquer expressão, não importando em qual função esteja.

Exemplo:

void func1();// protótipo da função func1() void func2(); // protótipo da função func2 int cont; // declaração da variável global cont void main()

{

cont=100; // atribuição do valor 100 para a variável cont func1(); // chamada da função func1()

system("pause"); }

void func1() // definição da função func1() {

int temp; //declaração da variável local temp da função func1() temp=cont;

func2(); // chamada da função func2()

printf("\ncont igual = %d",cont); // imprime: cont é = 100 }

void func2() // definição da função func2() {

int cont; // declaração da variável local cont da função func2() for(cont=1;cont<10;cont++)

printf("*"); // imprime: ********* }

Neste programa, a variável global cont foi declarada antes da função main( ) e, embora não tenha sido declarada dentro da main() nem da func1( ), estas duas funções podem usá-la. Entretanto, func2( ) tem declarado uma variável local chamada cont. Quando se referencia a variável cont, func2( ) está se referenciando somente a sua variável local, não a global.

Se uma variável global e uma local tiverem o mesmo nome, todas as referências àquele nome de variável dentro da função onde a variável local é declarada se referirão somente a ela e não terão efeito na variável global.

Variáveis globais são muito úteis quando o mesmo dado é usado em muitas funções no seu programa. Entretanto, deve-se evitar a utilização de variáveis globais desnecessárias por três razões:

• Ocupam a memória durante todo o tempo em que o programa está executando, não somente quando necessário; • Torna uma função menos geral, porque ela vai depender de algo que deve ser definido fora dela;

(3)

Passagem de parâmetros entre funções

Os argumentos podem ser passados para as funções de duas maneiras. A primeira é chamada de passagem por valor que copia o valor de um argumento para um parâmetro formal de uma função. A segunda é chamada por referência (ou passagem de parâmetro por referência), onde o endereço de um argumento é copiado no seu parâmetro.

Passagem por valor

A passagem por valor (ou passagem de parâmetro por cópia) copia o valor do argumento na chamada da função para um parâmetro declarado na função. Portanto, é uma cópia do valor do argumento que é passado para uma dada função. O que ocorre dentro da função não terá efeito na variável usada na chamada. O valor de um argumento é copiado para o parâmetro formal da função e as alterações no processamento não alteram as variáveis usadas para chamar a função.

Exemplo:

int quad(int x); // protótipo da função quad( ) void main()

{

int t=10; // declaração e inicialização da variável local t

printf("%d %d",quad(t),t); // chama a função quad( ) e imprime 100 10 system("pause");

}

int quad(int x) // definição da função quad( ) e declaração do parâmetro x {

x=x*x; return(x); }

O valor do argumento passado para a função quad( ), 10, é copiado no parâmetro x. Quando a atribuição x = x * x é executada, modifica somente a variável local x. A variável t, usada para chamar quad( ), ainda terá o valor 10. Por isso o resultado será 100 10.

Ponteiros

Para alterar as variáveis que são passadas para uma função, seus parâmetros formais devem ser declarados como ponteiros.

Ponteiro é uma variável que contém um endereço de memória, ou seja, é uma variável que guarda um endereço de memória de outro objeto.

Endereço de memória é cada uma das posições de memória, sequencialmente numeradas, que pode ser dividida a memória do computador. Qualquer variável, de qualquer tipo, é posicionada em uma única posição ( 1 byte por posição).

São usados para o gerenciamento de dados na memória disponível, para acessar dados e funções membros de classe e para a passagem de variáveis por referência para funções.

Uma variável que vai armazenar um ponteiro deve ser declarada como tal. Uma declaração de ponteiro consiste em um tipo base, um * e o nome da variável. A forma geral para declaração de uma variável ponteiro é:

tipo *<nome da variável>;

Onde o tipo pode ser qualquer tipo válido da linguagem C e o nome da variável é o nome da variável ponteiro. O tipo base do ponteiro define qual tipo de variáveis o ponteiro pode apontar.

As declarações abaixo criam um ponteiro caractere e dois ponteiros inteiros.

• char *p;

• int *temp, *início;

Existem dois operadores especiais de ponteiro: o & e o *.

O & é um operador unário que retorna o endereço de memória do seu operando. Por exemplo,

(4)

Coloca em end_cont o endereço de memória da variável cont. Esse endereço é a localização interna da variável no computador. Ele não faz nada com o valor de cont.

Para entender melhor essa atribuição, assuma que a variável cont esteja localizada no endereço 2000. Então, após a atribuição, end_cont terá o valor de 2000.

O operador * é o complemento do operador &. Ele é um operador unário que retorna o valor da variável localizada no endereço que o segue. Por exemplo, se end_cont contém o endereço de memória da variável cont, então:

• val = *end_cont;

Colocará o valor de cont em val. Supondo que a variável cont originalmente tem o valor 100, então val terá o valor de 100, porque este é o valor armazenado no endereço 2000, que é o endereço de memória que foi atribuído a end_cont. Neste caso, então, a declaração pode ser lida como “val recebe o valor que está no endereço end_cont”.

Exemplo:

#include <stdio.h> void main() {

int *end_cont, cont, val; cont = 100;

end_cont= &cont; //pega o endereço de cont

val = *end_cont; //pega o valor armazenado no endereço end_cont printf("%d", val); //exibe 100

system("pause"); }

Infelizmente, o sinal de multiplicação e o sinal “valor no endereço” são os mesmos, porém, esses operadores não se relacionam um com o outro. Tanto & como * têm precedência maior que todos os outros operadores aritméticos, exceto o menos unário, com o qual eles se igualam.

Obs: operadores unários são aqueles usados em expressões com apenas 1 operando, exemplo: ++i e i--.

Criando uma chamada por referência

Como o C só faz chamadas por valor, é possível usar os parâmetros formais à vontade dentro da função, sem a preocupação de estar alterando os valores dos argumentos que foram passados para a função. Porém, pode-se querer mudar os valores fora da função. Ainda que a convenção de passagem de parâmetros da linguagem C seja a chamada por valor, é possível criar uma chamada por referência passando-se um ponteiro para o argumento. Esta maneira é chamada por referência (passagem de parâmetro por referência), onde o endereço de um argumento é copiado no seu parâmetro.

Este tipo de passagem de parâmetros para uma função ocorre quando alterações nos parâmetros formais, dentro da função, alteram os valores dos parâmetros que foram passados para a função; neste tipo de chamada, não se passa para a função os valores das variáveis, mas sim suas referências (a função usa as referências para alterar os valores das variáveis fora da função). Para usar a função é necessário colocar um & na frente das variáveis que estiverem sendo passadas para a função.

1. #include <stdio.h>

2. void troca (int *a,int *b); //declaração dos ponteiros a e b

3. void main ()

4. {

5. int num1,num2; // declaração das variáveis locais num1 e num2 da main( )

6. num1=100;

7. num2=200;

8. troca (&num1,&num2); //A função troca passando os endereços das variáveis num1 e num2

9. printf ("\n\nEles agora valem %d %d\n",num1,num2);

10. system("pause"); 11. }

12. void troca (int *a,int *b) // definição da função troca( )

13. {

14. int temp; // declaração da variável local temp da função troca( )

15. temp=*a;

16. *a=*b;

17. *b=temp;

(5)

Na linha 2 são declarados o protótipo da função troca( ). Na linha 8, a função troca é chamada e os endereços das variáveis num1 e num2 são passados (copiados) para os ponteiros a e b, ou seja, a variável a recebe o endereço da variável num1 e a variável b o endereço de num2.

Na linha 15, o valor da variável num1, armazenada no endereço contido no ponteiro a (&num1) é atribuído à variável temp, na linha 16, o valor da variável apontada pelo ponteiro b (num2) é atribuído à variável apontada pelo ponteiro a e, finalmente, o valor da variável apontada pelo ponteiro b recebe o valor de temp.

Através do operador * o conteúdo apontado pelos ponteiros é acessado e modificado e, estes conteúdos nada mais são que os valores armazenados em num1 e num2, que, portanto, estão sendo modificados!

Na função scanf() as variáveis chamadas também são precedidas pelo operador de endereços &. Esta função usa chamada por referência porque ela precisa alterar as variáveis que são passadas para ela! Ela lê uma variável e, portanto, precisa alterar seu valor. Assim, o endereço da variável a ser modificada é passado para a função com o operador & sendo colocado na frente dos argumentos da função scanf( ), que recebem valores.

Exercícios

Veja como você está.

1. (Variáveis locais e globais.) O que é impresso na tela pelo seguinte programa?

#include <stdio.h> int x=0; void main() { int i, x=1; printf("%d ",x); for(i=0; i<4; i++) { int x=2; printf("\n%d ",x); } printf("\n%d ",x); system("pause"); }

2. (Variáveis locais e globais.) O que é impresso na tela pelo seguinte programa?

#include <stdio.h> int w=1,x=2,y=3,z=4; void teste (int y) { int z=6; printf("\n%d %d %d %d ", w,x,y,z); } main() { int x=7; teste(5); teste(x); printf("\n%d %d %d %d.", w,x,y,z); system("pause"); }

3. (Variáveis locais e globais.) O que é impresso na tela pelo seguinte programa?

#include <stdio.h> int w=1,x=2,y=3,z=4; void teste(int y) { int z=6; printf("\n%d %d %d %d", w,x,y,z); z=y;

(6)

} main() { int x=7, w=8; teste(5); printf("\n%d %d %d %d.", w,x,y,z); system("pause"); }

4. Modifique o programa abaixo corrigindo os erros existentes na passagem de parâmetros. Depois de corrigido, o que será apresentado na tela?

#include <stdio.h>

void teste( float x, float *v1, float v2 ) { *v1 = x * 10; v2 = x / 10; } void main() {

float num = 15, mult, div; teste( num, mult, &div );

printf ( "\n%f * 10 = %f", num, mult ); printf ( "\n%f / 10 = %f", num, div ); system("pause");

}

5. Modifique o programa abaixo corrigindo os erros existentes na passagem de parâmetros. Depois de corrigido, o que será apresentado na tela?

#include <stdio.h>

void troca(int *a, int *b) { int aux; aux = *a; *a = *b; *b = aux; } void main() { int x = 10, y = 20;

printf("Valor de x: %d e y:%d antes da funcao\n",x, y); troca(x,y);

printf("Valor de x: %d e y:%d depois da funcao\n",x, y); system("PAUSE");

Referências

Documentos relacionados

de Socioeducação, que a partir de uma gestão_ democrática instaurada em consonância com os instrumentos-metodológicos de atendimento socioeducativo (Estudo de Caso - uma

Após os ensaios das juntas soldadas, também foi realizado o ensaio de tração com uma das hastes de 80 mm, com o comprimento útil do corpo de prova de 20 mm, visto na Figura 9a e

Escreva um programa que receba um número inteiro representando a quantidade total de segundos e, usando passagem de parâmetros por referência, converta a quantidade informada

• O mecanismo de informar os valores a serem processados pela função chama-se passagem de parâmetros... • Mas, como os parâmetros de uma função são variáveis locais,

Ausência de gás Ausência de gás Teste negativo Teste negativo Teste positivo para coliforme. Teste positivo

As frequências alélicas HPA variam muito entre grupos populacionais, e, portanto, a seleção de doadores genotipados para os principais polimorfismos dos

Em suas tradições que foram meticulosamente registrada por eruditos muçulmanos, o profeta Muhammad, que Deus o louve, encorajou seus seguidores a buscar conhecimento 4.. Disse

• As variáveis do protótipo da função que recebem dados de entrada ou que retornam resultados (ou dados de saída) são designadas por parâmetros formais. Estes