C 以这种方式声明和初始化指针需要什么:int(*p)[n]
我正在学习指针算法,有一个例子是关于精确地利用指针处理二维数组的列。为了做到这一点,代码向我展示了一个新的指针声明,下面是代码片段:C 以这种方式声明和初始化指针需要什么:int(*p)[n],c,pointers,C,Pointers,我正在学习指针算法,有一个例子是关于精确地利用指针处理二维数组的列。为了做到这一点,代码向我展示了一个新的指针声明,下面是代码片段: inta[NUM_ROWS][NUM_COLS],(*p[NUM_COLS],i; ... for(p=&a[0];p
inta[NUM_ROWS][NUM_COLS],(*p[NUM_COLS],i;
...
for(p=&a[0];p<&a[NUM_ROWS];p++)
(*p)[i]=0;
这个指针((*p)[NUM_COLS])的行为对我来说很奇怪,因为我刚刚了解到,递增指针的行为就像递增数组下标一样,允许您处理该指针指向的数组。所以这不是一个常规指针
大小(以字节为单位)是相同的,但是如果在for循环中赋值时它代表整行,那么该声明涉及到什么呢
int (*p)[NUM_COLS];
本质上定义了一个指针p
,它是指向带有NUM\u COLS
元素的int
s数组的指针
因此,它可以用作
int arr[NUM_COLS] = {0};
p = &arr;
它与所有其他指针具有相同的属性
- 指针的类型是
int(*)[NUM\u COLS]
- 此指针指向的实例的大小是
,即int[NUM\u COLS]
的大小乘以int
NUM\u COLS
- 类似于
int (*p)[NUM_COLS];
本质上定义了一个指针p
,它是指向带有NUM\u COLS
元素的int
s数组的指针
因此,它可以用作
int arr[NUM_COLS] = {0};
p = &arr;
它与所有其他指针具有相同的属性
- 指针的类型是
int(*)[NUM\u COLS]
- 此指针指向的实例的大小是
,即int[NUM\u COLS]
的大小乘以int
NUM\u COLS
- 正如@SouravHhosh所写,它定义了指向整数数组的指针。任何指针算法都是数组大小的乘积
正如@SouravHhosh所写,它定义了指向整数数组的指针。任何指针算法都是数组大小的乘积 将
p
声明为指向T
的N元素数组的指针。您主要在以下上下文中看到它们:
- 由于高维数组表达式“衰减”为指针表达式李>
- 为高维数组分配内存时李>
作为前者的一个例子,考虑下面的代码:
void foo( int (*p)[3] )
{
// do something with p
}
int main( void )
{
int arr[2][3];
foo( arr );
}
除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化声明中字符数组的字符串文字,否则“T的N元素数组”类型的表达式将被转换(“衰减”)为“指向T
的指针”类型的表达式,表达式的值将是数组第一个元素的地址
当您将表达式arr
作为参数传递给foo
时,它将从类型“int的3元素数组的2元素数组”(int[2][3]
)转换为“指向int的3元素数组的指针”(int(*)[3]
)。因此,函数实际上接收的是指针值,而不是数组
由于指向数组的指针语法有点难看和麻烦,您可以交替使用
void foo( int p[][3] ) { ... }
用于声明,但仅在函数参数声明中
作为后者的一个示例,如果要动态声明二维数组,可以执行以下操作:
int (*p)[3] = malloc( 2 * sizeof *p );
它为int
的2x3数组分配空间,并将指向该空间的指针分配给p
。表达式p
的类型是“指向int
的三元素数组的指针”,因此*p
的类型是“int的三元素数组”
请记住,数组下标操作a[i]
定义为*(a+i)
——给定起始地址a
,从该地址偏移i
元素(而非字节),并取消对结果1的引用。因此,可以得出如下结论:
*p == *(p + 0) == p[0]
意义
(*p)[i] == (*(p + 0))[i] == (p[0])[i] == p[0][i]
因此,在为p
分配内存后,您可以像任何2D数组一样对其进行索引:
for ( size_t i = 0; i < 2; i++ )
for ( size_t j = 0; j < 3; j++ )
p[i][j] = some_value;
由于下标[]
和函数调用()
运算符的优先级高于一元*
,*a[i]
将解析为*(a[i])
,*f()
将解析为*(f())
。如果要将a
视为指向数组的指针,将f
视为指向函数的指针,则必须使用括号-(*a)[i]
和(*f)(
)将*
运算符与标识符显式分组
*(a+i)
语法是有意义的,因为a
始终是一个指针。当Ritchie设计C时,他不想在数组中保留显式指针,因此他引入了一条规则,即数组表达式“衰减”到指针,除非在特定情况下。
将p
声明为指向T
的N元素数组的指针。您主要在以下上下文中看到它们:
- 由于高维数组表达式“衰减”为指针表达式李>
- 为高维数组分配内存时李>
作为前者的一个例子,考虑下面的代码:
void foo( int (*p)[3] )
{
// do something with p
}
int main( void )
{
int arr[2][3];
foo( arr );
}
除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化声明中字符数组的字符串文字,否则“T的N元素数组”类型的表达式将被转换(“衰减”)为“指向T
的指针”类型的表达式,表达式的值将是地址o