Estou um pouco confuso sobre alguma coisa. Fiquei com a impressão de que a maneira correta de ler uma string C scanf()
seguia as linhas de
(não importa o possível estouro de buffer, é apenas um exemplo simples)
char string[256];
scanf( "%s" , string );
No entanto, o seguinte parece funcionar também,
scanf( "%s" , &string );
Este é apenas o meu compilador (gcc), pura sorte ou algo mais?
scanf
e a pergunta e a resposta aceita se concentram em e omita as restrições criticamente importantes para o comprimento máximo de entrada que devem ser usadas no código real (mas estão além do objetivo desta pergunta).Respostas:
Uma matriz "decai" em um ponteiro para seu primeiro elemento, portanto
scanf("%s", string)
é equivalente ascanf("%s", &string[0])
. Por outro lado,scanf("%s", &string)
passa um ponteiro parachar[256]
, mas aponta para o mesmo local.Então
scanf
, ao processar o final de sua lista de argumentos, tentará extrair achar *
. Essa é a coisa certa quando você passastring
ou&string[0]
, mas quando passa,&string
depende de algo que o padrão de linguagem não garante, a saber, os ponteiros&string
e&string[0]
- ponteiros para objetos de diferentes tipos e tamanhos que começar no mesmo lugar - são representados da mesma maneira.Não acredito que já tenha encontrado um sistema no qual isso não funcione e, na prática, você provavelmente está seguro. No entanto, está errado e pode falhar em algumas plataformas. (Exemplo hipotético: uma implementação de "depuração" que inclui informações de tipo com todos os ponteiros. Acho que a implementação C na Symbolics "Lisp Machines" fez algo assim.)
fonte
&string
trabalhar o mesmo questring
(em vez de resultar em corrupção de memória aleatório, como outras respostas incorretamente assert):printf("%x\n%x\n", string, &string);
string
é um ponteiro e&string
é o endereço desse ponteiro, portanto os dois NÃO são intercambiáveis. Como Gareth explica, mesmo no caso de decaimento de array,string
e&string
tecnicamente não são os mesmos tipos (mesmo que sejam intercambiáveis para a maioria das arquiteturas), e o gcc dará um aviso para o seu segundo exemplo se você ativar-Wall
.Eu acho que isso abaixo é preciso e pode ajudar. Sinta-se livre para corrigi-lo se encontrar algum erro. Eu sou novo em C.
incluindo caractere nulo de terminação
'\0'
&str
,&str[0]
estr
, todos os três representam o mesmo local na memória que é o endereço do primeiro elemento da matrizstr
char * strPtr = & str [0]; // declaração e inicialização
Como alternativa, você pode dividir isso em dois:
strPtr
é um ponteiro para umchar
strPtr
pontos na matrizstr
strPtr
é uma variável com seu próprio endereço na memóriastrPtr
é uma variável que armazena o valor do endereço&str[0]
strPtr
próprio endereço na memória é diferente do endereço de memória que ele armazena (endereço do array na memória, também conhecido como & str [0])&strPtr
representa o endereço do próprio strPtrEu acho que você poderia declarar um ponteiro para um ponteiro como:
declara e inicializa com o endereço do ponteiro strPtr
Como alternativa, você pode dividir em dois:
*vPtr
pontos no ponteiro strPtr*vPtr
é uma variável com seu próprio endereço na memória*vPtr
é uma variável que armazena o valor do endereço & strPtrstr++
, ostr
endereço é umconst
, mas você pode fazerstrPtr++
fonte