Ir ao conteúdo
  • Cadastre-se
Whiplax

C Tentando entender ponteiros para char

Recommended Posts

Quero entende porque isto funciona
   

 char c[30] = "testing";
char *p;
*p = c[6];
printf("%c - %c", c[6], *p);
//> g - g

 

Porém isso da esse erro   

char c[30] = "testing";
char *p = c[6];
printf("%c - %c", c[6], *p);

//>warning: initialization makes pointer from integer without a cast [-Wint-conversion]
//     char *p = c[6];
//               ^

 

 

E também porque nesse caso aqui não consigo passar um char pro ponteiro

void foo(char *s){;}
int main(){
    char c[30] = "testing";
    foo(c);}// ou foo("g")
//Isso funciona

void foo(char *s){;}
int main(){
    char c[30] = "testing";
    foo(c[6]);}// ou foo('g')
//Isso não funciona
//Para foo(c[6]);
//warning: passing argument 1 of 'foo' makes pointer from integer without a cast [-Wint-conversion]
//     foo(c[6]);
//         ^
//note: expected 'char *' but argument is of type 'char'
// void foo(char *s){
//      ^~~
//Para foo('o');
//warning: passing argument 1 of 'foo' makes pointer from integer without a cast [-Wint-conversion]
//     foo('o');
//         ^~~
//note: expected 'char *' but argument is of type 'int'
// void foo(char *s){
//      ^~~

Foi mal se tá mal formatado e se a pergunta é *****

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ponteiros armazenam endereços de memória, não guardam valores.

 

Então nesse caso:

char c[30] = "testing";
char *p; //Cria um ponteiro, que não foi inicializado,
         //logo ele aponta para um lugar aleatório da memória,
         //e não temos controle sobre que lugar de memória ele
         //está apontando.

*p = c[6];//Muda para 'g' o valor do lugar aleatório da memória
          //apontado pelo ponteiro, isso é um problema pois esse
          //lugar da memória pode não estar acessível, o que
          //possivelmente causaria um problema durante a execução
          //do programa ao tentar fazer essa operação.

printf("%c - %c", c[6], *p);

Logo, o código pode funcionar mas existe a possibilidade de dar erro na execução, portanto é um erro fazer isso.

 

Para não cair no erro de programar assim, o melhor seria garantir que o programa de erro ao tentar fazer essa atribuição, para isso recomenda-se toda vez que declarar um ponteiro sempre inicializá-lo fazendo-o apontar para um ponteiro nulo (NULL), ou seja fazer o ponteiro não apontar para lugar algum:

char *p = NULL;

 

Assim, não poderá fazer atribuição que fez no programa anterior.

 


Então poderia alterar para fazê-lo apontar para um endereço de memória conhecido, ex:

char c[30] = "testing";
char *p = NULL; //Cria ponteiro que não aponta para lugar algum
p = &c[6]; //Faz ponteiro apontar para o sétimo caractere do vetor c
printf("%c - %c", c[6], *p); //Aqui vai o operador de indireção * antes
                             //do nome do ponteiro p, pois deseja-se acessar
                             //o VALOR do local apontado pelo ponteiro.

Note acima que usamos p sem * para atribuir um novo endereço de memória a ser apontado pelo ponteiro p.

 

 

Uma abreviação disso seria fazer o ponteiro ser inicializado já apontando para o sétimo caractere do vetor c :

char c[30] = "testing";
char *p = &c[6]; //Cria ponteiro, já inicializando-o com o endereço
                 //de memória do sétimo caractere do vetor c
printf("%c - %c", c[6], *p);

Note que na inicialização do ponteiro p, mesmo sendo precedido com o operador de indireção *, atribui-se um endereço de memória, pois esse é o tipo de dado que ponteiros guardam. Nesse caso o * está aí apenas para identificar que a variável sendo declarada é do tipo ponteiro, diferenciando-a de variáveis comuns.

  • Curtir 2
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
21 horas atrás, Whiplax disse:

//Isso não funciona //Para foo(c[6]);

//warning: passing argument 1 of 'foo' makes pointer from integer without a cast [-Wint-conversion] // foo(c[6]); // ^ //note: expected 'char *' but argument is of type 'char' // void foo(char *s){ // ^~~ //Para foo('o'); //warning: passing argument 1 of 'foo' makes pointer from integer without a cast [-Wint-conversion] // foo('o'); // ^~~ //note: expected 'char *' but argument is of type 'int' // void foo(char *s){ // ^~~

 

Todas essas coisas são alertas de que se passa um valor inteiro que não é um número de referência para uma variável do tipo apontador. O verificador de sintaxe nos alerda do erro lógico porque sabe que a origem do número (valor) e o seu destino são de tipos incompatíveis, porém, se fizesse um casting (conversão) não configurada o programa posteriormente seria ou não finalizado por segmentation fault em tempo de execução e a responsabilidade pelo erro é toda sua (programador).

 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

×