k在C程序中存储了什么?

k在C程序中存储了什么?,c,pointers,C,Pointers,什么指针k存储?是b的k存储地址还是b的值???你可以说: int*k=b存储b的值 int(*j)[]=&b存储b的地址 但是,除了类型不同之外,这两个表示相同的内存地址,&b[0] 例如: int main () { int b[]={0,20,0,40,5}; int i,*k; k=b; } [编辑]为了澄清“可以说那”和“可以被认为是”两个部分,这两个部分都不意味着b[]字面上是int*。当然不是,变量b本身是一个int[]数组,如声明的那

什么指针k存储?是b的k存储地址还是b的值???

你可以说:

  • int*k=b
    存储
    b
    的值

  • int(*j)[]=&b
    存储
    b
    的地址

但是,除了类型不同之外,这两个表示相同的内存地址,
&b[0]

例如:

int main () {
    int b[]={0,20,0,40,5};
    int i,*k;
    k=b;
    
}

[编辑]为了澄清“可以说那”和“可以被认为是”两个部分,这两个部分都不意味着
b[]
字面上是
int*
。当然不是,变量
b
本身是一个
int[]
数组,如声明的那样。但是
b
每当在表达式中使用数组的第一个元素时,都会计算为指向该元素的
int*
指针,特别是在与C中的“值”概念最常见的两种情况下

  • Valueassignment”(“将值存储在由左操作数指定的对象中”。对于标量类型,这只是右侧值的副本,例如
    intv=123;INTO=v。但是,对于数组类型,等效值赋值存储指向数组开头的指针的值,例如
    intv[]={1,2,3};int*o=v

  • “按值传递”“调用函数时,表示()“对参数进行求值,并为每个参数指定相应参数的值”。作为参数传递的数组的“值”也是指向数组第一个元素的指针,例如
    intv[]={1,2,3};printf(“%p\n”,v)

(大多数)表达式中数组到指针的衰减如下所示:

除非是sizeof运算符的操作数、_Alignof运算符或一元&运算符,或者是用于初始化数组的字符串文字,否则类型为“类型的数组”的表达式将转换为类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素


正如任何一本像样的书、教程或课程都应该提到的那样,数组自然会衰减为指向其第一个元素的指针。这意味着赋值
k=b
等于
k=&b[0]
。如果两者都是呢,因为
b
的值是指向该数组的指针?@tadman,或者如果两者都不是呢
k
存储
b
的第一个元素的地址。IMO将第一个元素的地址描述为“b
的值”是一种误导,因为许多人对数组的心理模型不正确,认为它是由指针和内存块组成的二部结构。您描述了该指针的值,但实际上没有这样的指针。@M.M猜想您认为
b
的值是
{0,20,0,40,5}
,这在技术上是正确的,当然,也有不同的混淆方式
b[]
是一个“值”,当您尝试将它用作值时,它会衰减为指针-分配它,将它作为参数传递,等等。从这个意义上讲,
int*k=b可以被认为是
b
的值。错误地将
&b[0]
描述为
b
的值会在学生中造成误解,导致他们将来犯更多错误。数组不是指针。数组的值不是指针。这种草率和错误的想法或措辞是没有理由的。@EricPostphil我不是说(或写)数组的值是语言意义上的指针。然而,在许多情况下,数组引用会衰减为指针,在OP的问题中可以将其视为指针。为了澄清这一点,我在答案的末尾插入了一个编辑。
#include <stdio.h>

int main() {
    int b[]={0,20,0,40,5};

    int *k = b;
    int (*j)[] = &b;

    if((void *)k == (void *)j)
        printf("b (%p) == &b (%p) == &b[0] (%p)\n", k, j, &b[0]);

    return 0;
}
b (0x7ffe1535a5d0) == &b (0x7ffe1535a5d0) == &b[0] (0x7ffe1535a5d0)