Cir*_*red 6 c arrays malloc syntax pointers
我最近遇到了以下情况:
int ( *array )[10] = malloc(...);
Run Code Online (Sandbox Code Playgroud)
基于我对C语法和语法的理解,这看起来像废话.看起来像正在创建(并初始化)一个数组,其中取消引用指针的值作为其标识符.
我理解指向数组的指针,并且通常至少使用malloc()在堆上分配它们.例如,这是有道理的:
int *array = malloc(sizeof (int*) * 10);
Run Code Online (Sandbox Code Playgroud)
...但是,第一个例子看起来像不应该编译的乱码.显然,我错过了一些东西.
当我学习C时,我觉得我看到了回来的东西,但谷歌搜索并没有帮助我理解.使用术语"指针","解除引用"和"初始化"进行搜索显然会给结果带来污染,这些结果会跟踪人们如何跟踪解除引用等等.我希望人类可以帮助我.
das*_*ght 11
这是完全合法的 - 您正在分配一个指向十个整数数组的指针.
如果您只需要一个阵列*,那么...在您的完成中malloc使用的好方法是:sizeof(*array)
int ( *array )[10] = malloc(sizeof(*array));
Run Code Online (Sandbox Code Playgroud)
例如,这是有道理的:
int *array = malloc(sizeof (int*) * 10);
这是一个ints 数组.第一种语法允许您创建一个ints 数组数组- 例如
int ( *array )[10] = malloc(50*sizeof(*array));
Run Code Online (Sandbox Code Playgroud)
给你一个50×10阵列.
*这里有一个很好的解释,为什么sizeof(*array)这是分配大小的好方法.
int ( *array )[10] = malloc(...);
Run Code Online (Sandbox Code Playgroud)
声明array为指向10元素数组的指针int; 使用malloc调用结果初始化指针.这和写作一样
int (*array)[10] = NULL;
array = malloc( ... );
Run Code Online (Sandbox Code Playgroud)
记住这一点
T *p = malloc( sizeof *p * N );
Run Code Online (Sandbox Code Playgroud)
将分配足够的存储空间来保存N实例T并将结果指针值分配给p.这适用于任何类型T.
如果我们用T类似的数组类型替换R [10],我们得到
R (*p)[10] = malloc( sizeof *p * N );
Run Code Online (Sandbox Code Playgroud)
语义完全相同,所有改变的都是类型p; 我们正在分配足够的存储来保存N实例R [10].
基于我对C语法和语法的理解,这看起来像废话.
然后你需要重新审视这种理解.C的声明语法是很多更复杂的比大多数人的想法.请参阅在线C 2011标准的第6.7节.
编辑
以下是语法分解的方式:
int ( * array )[ 10 ] = malloc( ... );
^ ^ ^ ^ ^^ ^ ^ ^ ^
| | | | || | | | |
| | pointer direct || | | | assignment
| | | declarator || | | | expression
| | | | || | | | |
| | +-----+-----+ || | | | |
| | | || | | | |
| | declarator || | | | |
| | | || | | | |
| +---------+------------+| | | | |
| | | | | | |
| direct | assignment | | |
| declarator | expression | | |
| | | | | | |
| +-------------+-----+------+ | |
| | | |
| direct | |
| declarator | |
type | | |
specifier declarator | initializer
| | | |
| +---------------+-+
| |
| init-declarator
declaration |
specifiers init-declarator-list
| |
+----------------------+------------------------+
|
declaration
Run Code Online (Sandbox Code Playgroud)
我略去中间步骤10来assignment-expression从malloc(...)到initializer,因为他们刚刚制作图表难以阅读.
数组的地址和第一个元素的地址彼此相等.
所以如果你有一个数组,例如
int array[10];
Run Code Online (Sandbox Code Playgroud)
那么指针的值p和q
int *p = array;
Run Code Online (Sandbox Code Playgroud)
和
int ( *q )[10] = &array;
Run Code Online (Sandbox Code Playgroud)
尽管指针的类型不同,但它们将是相同的.
这些值等于数组的第一个元素的地址.在第一种情况下,元素的类型是int在第二种情况下元素的类型是int[10]但在这两种情况下,它是分配的内存范围的地址,不会根据它在C中的解释方式而改变.
您可以通过以下方式p从指针获取指针q
p = *q;
Run Code Online (Sandbox Code Playgroud)
考虑到该函数malloc返回一个指向void的指针,该指针的类型void *在C中可以隐式转换为任何其他类型的指针.
因此这些陈述
int ( *array )[10] = malloc( 10 * sizeof( int ) );
Run Code Online (Sandbox Code Playgroud)
和
int *array = malloc( 10 * sizeof( int ) );
Run Code Online (Sandbox Code Playgroud)
在C中有效
另一方面,函数free再次使用类型的指针作为其参数void *.并且可以将其他类型的指针隐式转换为该类型void *.
| 归档时间: |
|
| 查看次数: |
813 次 |
| 最近记录: |