【问题标题】:Char pointer arithmetic C字符指针算术 C
【发布时间】: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


    【解决方案1】:

    您提出问题的结果未定义。为了使指针差分正常工作,它们必须来自相同的数组序列(动态、自动甚至自动 VLA 都没有区别)。或最后一个元素过去的地址:

    §6.5.6 加法运算符 (p9)

    当两个指针相减时,都指向同一个数组对象的元素,或者指向数组对象最后一个元素的元素;结果是两个数组元素的下标之差。结果的大小是实现定义的,其类型(有符号整数类型)是ptrdiff_t 定义在<stddef.h> 标头中。如果结果在该类型的对象中不可表示,则行为未定义。换句话说,如果表达式PQ 分别指向数组对象的i-thj-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
    

    从标准的引用部分解释了原因。

    【讨论】:

      【解决方案2】:

      已编辑

      这个问题的答案视情况而定。

      1) 在你的情况下,由于指针没有指向任何东西,结果将是垃圾

      2) 如果两个指针指向程序空间中的两个有效内存位置,则结果将是这两个位置之间的内存字节数。虽然这没有任何意义,并且根据 C 规范它是 UB,如果两个指针没有指向同一个数组或字符串。如果两个指针指向同一个数组或字符串,则结果将是同一数组中两个元素之间的元素数(当指针指向该数组内的这两个元素时)。查看this SO question 以获取示例和更多解释。

      【讨论】:

      • 我会说 2) 只有当两个指针都指向同一个“对象”时才有效。
      • “结果将是这两个位置之间的内存字节数”是一个常见的结果,但 C 规范没有定义 - 它是 UB。其他结果可能包括程序错误或f 中的无意义值。
      【解决方案3】:

      f = str2 中的内存地址 - str1 中的内存地址。 "foo""foobar" 是这些指针指向的这些内存位置的值。

      例子:

      如果str2 = 0x8000000a

      str1 = 0x80000000

      str2 - str1 = 0x8000000a - 0x80000000 
      str2 - str1 = 0x0a 
      

      【讨论】:

      • 我想说这只有在两个指针都指向同一个“对象”时才有效。
      • 不一定,例如:char * str2 = &amp;a, char * str1 = &amp;b 然后地址在堆栈上,我上面的答案将有不同且不连续的内存位置。
      • 请看WhozCraig的回答:stackoverflow.com/a/31738328/694576(什么是ab,顺便说一句?)
      • ab 是局部变量。
      • "地址在堆栈上,我上面的答案将有不同且不连续的内存位置。"没有由 C 指定。“堆栈”甚至没有由 C 指定。结果取决于平台/编译器,因为它是未定义的行为。
      猜你喜欢
      • 2016-11-02
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多