对C指针的质疑
我试图理解C语言的基本概念。我有两个问题: 1.为什么下面的代码可以工作,而另一个不能对C指针的质疑,c,C,我试图理解C语言的基本概念。我有两个问题: 1.为什么下面的代码可以工作,而另一个不能 /* This works fine */ typedef int SortTableRows[20]; SortTableRows* SortTableRowsPtr; /* This will give error --> subscripted value is neither array nor pointer*/ int SortTableRows[20]; SortTableRow
/* This works fine */
typedef int SortTableRows[20];
SortTableRows* SortTableRowsPtr;
/* This will give error --> subscripted value is neither array nor pointer*/
int SortTableRows[20];
SortTableRows* SortTableRowsPtr;
typedef int SortTableRows[20];
SortTableRows* SortTableRowsPtr;
SortTableRowsPtr[2][3]=2; //Why the compiler doesnt give any error?how can we use a pointer as a 2d array.
您已经将
SortTableRows
定义为int
与int-SortTableRows[20]
的数组。该标识符现在已固定为数组,不能用于任何其他用途。然后,您尝试将其用作声明指针的类型(我认为)。如果要声明指向int数组的指针,请执行以下操作:
int *SortTableRowsPtr;
SortTablesRowPtr = SortTablesRows;
在第二个问题中,您将为指针分配一个值,该指针指向一个被视为二维数组的指针,这对编译器没有实际意义(尽管在本文中没有实际意义),因为“多维”数组以线性方式存储在内存中,与一维数组相同。您的typedef
在这里没有任何实际意义,因为您正在定义一种类型的数组,然后创建一个未初始化的指向它的指针(这会创建一个int**
),然后访问它,就好像它指向某个有效的东西一样(这会编译,但肯定会崩溃)
要完成此工作,您需要定义一个20整数的数组,然后指向它:
SortTablesRows table[10] = {}; // equivalent to int table[10][20];
SortTablesRowPtr = table;
这是因为您正在声明一个指向20整数数组的指针,即
int (*SortTablesRowPtr)[20];
我已经扩展了这个答案。这有助于更简单地一步一步地解释它。以一个3行10列的表格为例。定义如下:
int table[3][10];
然后可以设置指向此表的指针。因为它是二维的,这是不对的:
int *ptr = table; // wrong - incompatible pointer
但这将指向第二行(和第一列):
换句话说,您需要一个指向10个整数的数组的指针,也就是说,您需要一个指向int n[10]
类型的指针。为此,您可以编写:
int (*ptr2)[10] = table;
现在,您可以使用ptr2
直接访问表,可以作为指针、数组,也可以同时作为指针和数组。它指向第一行和第一列。如果将一个添加到ptr2
中,它将选择下一行
ptr2[1][3] = 3; // change row 2, column 4
(*(ptr2 + 1))[4] = 10 // row 2, column 5 (yuck)
问题1
在第一个示例中,您告诉它SortTablesRow是一个包含20个整数的数组。所以SortTablesRow是一种类型。在第二个示例中,您将创建一个名为SortTablesRow的变量,它是一个包含20个整数的数组。无法将其用作类型,因为它是变量
问题2
在这里,您正在将SortTablesRow定义为一个20整数的数组。然后说SortTablesRowPtr是指向它的指针。现在有了一个指向20个整数数组的指针。这本质上是一个int**。因此,第一个数组索引索引第一个指针,第二个数组索引索引第二个指针(或数组),从而查找20个元素的int数组 您试图使用
SortTableRows
作为类型名和变量名;你当然会遇到困难;)关于你的第二个问题:我已经有20年没有写过C了,但是指针和数组基本上是可以互换的。因此,引用第二列的3行(或者你想怎么称呼它)并不是一个语法错误——只是不寻常而且可能会混淆代码>,SortTableRows
成为标识符。SortTableRows*SortTableRowsPtr
的解释是什么。它会是int*SortTableRowsPtr
?类型声明语句中的[20]
有什么意义吗?@Ganesh:是的,定义SortTableRows*SortTableRowsPtr
使指针运算成为可能-因为SortTableRowsPtr
指向的元素的大小已知(sizeof(int[20])
。请记住,a[n]
,*(a+n)
甚至n[a]
(不是开玩笑的)都是同一个意思。难道int**
类型的x
不是吗?原始问题的代码非常好-SortTableRowsPtr
相当于int**
。第一次取消引用将指针移动2*sizeof(SortTableRows)
,并给出SortTableRows
,这相当于int*
。问题第二部分中的行为是完全定义的,只要将SortTableRowsPtr
初始化为真正的SortTableRows[]
@CodePainters:非常好的观点,这将教会我在睡觉前发布帖子;)你说int*ptr=table
不起作用是错的。它工作正常,ptr
指向为数组分配的内存的第一个元素。然而,现在关于这是一个数组的信息更少了。它已降级为指针。真正的关键是编译器在决定类型和如何处理指针算法时拥有多少信息。我通常试图将数组看作是从第一个元素的地址开始的连续分配内存。试图以任何其他方式思考它会很快导致混乱和错误。@AxelOmega:我的意思是在这种情况下,它不会起作用int*ptr=table
将编译,但它不是一种兼容的指针类型,如果您想以任何有意义的方式访问该表,它将是不正确的。这意味着它是正确的。但是,您仍然可以使用ptr[row*10+col]
以合理的方式访问它。从这个意义上讲,C语言中的多维数组很棘手。这就是我一直认为数组是一块分配的内存的意思。当你也将数组作为参数传递给函数时,这样想就容易多了。@AxelOmega:我知道你的意思,但如果你想以这种方式访问它(至少是为了消除编译器警告)int*p=(int*)table
ptr2[1][3] = 3; // change row 2, column 4
(*(ptr2 + 1))[4] = 10 // row 2, column 5 (yuck)