C++ 指针初始化

C++ 指针初始化,c++,pointers,C++,Pointers,在下面的代码中: char data[128] = "Just A Test \0"; char *cTest2 = data; char *cTest3 = &data[0]; cTest2和cTest3之间的区别是什么? 什么时候使用一种初始化方法而不是另一种?没有区别;因为一个好的编译器会产生相同的代码,您可以根据个人喜好使用这些代码。如果您有 char *cTest4 = &data[5]; 或者类似的方案,我会投票支持cTest3。否则cTest2看起来更干净。实际

在下面的代码中:

char data[128] = "Just A Test \0";
char *cTest2 = data;
char *cTest3 = &data[0];
cTest2和cTest3之间的区别是什么?
什么时候使用一种初始化方法而不是另一种?

没有区别;因为一个好的编译器会产生相同的代码,您可以根据个人喜好使用这些代码。

如果您有

char *cTest4 = &data[5];

或者类似的方案,我会投票支持cTest3。否则cTest2看起来更干净。

实际上没有区别,但您的代码应该反映您的意思

如果要对整个阵列寻址,请使用
cTest2


如果要处理第一个元素,请使用
cTest3

完全没有区别。C++规范表示:

5.2.1认购 后缀表达式后跟方括号中的表达式是后缀表达式。其中一个表达 应具有“T数组”或“指向T的指针”类型,另一个应具有非范围枚举 或整型。结果为“T”型。“T”型应为完全定义的对象类型。这个 表达式E1[E2]根据定义与*((E1)+(E2))相同


这意味着
数据[0]
在定义上与
*数据
相同,因此根据定义,
&(数据[0])
始终是
数据
首先,在字符串文本中包含零字符没有太大意义

char data[128] = "Just A Test \0";
                              ^^^ 
字符串文字已包含终止零

至于指针声明,那么这两者之间没有区别

char *cTest2 = data;
char *cTest3 = &data[0];
表达式中使用的字符数组隐式转换为指向其第一个元素的指针。所以这两个声明是等价的

不过,我更喜欢第一份声明,因为它更清楚。只有当指针必须由数组中除第一个元素之外的某个元素的地址初始化时,我才会使用第二个声明。比如说

char *cTest3 = &data[5];
但在这种情况下,取消引用表达式
data+5
是没有意义的,因为
data[5]
相当于
*(data+5)
&data[5]
相当于
&*(data+5)
。尽管当两个运算符&和*相互跟随时,编译器可能会忽略指针的解引用

根据C标准(6.5.3.2地址和间接运算符)

  • …如果操作数是一元*运算符的结果,则 运算符或&运算符都将被计算,结果就像两者一样 省略了,但运算符上的约束仍然适用 结果不是左值
  • 所以实际上我会写

    char *cTest3 = data + 5;
    

    您不需要\0。它将自动为您添加操作,有效地相互抵消。您可以执行
    char*test=&(&data[0])[0]如果您愿意。只有当
    数据
    不可取消引用时才会有区别。但在这种情况下,正如前面所述,没有区别。