在指针声明中放置星号

我最近决定,我不得不最终学习C / C ++,有一点我不太了解指针,或者更确切地说,他们的定义。

这些例子如何:

  1. int* test;
  2. int *test;
  3. int * test;
  4. int* test,test2;
  5. int *test,test2;
  6. int * test,test2;

现在,据我了解,前三种情况都是一样的:testing不是一个int,而是一个指针。

第二套例子有点棘手。 在情况4中,test和test2都是指向int的指针,而在情况5中,只有test是一个指针,而test2是一个“真实的”int。 那么情况6呢? 与案例5一样?

4,5和6是一样的东西,只有testing是一个指针。 如果你想要两个指针,你应该使用:

 int *test, *test2; 

或者,甚至更好(使一切都清楚):

 int* test; int* test2; 

星号周围的空白没有意义。 所有三个意思是相同的事情:

 int* test; int *test; int * test; 

int *var1, var2 ”是一个邪恶的语法,只是为了混淆人,应该避免。 它扩展到:

 int *var1; int var2; 

使用“顺时针螺旋规则”来帮助parsingC / C ++声明;

有三个简单的步骤:

  1. 以未知元素开始,以螺旋/顺时针方向移动; 当生成以下元素时,用相应的英语语句replace它们:

    [X][] :数组X的大小…或数组未定义的大小…

    (type1, type2) :函数传递type1和type2返回…

    * :指向…的指针

  2. 继续以螺旋/顺时针方向进行操作,直到所有的令牌都被覆盖。
  3. 总是先解决任何括号内的问题!

此外,声明应尽可能在单独的声明(绝大多数情况下是这样)。

许多编码指南build议您只在每行声明一个variables 。 这样可以避免你在提出这个问题之前所做的任何混淆。 与我一起工作的大多数C ++程序员似乎都坚持这一点。


有一点我知道,但是我发现有用的是向后读取声明。

 int* test; // test is a pointer to an int 

这开始工作得很好,特别是当你开始声明const指针时,知道它是否是const的指针,或者指针指向的是const还是非常棘手。

 int* const test; // test is a const pointer to an int int const * test; // test is a pointer to a const int ... but many people write this as const int * test; // test is a pointer to an int that's const 
 #include <type_traits> std::add_pointer<int>::type test, test2; 

正如其他人提到的,4,5和6是一样的。 通常,人们用这些例子来说明*属于variables而不是types。 虽然这是一个风格问题,但是你是否应该这样思考和写下这个问题呢?

 int* x; // "x is a pointer to int" 

或者这样:

 int *x; // "*x is an int" 

FWIW我在第一阵营,但其他人为第二种forms争论的原因是(主要)解决了这个问题:

 int* x,y; // "x is a pointer to int, y is an int" 

这可能是误导性的; 相反,你会写

 int *x,y; // it's a little clearer what is going on here 

或者如果你真的想要两个指针,

 int *x, *y; // two pointers 

就个人而言,我说每行保留一个variables,那么你更喜欢哪种风格并不重要。

在4,5和6中, test总是一个指针,而test2不是一个指针。 在C ++中,空白(几乎)是不重要的。

指针是types的修饰符。 为了更好地理解星号如何修改types,最好从右到左读取它们。 'int *'可以被读为“指向int的指针”。在多个声明中,你必须指定每个variables是一个指针,否则它将被创build为一个标准variables。

1,2和3)testing是types(int *)。 空白不重要。

4,5和6)testing是types(int *)。 Test2是inttypes的。 再次,空白是无关紧要的。

你可以认为4,5和6如下:声明types只需要做一次,但如果你想声明一个指向该types的指针(通过添加一个星号),你必须这样做每个variables。

当声明一个指针variables时,我总是在variables和星号之间加上空格,即使我在一行中声明了多个。 不这样做使得我几乎每次都把它混淆为一个解引用expression式。

一个好的经验法则是,很多人似乎都掌握了这些概念:在C ++中,很多语义含义是由关键字或标识符的左边绑定派生的。

举个例子:

 int const bla; 

const适用于“int”字。 指针的星号也是一样,它们适用于左侧的关键字。 而实际的variables名称? 是的,这是剩下的东西。

C语言的基本原理是你用variables的方式声明variables。 例如

 char *a[100]; 

*a[42]将是一个char 。 还有a[42]字符指针。 因此, a是一个char指针数组。

这是因为原始的编译器编写者想要使用相同的parsing器来进行expression式和声明。 (语言deviseselect不是一个非常明智的理由)

我会说,最初的约定是将星形放在指针名称一侧(声明的右侧)

你可以遵循相同的规则,但是如果你把星星放在types方面,这并不是什么大问题。 请记住, 一致性是重要的,所以总是在同一方,而不pipe你select哪一方。

情况1,2和3是相同的,他们声明指向intvariables的指针。 例3,例4和例5是相同的,因为它们分别声明一个指针和一个intvariables。 如果你想要在一行中声明两个指针(你不应该这样做),你需要在每个variables名前加一个星号:

 int *test, *test2; 

没有什么正确的方法可以说明星号在哪里。 int* test看起来更好,因为我们更容易想象在types末尾附加*意味着“指向”types。 然而, int *test更有意义,因为您可以像math中的减号一样使用它:

 -(-x) = x 

是类似的

 *(*test) = test 

这一直帮助我。 可悲的是,这一切的结果是,有时我使用int* test和有时int *test