在全局范围内重新定义指针 我对C这个看似基本的方面完全混淆了。考虑这两行代码: int *ptr; *ptr = 2;
gcc将发出以下警告:在全局范围内重新定义指针 我对C这个看似基本的方面完全混淆了。考虑这两行代码: int *ptr; *ptr = 2;,c,C,gcc将发出以下警告: main.cpp:4:1: warning: data definition has no type or storage class [enabled by default] *ptr = 2; ^ main.cpp:4:2: warning: type defaults to 'int' in declaration of 'ptr' [enabled by default] *ptr = 2; ^ main.cpp:4:8: warning: init
main.cpp:4:1: warning: data definition has no type or storage class [enabled by default]
*ptr = 2;
^
main.cpp:4:2: warning: type defaults to 'int' in declaration of 'ptr' [enabled by default]
*ptr = 2;
^
main.cpp:4:8: warning: initialization makes pointer from integer without a cast [enabled by default]
*ptr = 2;
^
什么类型的ptr
被默认为,int
或int*
(例如,ptr
是指针还是int
)?如果是这样,这是否意味着ptr
指向地址2,还是没有改变?我假设它发生了更改,因为它崩溃了,除非您给ptr
一个有效地址
int i = 5;
int *ptr;
*ptr = &i;
int main(){
printf("%d", *ptr); // 5
}
我知道存在未定义行为的可能性,您不应该忽略警告,但我正在尝试看看这里实际发生了什么
有关上下文,请参见此下的注释链。下面是发生的情况:由于您显示的两行在文件范围内(与本地范围相反),因此这两行都被视为声明,而不是声明和赋值语句。这是因为在文件范围内不能有任何语句-只允许声明和定义 旧的C规则允许
int
类型的声明完全省略类型。因此,第二行是
ptr
- …这是一个指针,因为它有一个星号
- …它也是指向
的指针,因为缺少类型int
int *ptr;
int *ptr = &i;
您的代码将编译并运行()
现在还有一个问题:编译器为什么不抱怨重复声明?事实证明,编译器会将多个相同的声明视为一个相同的声明,只要它们彼此完全相同。后续错误可能是由以前的声明引起的。只需为指针分配内存或将其指向有效内存。当编译器发现问题时,它会尽力找出最好的方法。应用了警告后,这会发出警告,并尽可能地进行。这可能会导致后续警告。最好关注第一个警告并纠正第一个是代码未定义的行为,即使它是出于这些原因工作的?我相信“未定义的行为”意味着“语言规范没有告诉编译器应该如何工作”,“它工作”意味着“您使用的编译器做出了您想要的选择”@remyabel它没有未定义的行为。该标准尊重关于声明的旧规则,没有隐式地考虑显式类型
int
,因此它与int*ptr=&i有人能给我解释一下吗?它看起来就像使用未初始化的指针(并且未分配),因此对我来说会导致分段错误,它很特别,因为它位于全局区域?@dasblinkenlight,所以整个点都在文件范围内,即*ptr=2
实际上像int*ptr=2
一样工作,并且不推荐使用?所以无论如何,不要做那样的事。