【发布时间】:2015-07-31 04:35:24
【问题描述】:
我正在学习指针算术,我遇到了这样的事情:
char *str1, *str2;
/* stuff in between */
int f = str2 - str1;
str2 - str1 返回的是什么?假设str1 = "foo" 和str2 = "foobar"。
【问题讨论】:
标签: c char pointer-arithmetic
我正在学习指针算术,我遇到了这样的事情:
char *str1, *str2;
/* stuff in between */
int f = str2 - str1;
str2 - str1 返回的是什么?假设str1 = "foo" 和str2 = "foobar"。
【问题讨论】:
标签: c char pointer-arithmetic
您提出问题的结果未定义。为了使指针差分正常工作,它们必须来自相同的数组序列(动态、自动甚至自动 VLA 都没有区别)。或最后一个元素过去的地址:
§6.5.6 加法运算符 (p9)
当两个指针相减时,都指向同一个数组对象的元素,或者指向数组对象最后一个元素的元素;结果是两个数组元素的下标之差。结果的大小是实现定义的,其类型(有符号整数类型)是
ptrdiff_t定义在<stddef.h>标头中。如果结果在该类型的对象中不可表示,则行为未定义。换句话说,如果表达式P和Q分别指向数组对象的i-th和j-th元素,则表达式(P)-(Q)具有值i-j,前提是该值适合ptrdiff_t.类型的对象 此外,如果表达式P指向数组对象的元素或数组对象的最后一个元素,则表达式Q指向同一数组对象的最后一个元素, 表达式((Q)+1)-(P)与((Q)-(P))+1和-((P)-((Q)+1))具有相同的值,并且如果表达式P指向数组对象的最后一个元素后一个,则值为零,即使表达式(Q)+1确实如此不指向数组对象的元素。106
也就是说,如果您改写以符合上述规则,则类似于:
#include <stdio.h>
int main()
{
const char *p = "Hello World";
const char *q = p+7;
printf("%td\n", q-p);
return 0;
}
输出
7
从标准的引用部分解释了原因。
【讨论】:
已编辑
这个问题的答案视情况而定。
1) 在你的情况下,由于指针没有指向任何东西,结果将是垃圾
2) 如果两个指针指向程序空间中的两个有效内存位置,则结果将是这两个位置之间的内存字节数。虽然这没有任何意义,并且根据 C 规范它是 UB,如果两个指针没有指向同一个数组或字符串。如果两个指针指向同一个数组或字符串,则结果将是同一数组中两个元素之间的元素数(当指针指向该数组内的这两个元素时)。查看this SO question 以获取示例和更多解释。
【讨论】:
f 中的无意义值。
f = str2 中的内存地址 - str1 中的内存地址。
"foo" 和 "foobar" 是这些指针指向的这些内存位置的值。
例子:
如果str2 = 0x8000000a
和str1 = 0x80000000
str2 - str1 = 0x8000000a - 0x80000000
str2 - str1 = 0x0a
【讨论】:
char * str2 = &a, char * str1 = &b 然后地址在堆栈上,我上面的答案将有不同且不连续的内存位置。
a和b,顺便说一句?)
a 和 b 是局部变量。