Ir ao conteúdo

Duvidas Ponteiros


hatosco

Posts recomendados

Postado

Estou com algumas duvidas sobre ponteiros, segue o codigo:


/* Teste de Ponteiros */



#include<stdio.h>

#include<stdlib.h>



int * aloca(unsigned int quantidade)

{

return (int *)malloc(sizeof(int)*quantidade);

}



int main(void)

{



int (*a)[3]; // Um ponteiro para vetores de 3 posições

int n, m;



a = aloca(2*3);//aloca matriz 2x3



a[0][0] = 1;

a[0][1] = 2;

a[0][2] = 3;

a[1][0] = 4;

a[1][1] = 5;

a[1][2] = 6;



printf("Valor de a[0][0] é %d\n", a[0][0]);

printf("Valor de a[0][1] é %d\n", a[0][1]);

printf("Valor de a[0][2] é %d\n", a[0][2]);

printf("Valor de a[1][0] é %d\n", a[1][0]);

printf("Valor de a[1][1] é %d\n", a[1][1]);

printf("Valor de a[1][2] é %d\n", a[1][2]);



/* Teste de Caracteres */



char (*palavras)[4] = {"Cachorro", "Gato" "Peixe", "Coelho", "Lagartixa"};



for(n = 0; n<10; n++)

{

printf("O nome é: %s\n", palavras[n]);

}

return 0;

}

- Ao compilar com o gcc resulta em:

teste_forum.c: In function ‘main’:

teste_forum.c:17: warning: assignment from incompatible pointer type

teste_forum.c:35: warning: initialization from incompatible pointer type

teste_forum.c:35: warning: excess elements in scalar initializer

teste_forum.c:35: warning: (near initialization for ‘palavras’)

teste_forum.c:35: warning: excess elements in scalar initializer

teste_forum.c:35: warning: (near initialization for ‘palavras’)

teste_forum.c:35: warning: excess elements in scalar initializer

teste_forum.c:35: warning: (near initialization for ‘palavras’)

Executando:

Valor de a[0][0] é 1

Valor de a[0][1] é 2

Valor de a[0][2] é 3

Valor de a[1][0] é 4

Valor de a[1][1] é 5

Valor de a[1][2] é 6

O nome é: Cachorro

O nome é: orro

O nome é:

O nome é: ome é: %s

O nome é: é: %s

O nome é: %s

O nome é: ,

O nome é: ,

O nome é:

O nome é:���H

- Compilando no g++:

teste_forum.c: In function ‘int main()’:

teste_forum.c:17: error: cannot convert ‘int*’ to ‘int (*)[3]’ in assignment

teste_forum.c:35: error: scalar object ‘palavras’ requires one element in initializer

Duvidas:

1) Como seria a correta declaração de retorno da função 'aloca' e como seria a correta conversão de tipo (cast) dentro da função 'aloca'? Preciso de uma solução utilizando int (*a)[3] porque é apenas um ponteiro para vetores de 3 posições. Tentei utilizar o cast e o retorno da função como int (*)[3] mas não dá certo também!

2) Na parte de strings porque é impresso um trecho do código?

Muito obrigado e Feliz Páscoa a todos!!!

Postado

A função aloca, quando é usada no seu exemplo


a = aloca(2*3);//aloca matriz 2x3

ela esta alocando um vetor 12 bytes, 2*6, ela vai retornar um ponteiro para um vetor de 6 inteiros.

Nunca tinha visto essa forma de declarar ponteiros:


int (*a)[3];

mas isso está me parecendo uma matriz(ponteiro para vetores, matriz com as linhas nao inicializadas), então(não tenho certeza) após usar a função aloca, a variavel 'a' ficaria assim:


a[6][3];

uma matriz de 6 por 3.

Então respondendo a 1 pergunta: Acho que não tem nada de errado com a sua função, apenas o uso dela :s

segunda pergunta:

pra essa não tenho resposta, mas algumas idérias que talvez ajudem:


for(n = 0; n<10; n++)

{

printf("O nome é: %s\n", palavras[n]);

}

porque n < 10? não deveria ser 5(Porque são 5 palavras)?

exemplo:


char palavra[][4] = {"p1", "p2", "p3", "p4", "p5"};
//palavra[5][4];

a saida ficou bem loca :s, não sei porque aconteceu isso.

espero que tenha ajudado um pouco. :)

Postado

Assim, esse tipo de declaração existe, é citada no livro do Kernighan, como "Declarações Complicadas", mas nao explica muito sobre o assunto. int (*a)[3] É um ponteiro q aponta pra vetores de 3 posições q é diferente de int* a[3] q é um vetor de 3 posições de ponteiros para int . Se for usar o sizeof isso fica claro. Eu sei q isso é possivel, so nao sei como fica a sintaxe no cast e como uma função retornaria esse int (*a)[3] . No erro do g++ cita algo como int (*)[3] , mas tentei algumas variacoes e nada. Sei q existem milhares de formas de fazer, mas como programo pra microcontroladores todos os bytes tem muita importancia!

