一、指针是否能相加?
两个指针是不能相加的。仍以街道地址的比喻为例,假设你住在湖滨大道1332号,你的邻居住在湖滨大道1364号,那么1332+1364指的是什么呢?其结果是一个毫无意义的数字。如果你的C程序试图将两个指针相加,编译程序就会发出警告。
当你试图将一个指针和另外两个指针的差值相加的时候,你很可能会误将其中的两个指针相加,例如,你很可能会使用下述语句:
p=p+p2-p1;
上述语句是不正确的,因为它和下述语句完全相同:
p=(p+p2)-p1;
正确的语句应该是:
p=p+(p2-p1);
对此例来说,使用下述语句更好:
p+=p2-p1;
但是,可以相减,
如果两个指针向同一个数组,它们就可以相减,其为结果为两个指针之间的元素数目。仍以本章开头介绍的街道地址的比喻为例,假设我住在第五大街118号,我的邻居住在第五大街124号,每家之间的地址间距是2(在我这一侧用连续的偶数作为街道地址),那么我的邻居家就是我家往前第(124-118)/2(或3)家(我和我的邻居家之间相隔两家,即120号和122号)。指针之间的减法运算和上述方法是相同的。
#include<stdio.h>
typedef struct {
char *name;
}stuff;stuff array[] = {
{"paul"},
{"allen"},
{"james"},
{"curry"},
{"rose"},
{"kobe"},
{"anthory"},
{"wade"},
};int main()
{
stuff *p0 = &array[0];
stuff *p7 = &array[7];int diff = p7 - p0;
printf("___p0_addr: %p\n",p0);
printf("___p7_addr: %p\n",p7);
printf("___p7-p0: %d\n",diff);
printf("___p7-7_addr: %p\n",(void *)(p7 - 7));
printf("___p7-7_addr: %p\n",(p7 - 7));
printf("sizeof(array): %ld\n", sizeof(array));
}
结果如下(操作系统为64位):
___p0_addr: 0x601060
___p7_addr: 0x601098
___p7-p0: 7
___p7-7_addr: 0x601060
___p7-7_addr: 0x601060
sizeof(array): 64
二、C语言中的NULL总是被定义为0吗?NULL总是等于0吗?
NULL总是被定义为0吗?
NULL不是被定义为0,就是被定义为(void *)0,这两种值几乎是相同的。当程序中需要一个指针时(尽管编译程序并不是总能指示什么时候需要一个指针),一个纯粹的零或者一个void指针都能自动被转换成所需的任何类型的指针。
NULL总是等于0吗?
对这个问题的回答与“等于”所指的意思有关。如果你是指“与。比较的结果为相等”,例如:
if(/* ... */)
{
p=NULL;
}
else
{
p=/* something else */;
}
/* ... */
if(p==0)
那么NULL确实总是等于0,这也就是空指针定义的本质所在。
如果你是指“其存储方式和整型值。相同”,那么答案是“不”。NULL并不必须被存为一个整型值0,尽管这是NULL最常见的存储方式。在有些计算机中,NULL会被存成另外一些形式。
如果你想知道NULL是否被存为一个整型值0,你可以(并且只能)通过调试程序来查看空指针的值,或者通过程序直接将空指针的值打印出来(如果你将一个空指针强制转换成整类型,那么你所看到的很可能就是一个非零值)。