Ferramentas do usuário

Ferramentas do site


ponteiros
no way to compare when less than two revisions

Diferenças

Aqui você vê as diferenças entre duas revisões dessa página.


ponteiros [2023/09/12 16:14] (atual) – criada - edição externa 127.0.0.1
Linha 1: Linha 1:
 +====== Ponteiros ======
  
 +===== Conceitos =====
 +
 +A Linguagem C implementa o conceito de ponteiro. Um ponteiro é um [[tipos_dados|tipo de dado]] como [[tipos_dados|int]], [[tipos_dados|char]] ou [[tipos_dados|float]]. A diferença do ponteiro em relação aos outros [[tipos_dados|tipos de dados]] é que uma variável que seja ponteiro irá guardar um **''endereço de memória''**.
 +
 +Através deste endereço pode-se acessar a informação, dizendo que a variável ponteiro ''aponta'' para uma posição de memória. O maior problema em relação ao ponteiro é entender que quando se está trabalhando com o seu valor (endereço de memória) e quando se está trabalhando com a informação apontada por ele (conteúdo).
 +
 +Por ser um endereço deve-se especificar que tipo de variável será encontrado na posição apontada pelo ponteiro. Assim é informado que foi criado um ponteiro para um [[tipos_dados|inteiro]] (no endereço indicado pelo ponteiro será encontrado um valor [[tipos_dados|inteiro]] e o compilador deve gerar código para tratar este endereço). Ponteiros podem ser utilizados para uma estrutura ou um ponteiro para um arquivo. 
 +
 +===== Definição de Ponteiros =====
 +|
 +Sintaxe:
 +
 +[[tipos_dados|tipo]] * [[variavel_definicao|nome_variável]];
 +
 +
 +----
 +
 +Para se definir uma [[variavel_definicao|variável]] do tipo ponteiro, deve-se colocar um **asterisco** (''*'') na frente de uma [[variavel_definicao|definição]] normal daquele [[tipos_dados|tipo]]. O ''asterisco'' deve ser colocado entre o [[tipos_dados|tipo]] e o [[variavel_definicao|nome da variável]].
 +
 +
 +A definição de um ponteiro é somente a definição de um espaço de memória que conterá outro endereço. Portanto ao definir um ponteiro somente é [[alocacao_memoria|alocado]] o espaço do endereço e não do valor. Para utilizar um ponteiro, é preciso sempre inicializar o mesmo, ou seja, colocar um endereço válido para depois realizar o acesso.
 +
 +Veja o exemplo:
 +
 +<code c>
 +int main (void)
 +{
 +   int *piInteiro; /*ponteiro para inteiro */
 +   char *pcCaractere; /*ponteiro para um caractere */
 +   float *pfPontoFlutuante; /*ponteiro para um ponto flutuante */
 +   return 0;
 +}
 +</code>
 +
 +===== Uso de Ponteiros =====
 +
 +Um ponteiro pode ser utilizado de duas maneiras distintas. Uma maneira é trabalhar com o endereço armazenado no ponteiro e outro modo é trabalhar com a área de memória apontada pelo ponteiro. É importantíssimo diferenciar estes dois modos para não causar problemas.
 +
 +Quando se quiser trabalhar com o endereço armazenado no ponteiro, utiliza-se o seu nome **sem** o asterisco na frente. Sendo assim qualquer operação realizada será feita no endereço do ponteiro.
 +
 +Na maioria dos casos, se deseja trabalhar com a memória apontada pelo ponteiro, alterando ou acessando este valor. Para isto **deve-se** colocar um asterisco antes do nome do ponteiro. Quando isto for feito o compilador irá gerar o código para acessar a memória apontada e não com o valor do endereço.
 +
 +<code c>
 +/* programa_ponteiro01.c */
 +
 +#include <stdio.h>
 +
 +int main(void)
 +{
 +   int * piA; /* ponteiro para inteiro */
 +   int iVariavel;
 +
 +   iVariavel = 10;
 +
 +   piA = &iVariavel; /* O ponteiro piA recebe o endereço de memória da variável iVariavel */
 +
 +   printf("\nEndereço: %d", piA);
 +   printf("\nValor   : %d", *piA);
 +
 +   *piA = 1975; /* Indica que endereço de memória, representado pelo ponteiro, irá receber o valor 1975 */
 +
 +   printf("\nValor alterado: %d", iVariavel);
 +   printf("\nValor         : %d", *piA);
 +
 +   return 0;
 +}
 +</code>
 +
 +
 +===== Parâmetros de Saída =====
 +
 +Para fazer a saída de valores via parâmetros de função, deve-se definir este parâmetro como sendo do tipo ponteiro. Na chamada da função deve-se colocar o endereço de uma variável local ou global neste parâmetro.
 +Para retornar um valor deve-se portanto utilizar o asterisco antes do nome do parâmetro, indicando assim que esta sendo mudando o valor naquele endereço passado como parâmetro.
 +
 +<code c>
 +/* programa_ponteiro02.c */
 +
 +#include <stdio.h>
 +
 +/* Indica que o último parâmetro é um ponteiro para inteiro. */
 +void soma (int iValorA, int iValorB, int *piValor)
 +{
 +  *piValor = iValorA + iValorB;
 +   return;
 +}
 +
 +int main(void)
 +{
 +   int iValor_a, iValor_b, iResultado;
 +
 +   printf("\nEntre com os valores:");
 +   scanf("%d %d", &iValor_a, &iValor_b);
 +
 +   /* Como está sendo passado o endereço de memória da variável (ponteiro), qualquer 
 +      alteração será realizada na memória. */
 +   soma(iValor_a, iValor_b, &iResultado);
 +   printf ("Soma : %d\n", iResultado);
 +   return 0;
 +}
 +</code>
 +
 +Exemplo trocando 2 valores:
 +<code c>
 +/* programa_ponteiro03.c */
 +
 +#include <stdio.h>
 +
 +void troca(int * piValor_a, int * piValor_b)
 +{
 +   int iAux;
 +   iAux = *piValor_a;
 +   *piValor_a = *piValor_b;
 +   *piValor_b = iAux;
 +   return;
 +}
 +
 +int main(void)
 +{
 +   int iValor_a, iValor_b;
 +   iValor_a = 10;
 +   iValor_b = 20;
 +
 +   troca(&iValor_a, &iValor_b);
 +
 +   printf("\nValor a = %d", iValor_a);
 +   printf("\nValor b = %d", iValor_b);
 +   return 0;
 +}
 +</code>
 +
 +===== Operações com Ponteiros =====
 +
 +Pode-se realizar as operações de soma e subtração do valor do ponteiro, ou seja, do endereço armazenado na variável.
 +
 +Um detalhe a ser observado é que esta soma estará condicionada ao tamanho do tipo que o ponteiro aponta. Suponha que exista um ponteiro para um inteiro, que ocupa 4 bytes na memória. Ao se somar uma unidade neste ponteiro (+ 1) o compilador interpretará que se deseja que some um valor que permita acessar o próximo inteiro e irá gerar código para somar 4 unidades no endereço do ponteiro.
 +
 +<code c>
 +/* programa_ponteiro04.c */
 +
 +#include <stdio.h>
 +int main(void)
 +{
 +   int *piInt;
 +   int iValor;
 +   char *pcChar;
 +   char cValor;
 +
 +   piInt = &iValor;
 +   pcChar = &cValor;
 +
 +   printf("Endereco de piInt  = %d\n", piInt);
 +   printf("Endereco de pcChar = %d\n", pcChar);
 +
 +   piInt++;
 +   pcChar++;
 +
 +   printf("Endereco de piInt  = %d\n", piInt);
 +   printf("Endereco de pcChar = %d\n", pcChar);
 +   return 0;
 +
 +</code>
 +
 +===== Ponteiros e Matrizes =====
 +
 +Quando é passado um vetor ou matriz como parâmetro, a Linguagem C coloca o endereço na pilha. Pode-se então definir o tipo do parâmetro como um ponteiro e acessar a matriz dentro da função como se fosse um ponteiro.
 +
 +<code c>
 +/* programa_ponteiro05.c */
 +
 +#include <stdio.h>
 +void imprime(int * piVet)
 +{
 +   int i;
 +   for (i=0; i < 5; i++)
 +   {
 +      /* Seria o equivalente:
 +         imprima vet[i];
 +         i++ */
 +      printf("\nConteudo na matriz na posicao %d=%d",i, *piVet);
 +      printf("\nEndereço de memória = %d", piVet );
 +      piVet++;
 +   }
 +   printf ("\n");
 +   return;
 +}
 +
 +int main(void)
 +{
 +   int matriz[5] = {1, 2, 3, 4, 5};
 +   printf("\nTamanho da matriz = [%d]", sizeof(matriz));
 +   imprime(matriz);
 +   return 0;
 +}
 +</code>
 +
 +
 +===== Ponteiros e Strings =====
 +Acessar um vetor como ponteiro e vice-versa é muito comum quando é utilizado strings. Quando é definido um vetor de caracteres, pode-se acessar o mesmo através de um ponteiro para caractere. Este ponteiro estará sempre apontando para um único caractere da string e através de operações sobre o ponteiro (incremento ou decremento) pode-se caminhar no vetor.
 +
 +<code c>
 +/* programa_ponteiro06.c */
 +#include <stdio.h>
 +int main(void)
 +{
 +   char sNome[30] = "Marcos Aurelio";
 +   char *pcCaracter;
 +
 +   /* Aponta para o primeiro caractere da string ou vetor. */
 +   pcCaracter = (char *) &sNome; 
 +
 +   /* Pegando o tamanho da variável na memória e não o tamanho da matriz. */
 +   printf("\nTamanho da string = %d", sizeof(sNome));
 +   printf("\nEndereço da 1a. posicao = %d\n", pcCaracter );
 +   while (*pcCaracter != NULL)
 +   {
 +      putchar(*pcCaracter); /* Seria o equivalente: */
 +      pcCaracter++;         /* imprima sNome[i];
 +                               i++; */
 +   }
 +   putchar ('\n');
 +   printf("\nEndereço da última posicao = %d", pcCaracter );
 +   return 0;
 +}
 +</code>
 +
 +===== Argumentos de Entrada =====
 +
 +De dentro de um programa C pode-se acessar a linha de comando que ativou o programa, permitindo assim passar valores para o programa na sua chamada. 
 +
 +Os valores passados para o programa são chamados de argumentos e pode-se acessá-los colocando-se dois parâmetros na definição da função [[main]]. O primeiro parâmetro deve ser do [[tipos_dados|tipo inteiro]] e conterá a quantidade de argumentos passados na linha de comando. É importante observar que o nome do programa é um argumento e portanto será contado como tal. Posto isto, vale dizer que sempre este parâmetro irá considerar o nome do programa como argumento.
 +
 +O outro parâmetro que deve ser colocado é um [[vetor_matriz|vetor]] de ponteiros. Cada ocorrência deste vetor será um ponteiro para uma [[strings|string]] contendo o argumento passado para o programa.
 +
 +<code c>
 +/* programa_ponteiro07.c */
 +#include <stdio.h>
 +
 +/* argc - Contém o número de argumentos passados. Será sempre pelo menos 1, pois o nome do 
 +          programa é sempre passado como 1º argumento.
 +   argv - Conterá os argumentos passados. Os argumentos são separados por um espaço em branco 
 +          ao ser passado na linha de comando. */
 +int main (int argc, char *argv[])
 +{
 +   int i;
 +
 +   printf ("Argumentos digitados\n");
 +   for (i=0; i < argc; i++)
 +   {
 +      printf ("Argumento %d - %s\n", i + 1, argv[i]);
 +   }
 +   return 0;
 +}
 +</code>
 +
 +===== Lista de funções =====
 +   * [[strstr]]
 +   * [[strtok]]
 +
 +
 + --- //[[marcos@laureano.eti.br|Marcos Laureano]] 2009/05/11 18:46//
ponteiros.txt · Última modificação: 2023/09/12 16:14 por 127.0.0.1