【问题标题】:Why it is possible to assign string to character pointer in C but not an integer value to an integer pointer为什么可以将字符串分配给 C 中的字符指针,但不能将整数值分配给整数指针
【发布时间】:2018-03-26 17:11:27
【问题描述】:

为什么在下面的代码中 int *p = 22 会给出编译时错误,而 ptr 会成功打印该值。

int main()
{

/*taking a character pointer and assigning a string to it*/
char *ptr = "Stackoverflow" ; //correct

/*taking a int pointer and assigning a string to it*/
int *p = 22 ; //incorrect

printf("%s",ptr); // correct and print
printf("%d",p); //incorrect and give compile time error.

return 0;
}

【问题讨论】:

    标签: c literals string-literals


    【解决方案1】:

    如果你有一个字符数组例如

    char s[] = "Stackoverflow";
    

    然后将表达式中使用的数组指示符转换为指向其第一个元素的指针。所以你可以写

    char *ptr = s;
    

    指针ptr 现在指向数组s 的第一个字符。

    C 中的字符串字面量也表示为字符数组,并像字符数组一样存储在内存中,具有静态存储持续时间。

    例如,字符串文字 "Stackoverflow" 的类型为 char[14](包括终止零)。

    那你写

    char *ptr = "Stackoverflow";
    

    那么这个说法其实如果有的话也一样

    static char unnamed[] = "Stackoverflow";
    char *ptr = unnamed;
    

    至于这个说法

    int *p = 22 ;
    

    然后整数文字不会转换为指向自身的指针。它实际上代表数字 22,仅此而已。

    因此编译器会发出一条消息,因为如果您希望指针确实包含整数值 22,那么您必须使用强制转换。

    表达式

    22 == 22
    

    总是产生true

    虽然这个表达式

    "Stackoverflow" == "Stackoverflow"
    

    没有必要产生true,因为根据编译器选项,编译器可以将巧合的字符串文字放置在不同的内存区域中。在这个表达式中,比较的是指向字符串文字的第一个字符的指针。

    考虑到如果你要输出一个由指针指向的整数对象,你需要使用解引用。所以无论如何,而不是

    printf("%d",p); 
    

    你应该写

    printf("%d", *p); 
    

    或者如果你想输出存储在指针中的值,你必须使用另一个格式说明符

    printf("%p", p); 
    

    【讨论】:

      【解决方案2】:

      因为字符串实际上是一个 char 数组,并且在将数组分配给变量时,数组将表现为指向数组第一个元素的指针。这可能会令人困惑。更多信息在这里:

      when does a array act as a pointer in c?

      另一方面,整数只是一个整数,而不是整数数组。

      【讨论】:

        【解决方案3】:

        这一行将内存地址分配为 22。这是不正确的。虽然这一行编译时只会出现警告,但当您稍后在代码中尝试访问内存地址 22 时,它会在运行时使您的程序崩溃。

        int *p = 22 ; //incorrect
        

        这将为您提供您正在寻找的结果:

        int *p = NULL;
        int val = 22;
        p = &val;
        

        还有

        printf("%d",p); //incorrect and give compile time error.
        printf("%d",*p); //you must derefence the pointer
        

        %s 接受一个指向 char 的指针,它是一个以 null 结尾的字符串,而 %d 接受一个 int,而不是一个 int*

        【讨论】:

        • 如果我们给出一些有效地址,那么整数指针将采用例如 int *ptr = 0xc0563321
        • 如果该地址被分配用于保存int,理论上应该可以。如果该地址未分配,您的程序将崩溃。话虽如此,这不是您愿意或应该做的事情。如果您尝试编译该行,您会注意到编译器警告“int* 在间接级别上与 int 不同”,其中 22 是 int。发出这个警告是有充分理由的!您只能使用callocmalloc& 运算符来分配指针。
        • @Vlad 很好地解释了为什么char *ptr = "Stackoverflow" 有效。
        猜你喜欢
        • 2011-10-11
        • 1970-01-01
        • 1970-01-01
        • 2014-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多