Zeb*_*ish 0 c c++ arrays memory-address
我一直以为:
char a[10];
char* p = &a;
Run Code Online (Sandbox Code Playgroud)
是错的,它应该是以下之一:
char a[10];
char* p = a; // OR
char* p = &a[0];
Run Code Online (Sandbox Code Playgroud)
我希望我能找到这里的主题,所以我正在阅读说p =&a; 是有效的,它是关于C语言,而不是C++.
我一直在想,显然:
char* p = new char[10];
char* p1 = &p; // Is wrong
Run Code Online (Sandbox Code Playgroud)
但是,当一个数组在堆栈空间为本地创造了它似乎是合理的我的直觉a,&a和&a[0]都是相同的值/地址.我不得不说,我一直在关注C++并且没有看到它以这种方式完成,这就是为什么当我开始研究CI时很快将其称为错误,但我确信它不在C中(很好地验证)在那将是赞赏).我只是想知道C++中的情况是否也是如此,因为据我所知,在C++中通常会采用其他两种方式中的一种,这种方式(如果我的想象力不是耍花招)似乎是用C语言完成的.
编辑:这是一个非常愚蠢的问题.我的困惑来自于我的Visual Studio编译器在C中编译它,但不是在C++中编译,所以我认为在这方面语言有所不同.我不会删除这个问题,因为它已经有了答案.
char a[10];
char* p = &a;
Run Code Online (Sandbox Code Playgroud)
在C中确实是错的.
特别是(所有引用都参考ISO 9899:1999(C99),所有重点都是我的):
6.7.8(初始化)/ 11说:
标量的初始值设定项应为单个表达式,可选择用大括号括起来.对象的初始值是表达式的初始值(转换后); 与简单赋值相同的类型约束和转换适用,将标量的类型作为其声明类型的非限定版本.
6.5.16.1(简单分配):
约束
- 以下其中一项应持有:
- 左操作数具有限定或非限定算术类型,右边具有算术类型;
- 左操作数具有与右侧类型兼容的结构或联合类型的限定或非限定版本;
- 两个操作数都是指向兼容类型的限定或非限定版本的指针,左边指向的类型具有右边指向的所有类型的限定符;
- 一个操作数是指向对象或不完整类型的指针,另一个是指向限定或非限定版本的指针,
void左边指向的类型具有右边指向的类型的所有限定符;- 左操作数是一个指针,右边是一个空指针常量; 要么
- 左操作数有类型
_Bool,右边是指针.
只有粗体部分适用; 我们没有使用任何算术或结构/联合类型,没有void或_Bool没有空指针常量.
有问题的类型是左侧的char *(指针char)和右侧的char (*)[10](指向数组[10]的指针char).指针类型的兼容性定义如下:
6.7.5.1(指针声明符)/ 2:
要使两个指针类型兼容,两者都应具有相同的限定条件,并且两者都应是兼容类型的指针.
指向的类型分别是char和char [10].
但现在我们被困住了.有6.2.7(兼容型和复合型)/ 1:
如果类型相同,则两种类型具有兼容类型.用于确定两种类型是否兼容的附加规则在6.7.2中描述了类型说明符,在6.7.3中描述了类型限定符,在6.7.5中描述了声明符.
char并且char [10]显然不一样.6.7.5中兼容类型的所有声明符规则都说" 要使两个指针类型兼容...... "," 要兼容两种数组类型...... "," 要兼容两种函数类型...... " ,但是非数组类型无法与数组类型兼容.
因此,类型不兼容并char *p = &a违反了6.5.16.1中的约束.
5.1.1.3(诊断):
如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现 -定义.
这意味着需要警告或错误消息.如果您的编译器没有生成一个,那么它不是一个真正的C编译器.