【问题标题】:Assigning Address of String Literal to a pointer将字符串文字的地址分配给指针
【发布时间】:2015-10-12 15:33:06
【问题描述】:

将字符串文字的地址分配给字符指针有什么区别吗?

char *ptr = &"Hello";
printf("%s",ptr);

当我打印时,它正确打印了“Hello”。 这类似于将数组的地址分配给指针吗?这种方式分配地址有什么用吗? &"Hello" 返回什么?指向字符的常量指针?

char a[]="Hi";
char *ptr2 = &a;

&a+1 也将打印数组边界之外的地址。但是我们不能使用它来获取它看起来的数组的大小。我尝试打印类似下面的数组内容,但它只打印一个字符。

for(i=0;i<((&a+1)-&a);i++)  printf("%c",*ptr2++);

【问题讨论】:

    标签: c gcc


    【解决方案1】:
    char *ptr = &"Hello";
    

    这是无效的。编译器会发出警告。

    "Hello" 的类型是 char[6]&amp;"Hello" 的类型是 char(*)[6]。像这样声明和初始化ptr -

    char (*ptr)[6] = &"Hello";     // ptr is pointer to array of char of size 6
    

    for 循环中,您的条件 -

    i<((&a+1)-&a);   // it should be i<(*(&a+1)-a);
    

    但是不要这样做,因为它会调用未定义的行为

    To know more about it refer here.

    【讨论】:

    • 注意到编译器警告被禁用。现在我至少收到了警告。
    • @JonWheelock 好吧,你应该总是启用编译器警告:)
    • 也只是为了好奇,我如何打印地址 (&a)+1 而不是 &a+1?如果我放括号,它仍然会打印超出数组边界的地址值。例如在下面的代码中,我希望最后一个打印语句显示 0028FF05 而不是 0028FF10。不允许向 (ptr*)[] 添加常量吗? char a[] = "你好世界";字符 (*ptrToEntireArray)[] = &a; printf("&ptrToEntireArray = %p\n",&a); printf("&ptrToEntireArray+1 = %p\n",(&a)+1);结果:&ptrToEntireArray = 0028FF04 &ptrToEntireArray+1 = 0028FF10
    • @JonWheelock 打印地址超出边界不是问题,但尝试读/写将有未定义的行为。因此,我认为打印该地址应该没有任何问题。
    • 我的问题是:如果 printf("%p",&a) 打印 0028FF04,我该如何打印地址 0028FF05?添加 1 会将整个数组的大小添加到第一个地址。我想用 &a 打印绝对地址 0028FF05。请注意,这只是为了好奇,而不是在编码中使用它。还有 &a 有什么用吗?
    【解决方案2】:
    char *ptr = &"Hello";
    

    你的编译器应该已经警告你了。 "Hello" 的类型为 char[6](字符串长度加 1 表示终止 '\0' 空字符)。所以&amp;"Hello" 的类型是char (*)[6],或指向6 个chars 的数组的指针。没有从该类型到 char* 的隐式转换。

    如果你想要一个指向字符串的指针,删除&amp;:

    const char *ptr = "Hello";
    

    这利用了数组类型的表达式(例如"Hello")隐式转换为指向数组第一个元素的指针的规则。(如果数组是一元@的操作数,则不进行此转换987654333@ 或 sizeof 运算符,或者是用于初始化数组对象的字符串字面量。)

    (我添加了const,因为它更安全;你不能合法地修改字符串文字的内容,const 提醒编译器不要让你尝试。感谢 Bathsheba 提醒我。 ) (实际上修改内容具有未定义的行为。长话短说。)

    您会注意到ptr 指向字符串的第一个字符,而不是整个字符串。这(可能)正是你想要的。在 C 中,数组通常通过指向其元素的指针而不是通过指向整个数组的指针来操作。指针算法用于遍历数组并访问其所有元素。

    请务必记住,构造指向数组初始元素的指针不会记住数组的大小。您必须自己跟踪。如果数组包含字符串,您通常会查找终止符'\0',或使用执行此操作的函数。对于其他数组,通常单独存储长度。例如,一个函数可能有两个参数,一个数组的初始元素的地址和一个包含元素数量的整数 (size_t)。

    建议阅读:comp.lang.c FAQ 的第 6 节。

    【讨论】:

    • 加一个虽然我更愿意看到const char *ptr
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多