中易网

C语言指针可以相减吗?为什么?

答案:5  悬赏:0  
解决时间 2021-01-13 00:07
  • 提问者网友:相思似海深
  • 2021-01-12 09:45
C语言指针可以相减吗?为什么?
最佳答案
  • 二级知识专家网友:夜余生
  • 2021-01-12 11:05
如果两个指针向同一个数组,它们就可以相减,其为结果为两个指针之间的元素数目。仍以本章开头介绍的街道地址的比喻为例,假设我住在第五大街118号,我的邻居住在第五大街124号,每家之间的地址间距是2(在我这一侧用连续的偶数作为街道地址),那么我的邻居家就是我家往前第(124-118)/2(或3)家(我和我的邻居家之间相隔两家,即120号和122号)。指针之间的减法运算和上述方法是相同的。

C 语言指针怎么理解?

你可以把它想象成一条无限长的纸带。纸带上边有一个个的小格子,每个小格子正好是一字节,里边能够存放一个数字。计算机的工作就是对这些小格子里的数字做处理。虽然你在电脑上能够看视频、听音乐,但这些东西本质上都是存在内存这条纸带上的数字。
全部回答
  • 1楼网友:三千妖杀
  • 2021-01-12 16:29
指针减指针没有意义,在数组中指针可以减整数
  • 2楼网友:蕴藏春秋
  • 2021-01-12 14:51
同类型的指针可以相减,其结果是两个指针所指向地址间相差的这个类型元素的个数,如果是高地址的减低地址就是正数,否则就是负数
比如int a[100], *p, *q;
p = &a[10];
q = &a[22];
那么q - p = 12,就是两者之间差了12个元素,q在后(高地址)
p - q = -12,p在前
  • 3楼网友:往事埋风中
  • 2021-01-12 13:23
如果两个指针向同一个数组,它们就可以相减,其为结果为两个指针之间的元素数目。仍以本章开头介绍的街道地址的比喻为例,假设我住在第五大街118号,我的邻居住在第五大街124号,每家之间的地址间距是2(在我这一侧用连续的偶数作为街道地址),那么我的邻居家就是我家往前第(124-118)/2(或3)家(我和我的邻居家之间相隔两家,即120号和122号)。指针之间的减法运算和上述方法是相同的。
在折半查找的过程中,同样会用到上述减法运算。假设p和q指向的元素分别位于你要找的元素的前面和后面,那么(q-p)/2+p指向一个位于p和q之间的元素。如果(q-p)/2+p位于你要找的元素之前,下一步你就可以在(q-p)/2+p和q之间查找要找的元素;反之,你可以停止查找了。
如果两个指针不是指向一个数组,它们相减就没有意义。假设有人住在梅恩大街110号,我就不能将第五大街118号减去梅恩大街110号(并除以2),并以为这个人住在我家往回第4家中。
如果每个街区的街道地址都从一个100的倍数开始计算,并且同一条街的不同街区的地址起址各不相同,那么,你甚至不能将第五大街204号和第五大街120号相减,因为它们尽管位于同一条街,但所在的街区不同(对指针来说,就是所指向的数组不同)。
C本身无法防止非法的指针减法运算,即使其结果可能会给你的程序带来麻烦,C也不会给出任何提示或警告。
指针相减的结果是某种整类型的值,为此,ANSIC标准头文件中预定义了一个整类型ptrdiff_t。尽管在不同的编译程序中ptrdiff_t的类型可能各不相同(int或long或其它),但它们都适当地定义了ptrdiff_t类型。
例7.7演示了指针的减法运算。该例中有一个结构体数组,每个结构体的长度都是16字节。
如果是对指向结构体数组的指针进行减法运算,则a[0]和a[8]之间的距离为8;如果将指向结构体数组的指针强制转换成指向纯粹的内存地址的指针后再相减,则a[0]和aL8]之间的距离为128(即十六进制数0x80)。如果将指向a[8]的指针减去8,该指针所指向的位置并不是往前移了8个字节,而是往前移了8个数组元素。

注意:把指针强制转换成指向纯粹的内存地址的指针,通常就是转换成void *类型,但是,本例将指针强制转换成char *类型,因为void。类型的指针之间不能进行减法运算。
例 7.7 指针的算术运算
# include
# include
struct stuff {
char name[l6];
/ * other stuff could go here, too * /
};
struct stuff array [] = {
{ "The" },
{ "quick" },
{ "brown" >,
{ "fox" },
{ "jumped" },
{ "over" },
{ "the" },
{ "lazy" },
{ "dog. " },

{ " " }
};
main ( )
{
struct stuff * p0 = &.array[0];
struct stuff * p8 = &-array[8];
ptrdiff_t diff = p8-p0;
ptrdiff_t addr.diff = (char * ) p8 - (char * ) p0;

printf ("&array[0] = p0 = %P\n" , (void* ) p0);
printf ("&. array[8] = p8 = %P\n" , (void* ) p8) ;
*/
cast the ptrdiff_t's to long's
(which we know printf () can handle)
*/
printf ("The difference of pointers is %ld\n" , (long) diff) ;
printf ("The difference of addresses is %ld\n" , (long) addr_diff);
printf ("p8-8 = %P\n" , (void*) (p8-8));
/ * example for FAQ VII. 8 * /
printf ("p0 + 8 = %P (same as p8)\n", (void* ) (p0 + 8));
return 0; / * see FAQ XVI. 4 * /
}
  • 4楼网友:一秋
  • 2021-01-12 11:43
可以啊本质上指针也是变量不过指针有大小
一般用指针相减来求偏移或者空间大小
对char的指针来说相差1内存相差1byte
对int的指针来说差1内存地址相差4个byte
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息!
大家都在看
推荐信息