当我突然想到指针只是一个存储变量的内存地址的变量时,我正在读指针,所以每个整数都应该作为指针.然后我创建了一个小程序,它发出警告,但它以某种方式工作.
int main()
{
int i,j;
i=3;
j=&i;
printf("%d\n%d\n%d",i,j,&i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是
3
1606416600
1606416600
Run Code Online (Sandbox Code Playgroud)
那么,为什么要添加额外的*如果正常的int工作呢?
另一个问题是关于以下计划的输出
int main()
{
int a[] = {1,2,3,4,5,6,7};
int *i,*j;
i=&a[1];
j=&a[5];
printf("%d\n%d\n%d",j,i,j-i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
1606416580
1606416564
4
Run Code Online (Sandbox Code Playgroud)
为什么ji = 4而不是16?
小智 16
为什么我们需要把*用于指针
因为语言规范是这样说的.
那么,为什么要添加额外的*如果正常的int工作呢?
因为"正常" int不起作用.也不是"异常" int.
指针是一种单独的类型.难怪人类大脑很容易将它们想象成一个称为"记忆"的huuuuuge字节数组的索引,但这并不一定是计算机和编译器所做的.C标准表示指针之间的转换int是一个实现定义的操作.
您可以存储一个指针,不会丢失数据,如果你使用内置int型intptr_t或者uintptr_t,虽然-但是那些都保证是一个int(或者unsigned int,对于这个问题).
关于你的第二个问题:因为那是指针运算的定义方式.并且它的定义是这样的,因为它是如何合乎逻辑和直观的.如果p2 = p1 + 4,那么p2 - p1是4而不是16.
有关指针算法的更多信息,请参阅此问题.
哦,从技术上讲,你的第一个程序有未定义的行为,因为打印指针是使用%p转换说明符完成的,但你使用的%d是int.你的第一个程序是这样的:
printf("%d\n%d\n%p", i, j, (void *)&i);
Run Code Online (Sandbox Code Playgroud)
(也注意到投地void *-这是在哪里铸造的少数情况下一个void *是必需的,否则你再有UB).