为什么&p和&a [0]不同?

时间:2018-10-02 11:43:13

标签: c arrays pointers printf

#include <stdio.h>

int main(void) {
    int a[4][2] = { {11, 12}, {21, 22}, {31, 32}, {41, 42} };
    int *p = a[0];

    printf("%d\n", *p);

    printf("%d\n", p); 

    printf("%d\n", a[0]);

    printf("%d\n", &p);

    printf("%d\n", &a[0]);

    printf("%d\n", a); 

    return 0;
}

看上面的代码。

据我了解,由于p等于a[0],因此&p&a[0]应该具有相同的值。

但是实际输出如下:

11
1772204208
1772204208
1772204200
1772204208
1772204208

&p&a[0]为什么不同?

&p代表什么?

6 个答案:

答案 0 :(得分:12)

create-react-app产生指针&p的地址,该地址显然必须与p的地址不同。

答案 1 :(得分:5)

p是一个指向整数的指针。它存储在一个地址中,并且还存储一个地址。

打印p将打印指向p的地址。

打印*p将打印指向p的值。

打印&p会打印p的地址,该地址是p唯一的,并且在声明时即已分配。

int *p_2 = &p;

p_2将具有与&p相同的值

每个变量都有其唯一的地址!

答案 2 :(得分:3)

p是指向数组a[0]的指针:

int *p = a[0];

内存视图如下所示:

        a[0][0] a[0][1]
        +-------------+
   a[0] |  11  |  12  |
        +-------------+
        ^
        |
        p

由此可见,pa[0]是相同的指针,而&p&a[0]是不同的指针。

注意:
%d不是用于打印指针的正确格式说明符。相反,您应该使用%p

答案 3 :(得分:1)

  

据我了解,由于p等于a [0],所以&p和&a [0]应该具有相同的值。

pa[0]确实具有相同的值,但这并不意味着它们是相同的。就像您有两个变量ij定义为int i = 0, j = 0;一样,ij的值相同,但显然具有不同的地址,这是事实。

还请注意,您的代码具有未定义的行为,因为%d不是指向int的指针的适当转换说明符。您应该%p并将指针强制转换为(void*)%llu,并将指针强制转换为(unsigned long long)(uintptr_t)puintptr_t<stdint.h>中定义。

这是更正的版本:

#include <stdio.h>

int main(void) {
    int a[4][2] = { {11, 12}, {21, 22}, {31, 32}, {41, 42} };
    int *p = a[0];

    printf("   *p: %d\n", *p);
    printf("    p: %p\n", (void*)p); 
    printf(" a[0]: %p\n", (void*)a[0]);
    printf("   &p: %p\n", (void*)&p);
    printf("&a[0]: %p\n", (void*)&a[0]);
    printf("    a: %p\n", (void*)a); 
    return 0;
}

输出:

   *p: 11
    p: 0x7fff5144d950
 a[0]: 0x7fff5144d950
   &p: 0x7fff5144d948
&a[0]: 0x7fff5144d950
    a: 0x7fff5144d950

如您所见,数组a与第一行a[0]具有相同的地址,这也是a[0][0]指向的p的地址。 / p>

&a[0]a[0]不同:相同的地址但类型不同:a[0]是2个int的数组,&a[0]是一个数组的地址之2 int&a[0] + 1指向a[1],而a[0] + 1指向a[0][1]

很抱歉,我无法用简单的术语来解释这一点,采用数组的地址非常令人困惑:您可以实现相当高级的C编程级别,而无需了解这些细节。请记住,在大多数表达式上下文中,数组会作为其第一个元素的指针衰减(除了作为sizeof的参数),并且永远不要在数组上使用addressof运算符(&)。

答案 4 :(得分:1)

在C中,“&”表示“地址”。它表示&p表示p的地址。要记住的一件事是,指针也是一个变量,可以存储另一个变量的地址。C编程的特性是声明了一个新变量,它将为该变量分配一个不同的存储位置(地址)以存储该变量的值。因此,变量值与变量地址不同。在您的代码中,a [0]和p都是不同的变量。因此两者都有不同的内存位置。

所以请尝试了解以下内容

int * p = a [0]; 上面这行的意思是a [0]的地址存储在变量p中。这意味着p的值是a [0]的地址。所以p等于&a [0]。

现在考虑以下代码(不在您的代码中) int ar [10]; int * k = ar; 上面的两行代码是C语言中的有效代码。请考虑第二行代码。由于ar分配了k,我们必须了解一件事,它们都是相同类型的变量。这意味着ar也是指针。ar表示ar数组中第一个元素的地址,即a [0]。这意味着ar和&a [0]都相同。 如果我们将上述内容与您的代码相关联,我们得出结论

&a [0],p,a相同,代表相同的地址。 * p,a [0]相同,表示数组中第一个元素的值。

希望这对您有帮助...

答案 5 :(得分:0)

p是一个指针,它是一个包含内存地址的变量。

运算符&给出您正在使用它的对象的地址,因此&p表示指针的地址。