So um pequeno detalhe, a matriz resultante é a[2][3] , pois aloca 6 int para o 'a' distribuido em [2][3] . Na verdade sao alocados 2 vetores de 3 posições cada.

No segundo caso você tem vetores de 4 posições, logo se tem:

vetor 0 = ['C' 'a' 'c' 'h']

vetor 1 = ['o' 'r' 'r' 'o']

vetor 2 = ['\0' 'G' 'a' 't']

vetor 3 = ['o' '\0' 'P' 'e']

e assim sucessivamente... So na hora de imprimir, o %s so para quando encontra um '\0'.

Pelo menos é assim q eu acho q deveria funcionar... O estranho é q o programa imprime partes do codigo fonte hehehe... Obrigado pela atencao!

Postado

hmm, acho que entendi, seria algo como:

a[0] a[1] a[2] ...

[0][1][2] [0][1][2] [0][1][2]

um vetor de vetores, no caso um ponteiro :)

Se for isso, então:

cada posição de 'a' teria um endereço para o inicio de um vetor, para aloca-lo seria necessário: o tamanho de um ponteiro para inteiro(4 bytes se nao me engano) multiplicado pelo numero de elementos para o qual aponta(no caso 3), então acho que ficaria assim:


return (int*)malloc(sizeof(int*)*quantidade);

malloc retorna o ponteiro para o inicio do vetor(vetor a), então acho que a conversão é essa mesma, ou então (int**) no caso 'a' seria um ponteiro para um ponteiro onde o segundo ponteiro é o inicio de um vetor.

para acessar um elemento de a seria assim:

a[0][0], primeiro seria para indicar qual vetor eu quero e depois qual elemento desse vetor eu quero, é bem parecido com uma matriz, mas é diferente.

a parte de mostrar o código, não sei direito mas acho que o código do programa fica armazenado em algum local enquanto ele é executado certo? talvez ele tenha atingido essa posição, não sei muito sobre programas em execução :)

Postado

exatamente isso q você disse, ele é um ponteiro para vetores de 3 posições.

as formas int* e int** dao erro. int* ate compila mas gera warning dizendo q os tipos sao incompactiveis, mas q voi convertido e ficou tudo bem. O q eu acho q seria o correto seria


int (*)[3] aloca(unsigned int quantidade)

{

return (int (*)[3])malloc(sizeof(int)*quantidade);

}

Eu acho isso totalmente logico porque os dados seriam convertidos para int (*)[3] , mas o compilador da um erro muito estranho, diz q falta informações (?) . Procurei na net mas eu sempre encontro coisas do tipo int* a[2][3]. Isso ate funciona mas você teria uma matriz 2x3 de ponteiros, onde você precisa alocar memoria pra cada um deles. Nao acho certo, porque pra uma matriz basta apenas um ponteiro, seja ela de qualquer dimensao.

Postado

na verdade, acho que int* [2][3] seria uma matriz 3D depois que alocasse os espaços pra ela, porque a linguagem C permite que façamos isso: int [dimensoes][linhas][colunas], como se fosse z, y, x.

fiz uns testes:


#include <stdio.h>

int main()
{

int (*a)[3];

a = (int*)malloc(sizeof(int)*3);

int i, j;
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
a[i][j] = i*j;
}
}

for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}

return 0;
}

recebi duas warning: rea de Trabalho/teste.c|8|warning: incompatible implicit declaration of built-in function ‘malloc’ [habilitado por padrão]|

rea de Trabalho/teste.c|8|warning: assignment from incompatible pointer type [habilitado por padrão]|

||=== Build finished: 0 errors, 2 warnings ===|

a primeira é da função acho que não tem nada a ver com a conversão não, só a segunda mesmo que tem. Mas os valores foram adcionados corretamente a cada posição, porém sei que receber warnings tira a confiabilidade do código, vou ve se acho alguma forma de fazer isso.

Postado

Pois é, o codigo funciona, mas ainda acho q deve ter uma maneira mais correta de realiza-lo. Vou continuar aqui nos testes!!! Obrigado!!!

Achei algo interessante, que envolve o typedef. o link é http://cesarakg.freeshell.org/pointers.html no item 9. Ponteiros e Alocação Dinâmica de Memória, metodo 1 (ensina a fazer o cast) e metodo 2 (nao ensina a fazer o cast).

Postado

Depois de muito procurar a resposta acabei acertando o codigo:


#include<stdio.h>
#include<stdlib.h>


int (* alocar(unsigned int qtde))[3]

{

return (int (*)[3])malloc(sizeof(int)*qtde);

}


int main(void)
{

int (*x)[3];
int i, j, a;

x = alocar(2*3);

for(i = 0, a = 0; i<2; i++)
{
for(j = 0; j<3; j++)
x[i][j] = ++a;
}

for(i = 0; i<2; i++)
{
for(j = 0; j<3; j++)
printf("x[%d][%d] = %d\n", i, j, x[i][j]);
}

return 0;
}

Obrigado a todos pela ajuda!

  • Moderador
Postado

Caso o autor do tópico necessite, o mesmo será reaberto, para isso deverá entrar em contato com a moderação solicitando o desbloqueio.

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...