零';超载';在C中为指针赋值时
这个问题的灵感来自我一直在读的一本C语言书 他在哪里说:零';超载';在C中为指针赋值时,c,pointers,C,Pointers,这个问题的灵感来自我一直在读的一本C语言书 他在哪里说: int num; int *pi=0; // Zero referes to the null pointer, NULL pi = # *pi = 0; // Zero refers to the integer zero 我们习惯于重载运算符,例如使用星号 声明指针、取消引用指针或乘法。这个 zero也是重载的。我们可能会感到不安,因为我们 不习惯重载操作数 所以我用调试器做了一系列的调查,我的答案是调试器给我的
int num;
int *pi=0; // Zero referes to the null pointer, NULL
pi = #
*pi = 0; // Zero refers to the integer zero
我们习惯于重载运算符,例如使用星号
声明指针、取消引用指针或乘法。这个
zero也是重载的。我们可能会感到不安,因为我们
不习惯重载操作数
所以我用调试器做了一系列的调查,我的答案是调试器给我的。我明白,这是一种未定义的行为,但我不是在写程序,我只是想弄明白。不管是什么情况,每次运行指针时都会将其初始化为1,在某些计算中我并不依赖于它,它是调试器反复显示的
这其实只是一个问题,但我必须写更多,否则它不会接受。
为什么*p=0在不同的时间有不同的影响?0是如何重载的?
如何判断*p=0是将p设为空指针,还是将0赋给p所指向的变量?编译器如何知道在p的地址而不是p所指向的地址分配null
$ cat prac.c
#include <stdio.h>
int main()
{
int num;
int *p;
printf("0) %p is %d\n",p,*p);
*p=0; //Why is this......
printf("1) %p is %d\n",p,*p);
num=5;
p=#
printf("2) Now %p is %d\n",p,*p);
*p=0; //....different than this
printf("3) p is not null, %p : %d\n",p,*p);
return 0;
}
$ ./prac
0) 0x7ffeb36b5c30 is 1 //pointer is initialized to 1, not-null, definitely out-of-bounds though
1) 0x7ffeb36b5c30 is 0
2) Now 0x7ffeb36b5b3c is 5
3) p is not null, 0x7ffeb36b5b3c : 0
$cat prac.c
#包括
int main()
{
int-num;
int*p;
printf(“0)%p是%d\n”,p,*p);
*p=0;//为什么。。。。。。
printf(“1)%p是%d\n”,p,*p);
num=5;
p=&num;
printf(“2)现在%p是%d\n”,p,*p);
*p=0;//…与此不同
printf(“3)p不为空,%p:%d\n”,p,*p);
返回0;
}
美元/普拉克
0)0x7ffeb36b5c30为1//指针初始化为1,不是null,但绝对超出范围
1) 0x7ffeb36b5c30是0
2) 现在0x7ffeb36b5b3c是5
3) p不为null,0x7FFEB36B3C:0
您要问的概念是空指针常量
C标准将空指针常量定义为
值为0
的整型常量表达式,或此类表达式
键入void*
因此,属于int
类型的表达式0
,也是一个空指针常量。(请注意,空指针常量不必是指针类型。)
该标准进一步规定:
如果将空指针常量转换为指针类型,则
结果指针(称为空指针)保证可以进行比较
不等于指向任何对象或函数的指针
鉴于:
int n;
int *p;
这:
隐式地将int
表达式0
转换为int*
类型的空指针,而这:
n = 0;
或
不执行隐式转换,因为正在初始化的对象已经是int
类型
调用隐式转换的规则在赋值运算符的描述中说明。同样的规则也适用于初始化、参数传递和return
语句。这些规则明确声明将null指针常量转换为目标类型
参见C11标准草案(大PDF)
- 空指针常量和空指针:6.3.2.3
- 简单作业:6.15.6.1
0
的整型常量表达式,或此类表达式
键入void*
因此,属于int
类型的表达式0
,也是一个空指针常量。(请注意,空指针常量不必是指针类型。)
该标准进一步规定:
如果将空指针常量转换为指针类型,则
结果指针(称为空指针)保证可以进行比较
不等于指向任何对象或函数的指针
鉴于:
int n;
int *p;
这:
隐式地将int
表达式0
转换为int*
类型的空指针,而这:
n = 0;
或
不执行隐式转换,因为正在初始化的对象已经是int
类型
调用隐式转换的规则在赋值运算符的描述中说明。同样的规则也适用于初始化、参数传递和return
语句。这些规则明确声明将null指针常量转换为目标类型
参见C11标准草案(大PDF)
- 空指针常量和空指针:6.3.2.3
- 简单作业:6.15.6.1
inta=5
,指针只需保存5
存储在内存中的地址,例如int*b=&a代码>。无论指针指向什么类型的对象,其工作方式都是相同的。(一个指针,就是一个指针……)
如何声明、分配地址和引用指向的值
让我们以您的示例为例,看看每一行的功能(忽略您的p
&pi
打字错误,仅使用p
):
查看哪个是值为0
的常量表达式,或转换为类型void*
(例如(void*)0
)的此类表达式。实际上所有的C编译器,如果事实上C标准为此提供了NULL
。(请参见:)因此您通常会看到:
int *p = NULL; /* declare and initialize 'p' to the Null Pointer Constant */
接下来,一元运算符“&”
用于获取对象的地址。在这里:
p = # /* assigns the address of 'num' as the value of 'p', so
* 'p' holds the address of 'num' (e.g. 'p' points to the
* memory location where 'num' is stored).
*/
一元'*'
op
p = # /* assigns the address of 'num' as the value of 'p', so
* 'p' holds the address of 'num' (e.g. 'p' points to the
* memory location where 'num' is stored).
*/
*p = 0; /* sets the value at the address held by 'p' to zero */
int num;
int *p;
printf("0) %p is %d\n",p,*p);
*p=0;
printf("1) %p is %d\n",p,*p);
num=5;
p=#
printf("2) Now %p is %d\n",p,*p);
*p=0;
printf("3) p is not null, %p : %d\n",p,*p);