C 指向数组和二维数组表示形式的指针
我对数组指针和2D数组的语法有疑问C 指向数组和二维数组表示形式的指针,c,arrays,pointers,C,Arrays,Pointers,我对数组指针和2D数组的语法有疑问 #include<stdio.h> #include<stdlib.h> void show ( int q[][4], int row ) { int i, j ; for ( i = 0 ; i < row ; i++ ) { for ( j = 0 ; j < 4 ; j++ ) printf ( "%d ", q[i][j] ) ; printf ( "\n" ) ;
#include<stdio.h>
#include<stdlib.h>
void show ( int q[][4], int row )
{
int i, j ;
for ( i = 0 ; i < row ; i++ )
{
for ( j = 0 ; j < 4 ; j++ )
printf ( "%d ", q[i][j] ) ;
printf ( "\n" ) ;
}
printf ( "\n" ) ;
}
int main( )
{
int a[][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 0, 1, 6}
} ;
show ( a, 3, 4 ) ;
return 0;
}
我读过这个
intq[][4]代码>
这与int(*q)[4]
相同,其中q
是指向4的数组的指针
整数。唯一的优点是我们现在可以使用更多
用于访问数组元素的熟悉表达式q[i][j]
问题:
show()
函数与这两个函数一起使用,int q[][4]
和int q[3][4]
来接收2D数组的地址
但这些是2D数组的表示,对吗
我们不能像下面这样分配2D
int (*a)[4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 0, 1, 6}
} ;
但2D可以通过此语句进行分配
int a[][4]={
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 0, 1, 6}
} ;
int(*a)[4]
与int a[][4]
不同,那么为什么“指向数组的指针”和“二维数组表示法”都可以在show函数中使用呢?数组不是指针,但在许多情况下,数组会衰减为指针,例如当作为函数参数传递时。因此,当您将int q[][4]
传递给函数时,函数将收到一个int(*q)[4]
,一个指向四个int
数组的指针。这就是为什么这两种形式都用作show()
的参数。但是对于声明和初始化,实际类型很重要,因此不能使用数组初始值设定项初始化指针。函数有关于数组参数的特殊规则,基本规则是,如果您说出函数的原型,并且您的第一个单词是数组,则将其更改为“指针指向”,以便
在一个函数中,这种转换不会发生,数组类型和指针类型之间有很大的区别
int a[] = {5, 3, 2};
这是合法的,但是
int *a = {5, 3, 2};
事实并非如此。通常,不能从数组初始值设定项中指定指针。相反,c99提供复合文字:
int *a = (int[]){5, 3, 2};
int (*a)[4] = (int [][4]){
{2, 2, 3, 1},
{2, 3, 5, 3},
};
首先,C标准中的一些语言:
6.3.2.1左值、数组和函数指示符
…
3除非它是sizeof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,类型为“类型的数组”的表达式转换为类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素,并且不是左值。如果数组对象具有寄存器存储类,则行为未定义。
在调用show
函数时,表达式a
的类型为“int
的4元素数组的3元素数组”。根据上述规则,在进行调用之前,此表达式将替换为“指向int
的4元素数组的指针”类型的表达式;因此,show
接收类型为int(*)[4]
的指针值,而不是数组
更标准的语言:
6.7.5.3功能声明器(包括原型)…
7作为“类型数组”的参数声明应调整为“类型限定指针”,其中类型限定符(如有)是数组类型派生的
[
和]
中指定的类型限定符。如果关键字static
也出现在数组类型派生的[
和]
中,则对于函数的每次调用,对应的实际参数的值应提供对数组第一个元素的访问,该元素的数量至少与大小表达式指定的元素数量相同。
因此,在函数参数声明的上下文中,ta[n]
、ta[]
和ta*a
都是等效的。如果T
是数组类型,例如“int的4元素数组”,那么int a[3][4]
、int a[][4]
和int(*a)[4]
都是等价的
请注意,这仅适用于函数参数声明。声明数组对象时,将使用以下语言:
6.7.8初始化…
22如果初始化了未知大小的数组,则其大小由具有显式初始值设定项的最大索引元素确定。在初始值设定项列表的末尾,数组不再具有不完整的类型。 所以当你写作的时候
int a[][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 0, 1, 6}
} ;
您正在声明一个int
的Nx4数组,而不是指向int
数组的指针——内部维度3是从初始值设定项中的4元素数组数推断出来的 有了int(*q)[4]
和intq[][4]
,q[i][j]
就可以了。
int *a = (int[]){5, 3, 2};
int (*a)[4] = (int [][4]){
{2, 2, 3, 1},
{2, 3, 5, 3},
};
int a[][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 0, 1, 6}
} ;