Recentemente, decidi que só preciso aprender C / C ++, e há uma coisa que realmente não entendo sobre ponteiros ou, mais precisamente, sua definição.
Que tal estes exemplos:
int* test;
int *test;
int * test;
int* test,test2;
int *test,test2;
int * test,test2;
Agora, no meu entendimento, os três primeiros casos estão todos fazendo o mesmo: Teste não é um int, mas um indicador para um.
O segundo conjunto de exemplos é um pouco mais complicado. No caso 4, teste e test2 serão ponteiros para um int, enquanto no caso 5, apenas teste é um ponteiro, enquanto test2 é um int "real". E o caso 6? Mesmo que o caso 5?
c++
c
pointers
declaration
Michael Stum
fonte
fonte
int*test;
?Foo<Bar<char>>
No>>
tinha de ser escrita> >
para não ser tratado como um shift direita.++
operador de incremento não pode ser dividido por um espaço, os identificadores não podem ser divididos por um espaço (e o resultado ainda pode ser válido para o compilador, mas com comportamento de tempo de execução indefinido). As situações exatas são muito difíceis de definir considerando a bagunça de sintaxe que é C / C ++.Respostas:
4, 5 e 6 são a mesma coisa, apenas teste é um indicador. Se você quiser duas dicas, você deve usar:
Ou, ainda melhor (para deixar tudo claro):
fonte
O espaço em branco ao redor dos asteriscos não tem significado. Todos os três significam a mesma coisa:
O "
int *var1, var2
" é uma sintaxe maligna que visa confundir as pessoas e deve ser evitada. Ele se expande para:fonte
int*test
.int *test
( google-styleguide.googlecode.com/svn/trunk/… ). Apenas seja consistenteMuitas diretrizes de codificação recomendam que você declare apenas uma variável por linha . Isso evita qualquer confusão do tipo que você tinha antes de fazer esta pergunta. A maioria dos programadores de C ++ com quem trabalhei parecem aderir a isso.
Um pouco à parte, eu sei, mas algo que achei útil é ler as declarações de trás para frente.
Isso começa a funcionar muito bem, especialmente quando você começa a declarar ponteiros const e fica complicado saber se é o ponteiro que é const ou se é para o que o ponteiro está apontando é const.
fonte
Use a "Regra da espiral no sentido horário" para ajudar a analisar as declarações C / C ++;
Além disso, as declarações devem ser feitas em instruções separadas, quando possível (o que é verdade na grande maioria das vezes).
fonte
int* x;
estilo em vez doint *x;
estilo tradicional . Claro, o espaçamento não importa para o compilador, mas afeta os humanos. A negação da sintaxe real leva a regras de estilo que podem irritar e confundir os leitores.Como outros mencionaram, 4, 5 e 6 são iguais. Freqüentemente, as pessoas usam esses exemplos para fazer o argumento de que
*
pertence à variável em vez do tipo. Embora seja uma questão de estilo, há um debate sobre se você deve pensar e escrever desta forma:ou assim:
FWIW Estou no primeiro campo, mas a razão pela qual outros defendem a segunda forma é que ela (principalmente) resolve este problema específico:
o que é potencialmente enganoso; em vez disso você escreveria
ou se você realmente quer duas dicas,
Pessoalmente, eu digo que mantenha uma variável por linha, então não importa qual estilo você prefere.
fonte
int *MyFunc(void)
? a*MyFunc
é uma função que retorna umint
? não. Obviamente, devemos escreverint* MyFunc(void)
, e dizer queMyFunc
é uma função que retorna aint*
. Então, para mim, isso está claro, as regras de análise gramatical C e C ++ são simplesmente erradas para declaração de variável. eles devem ter incluído a qualificação de ponteiro como parte do tipo compartilhado para toda a sequência de vírgula.*MyFunc()
é umint
. O problema com a sintaxe C é misturar sintaxe prefixo e pós - fixada - se apenas o pós-fixo fosse usado, não haveria confusão.int const* x;
, que considero tão enganosas quantoa * x+b * y
.fonte
#include <windows.h>LPINT test, test2;
Em 4, 5 e 6,
test
é sempre um ponteiro etest2
não é um ponteiro. O espaço em branco (quase) nunca é significativo em C ++.fonte
Na minha opinião, a resposta é AMBAS, dependendo da situação. Geralmente, IMO, é melhor colocar o asterisco ao lado do nome do ponteiro, em vez do tipo. Compare, por exemplo:
Por que o segundo caso é inconsistente? Porque, por exemplo,
int x,y;
declara duas variáveis do mesmo tipo, mas o tipo é mencionado apenas uma vez na declaração. Isso cria um precedente e um comportamento esperado. Eint* pointer1, pointer2;
é inconsistente com isso porque declarapointer1
como um ponteiro, maspointer2
é uma variável inteira. Está claramente sujeito a erros e, portanto, deve ser evitado (colocando o asterisco ao lado do nome do ponteiro, em vez do tipo).No entanto , existem algumas exceções em que você pode não ser capaz de colocar o asterisco ao lado do nome de um objeto (e onde importa onde colocá-lo) sem obter resultados indesejados - por exemplo:
MyClass *volatile MyObjName
void test (const char *const p) // const value pointed to by a const pointer
Finalmente, em alguns casos, pode ser indiscutivelmente mais claro colocar o asterisco ao lado do nome do tipo , por exemplo:
void* ClassName::getItemPtr () {return &item;} // Clear at first sight
fonte
A lógica em C é que você declara as variáveis da maneira como as usa. Por exemplo
diz que
*a[42]
será achar
. Ea[42]
um ponteiro char. E assima
é uma matriz de ponteiros char.Isso porque os escritores do compilador original queriam usar o mesmo analisador para expressões e declarações. (Não é uma razão muito sensata para uma escolha de design de idioma)
fonte
char* a[100];
também deduz que*a[42];
será um ponteirochar
ea[42];
um char.a[42]
é umchar
ponteiro e*a[42]
é um char.Eu diria que a convenção inicial era colocar a estrela no lado do nome do ponteiro (lado direito da declaração
na linguagem de programação c de Dennis M. Ritchie, as estrelas estão no lado direito da declaração.
olhando o código-fonte do linux em https://github.com/torvalds/linux/blob/master/init/main.c podemos ver que a estrela também está no lado direito.
Você pode seguir as mesmas regras, mas não é um grande problema colocar estrelas no lado das letras. Lembre-se de que a consistência é importante, portanto, sempre, mas a estrela do mesmo lado, independentemente do lado que você escolheu.
fonte
O ponteiro é um modificador do tipo. É melhor lê-los da direita para a esquerda para entender melhor como o asterisco modifica o tipo. 'int *' pode ser lido como "ponteiro para int '. Em várias declarações, você deve especificar que cada variável é um ponteiro ou será criada como uma variável padrão.
1,2 e 3) O teste é do tipo (int *). O espaço em branco não importa.
4,5 e 6) O teste é do tipo (int *). Test2 é do tipo int. Novamente, o espaço em branco é irrelevante.
fonte
Uma boa regra prática, muitas pessoas parecem compreender esses conceitos por: Em C ++, muito significado semântico é derivado pela ligação à esquerda de palavras-chave ou identificadores.
Considere por exemplo:
O const se aplica à palavra "int". O mesmo acontece com os asteriscos dos ponteiros, eles se aplicam à palavra-chave à esquerda deles. E o nome real da variável? Sim, isso é declarado pelo que sobrou dele.
fonte