在C中分配指针,地址运算符和解引用指针

时间:2015-11-29 18:04:43

标签: c pointers

你能解释下面的代码,

int main() {
    int value = 2;
    int *ptrWithAmpersand = &value;
    int *ptrWithoutAmpersand = value;
    //printf("%d", *ptrWithoutAmpersand); 1) Why Runtime error.
    printf("Pointer with & --> %d\n", *ptrWithAmpersand);
    printf("Pointer withOUT & and * --> %d\n", ptrWithoutAmpersand); //2) Why this works??!!
    getch();
}

如代码中所述

  1. 为什么运行时错误?
  2. 为什么会这样?
  3. 输出

    Pointer with & --> 2
    Pointer withOUT & and * --> 2
    

2 个答案:

答案 0 :(得分:1)

在:

int *ptrWithAmpersand = &value;
printf("Pointer with & --> %d\n", *ptrWithAmpersand);

您正确地为指针分配地址,并在printf中正确取消引用它以使用%d参数打印int。

在:

int *ptrWithoutAmpersand = value;
printf("Pointer withOUT & and * --> %d\n", ptrWithoutAmpersand);

您无意中为指针指定了一个整数值,但由于在printf中您没有取消引用它,因此它将打印为带有int参数的%d。如果sizeof(int *) != sizeof(int),这只会导致问题(UB)。

在:

int *ptrWithoutAmpersand = value;
printf("%d", *ptrWithoutAmpersand);

你得到一个运行时错误,因为你要取消引用一个指向内存地址2的指针,这不是你的,所以系统会中止你的程序。

答案 1 :(得分:1)

在第

int *ptrWithAmpersand = &value;

您正在创建指向int的指针,并为其分配变量value地址。到目前为止一切都很好。

在第

int *ptrWithoutAmpersand = value;

您正在创建指向int的指针,并为其分配变量value(2)的内容。这导致了几个问题:

  1. 您正在尝试将类型int的值分配给类型为int *的变量,这些变量不是兼容类型;编译器至少应发出“赋值不兼容类型”或类似内容的警告(打开所有警告)

  2. 在您的系统上,2不是有效的对象地址,因此当您尝试取消引用 ptrWithoutAmpersand时会出现运行时错误。

  3. 您的代码中还有其他几个问题。您不应该使用%d转换说明符来打印指针值;为此目的始终使用%p

    这是对代码的轻微改写,使某些事情变得更加清晰:

    #include <stdio.h>
    
    int main() {
        int value = 2;
        int *ptrWithAmpersand = &value;
        int *ptrWithoutAmpersand = value; // throws a warning in gcc; you should not do this
    
        printf("value of expression \"value\" = %d\n", value );
        printf("value of expression \"&value\" = %p\n", (void *) &value );
        printf("value of expression \"ptrWithAmpersand\" = %p\n", (void *) ptrWithAmpersand );
        printf("value of expression \"*ptrWithAmpersand\" = %d\n", *ptrWithAmpersand );
        printf("value of expression \"ptrWithoutAmpersand\" = %p\n", (void *) ptrWithoutAmpersand );
    
        return 0;
    }
    

    以下是代码的输出:

    value of expression "value" = 2
    value of expression "&value" = 0x7ffecb63cf44
    value of expression "ptrWithAmpersand" = 0x7ffecb63cf44
    value of expression "*ptrWithAmpersand" = 2
    value of expression "ptrWithoutAmpersand" = 0x2
    

    注意如何打印指针表达式与整数表达式。

    简而言之:

    *ptrWithAmpersand    ==  value == 2        type == int
     ptrWithAmpersand    == &value             type == int *
     ptrWithoutAmpersand ==  value == 2        mismatched types int * and int