Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 理解指针和数组_C_Arrays_Pointers - Fatal编程技术网

C 理解指针和数组

C 理解指针和数组,c,arrays,pointers,C,Arrays,Pointers,有人能解释一下数组是如何通过名称引用的,比如在指针和双指针前面加上它的名称,如下面的代码所示: #include<stdio.h> main() { int a[3][2]; a[0][0]=15; a[0][1]=150; a[1][0]=115; a[1][1]=165; a[2][0]=135; a[2][1]=139; printf( "%u\n", a); printf( "%u\n", *a);

有人能解释一下数组是如何通过名称引用的,比如在指针和双指针前面加上它的名称,如下面的代码所示:

#include<stdio.h>

main()
{  
    int a[3][2];
    a[0][0]=15;
    a[0][1]=150;
    a[1][0]=115;
    a[1][1]=165;
    a[2][0]=135;
    a[2][1]=139;
    printf( "%u\n", a);
    printf( "%u\n", *a);
    printf( "%u\n", **a);
}
#包括
main()
{  
INTA[3][2];
a[0][0]=15;
a[0][1]=150;
a[1][0]=115;
a[1][1]=165;
a[2][0]=135;
a[2][1]=139;
printf(“%u\n”,a);
printf(“%u\n”,*a);
printf(“%u\n”,**a);
}
第一个

printf("%u\n",a);
打印
a
的地址,该地址与第一个元素的地址相同

第二个

printf("%u\n",*a);
取消引用
a
,并给出
a

第三个呢

printf("%u\n",**a);
取消引用指向
a
的第一个“行”的指针,并给出此二维数组中第一个元素的值

当您在编译示例时打开了警告时,编译器已经在抱怨,因此会告诉您所使用的某些类型。将指针作为参数时,应使用格式说明符
%p

printf("%p\n",a);
printf("%p\n",*a);
格式说明符
%u
用于
无符号int
,如果有
int
,最好使用说明符
%d

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

a
*a
都是指针,所以在格式化输出中打印它就像在
printf()中一样使用
%p
作为格式说明符

否则,编译器将显示警告消息

警告:格式“%x”要求类型为“unsigned int”,但参数2的类型为“int(*)[2]”
警告:格式“%x”要求类型为“unsigned int”,但参数2的类型为“int*”

所以试试这个:

printf("%p\n",a);
printf("%p\n",*a);
对于第三种情况,
**a
属于
int
类型,因此最好使用
%d
%i

printf("%d\n",**a);
根据C标准,

ISO c99 standard : 7.19.6 Formatted input/output functions

9   If a conversion specification is invalid, the behavior is undefined.

    If any argument is not the correct type for the corresponding conversion 

    specification, the behavior is undefined.

这就像a是地址而不是*a是a的值一样


除非它是
大小的
\u Alignof
或一元的
&
运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字,否则“T
的N元素数组”类型的表达式将被转换(“衰减”)为“指向
T
的指针”类型的表达式,表达式的值将是数组第一个元素的地址

在第一个
printf
调用中,表达式
a
的类型为“int的2元素数组的3元素数组”;根据上述规则,表达式将转换为类型“指向
int
的2元素数组的指针”(
int(*)[2]
),其值与
&a[0]
相同

在第二个
printf
调用中,表达式
*a
的类型为“int的2元素数组”;根据上述规则,表达式将转换为类型“指向
int
”(
int*
),其值将与
&a[0][0]
相同(与
&a[0]
相同-数组的第一个元素的地址与数组本身的地址相同)


在第三个
printf
调用中,表达式
**a
具有type
int
,其值是存储在
a[0][0]
中的任何值(在本例中为15)。

对类型的检查是有益的

a
具有类型
int[3][2]
,即一个由3个数组和2个int组成的数组。但是,不能在C中分配或传递数组类型。将
a
传递给
printf
时发生的情况是,它降级为指向其第一个参数的指针,即
&a[0]
,该参数具有类型
int(*)[2]
,即指向2个整数数组的指针。这就是你看到的地址

(当然,数组的第一个参数的地址也与数组本身的地址相同,因此如果您使用
printf(“%u”,&a);
,您将看到相同的地址值(但类型不同--
&a
将具有type
int(*)[3][2]

接下来,
*a
。您只能取消引用指针,因此
a
首先降级为指针(
&a[0]
),然后取消引用(
*&a[0]
)。结果是
a[0]
,是
a
的第一个元素<代码>一个[0]具有类型
int[2]
,即2个int的数组。同样如上所述,数组无法传递,因此当您将其传递给
printf
时,它将降级为指向其第一个参数的指针,即
&a[0][0]
,该参数的类型为
int*
,指针指向int。这是您看到的第二个地址。同样,由于
a[0]
的地址与其第一个元素
a[0][0]
的地址相同(但类型不同),因此它将与上述地址相同


最后是
**a
。如上所述,
*a
a
,先降级,然后取消引用。请记住上面的
*a
具有类型
int[2]
,一种数组类型。与
a
类似,当您取消引用它时,它会在取消引用之前将其隐式降级为指针。因此,
**a
a
,降级、取消引用、降级,然后再次取消引用。对正在发生的事情的更明确的描述是
*&(*&A[0])[0]
。最终结果是
a[0][0]
,其类型为
int

请更好地解释您的问题。我只看到代码无效(前两个
printf
语句)。可能重复的请注意,在案例1和案例2中使用
%u
是不正确的。
printf(“%u\n”,a/*a)
在前两个案例中应该是
printf(“%p\n”,a/*a)
。它应该是
printf(“%d\n”**a)在最后一种情况下。请考虑更新答案以添加这一点。对于迂腐,指针应该被转换成<代码>空白>代码>。在指向不同类型的指针大小不同的平台上,这实际上很重要(但这些平台可能是假设的)