typedef struct node {
int value;
struct node* next;
}node;
int* to_array (node* ll, int size) {
int i = 0;
int* arr = malloc(size*sizeof(int));
while (ll) {
arr[i] = ll->value;
ll = ll->next;
i++;
}
return arr;
}
有人可以解释为什么
int* arr = malloc(size);
会给我们一个数组吗?我认为当我们有指针时,我们不能像arr[i] = 5
或其他东西那样单独更改它。
你的问题实际上是一个很好的问题。 当然,一个已经在SO上被问过和回答过很多次的问题。 但仍然是一个好问题。
从 C/C++ 常见问题解答:
http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr
数组不是指针,尽管它们密切相关(参见问题 6.3),并且可以类似地使用(见问题4.1、6.8、6.10和6.14)。
-
当您声明数组(例如
int a[5]
),您已经为五个"int"元素分配了存储空间。 您可以像a[i]
一样访问每个元素。 -
当您声明指针(例如
int *b
) 您尚未分配任何存储空间。 -
您可以同时声明和初始化指针:
int *b = NULL; /* Initialize to 0 */ ... OR ... int *b = malloc (5 * sizeof (int)); /* Allocate storage for 5 "int" elements */
-
当您声明数组
a
时,您从堆栈中分配了空间。 无法更改分配。当您声明
b
时,您分配了相同数量的空间,但您从堆中分配了空间。 此外,您可以随时更改b
以指向其他任何内容。 您还可以realloc()
内存以更改存储大小。 -
正如您可以使用索引语法
a[i]
一样,您可以使用完全相同的语法b[i]
。
此链接可能有助于解释: http://www.geeksforgeeks.org/g-fact-5/
附注: 当你"有指针"时,你绝对可以"像arr[i] = 5
或其他东西一样单独更改它"。
int *arr = malloc(size * sizeof(int));
不给出数组,它给你一个足够大的内存块来容纳size
整数。
arr[i] = ll->value;
语句使用指针算法:一个表达式arr + 5
表示获取arr
指向的整数的内存地址,并从那里向上移动 5 个位置。现在,因为编译器知道它正在使用int
指针,并且假设 32 位int
s,所以它将知道在arr
的值中添加 20(=5*4 字节)以找到第 6 个元素。
接下来,C 语言具有句法糖,其中表达式arr[5]
等效于*(arr + 5)
。
这也是为什么 C 中的数组从 0 开始索引,以及为什么 C 数组的名称也可以用作指向数组第一个元素的指针。
在此语句中
int* arr = malloc(size*sizeof(int));
函数 malloc 分配一个能够存储size
int
类型的对象的内存范围,并返回指向此范围的指针(或指向可以容纳 int 类型的对象的第一个槽)的指针,因为类型void *
被隐式转换为类型int *
,因为在声明标识符的左侧,arr
具有类型int *
。
根据 C 标准(6.5.2.1 数组下标)
阿拉伯数字。。。下标运算符 [] 的定义是 E1[E2] 是 与 (*((E1)+(E2)))相同)。由于转换规则 适用于二进制 + 运算符,如果 E1 是数组对象 (等效地,指向数组对象的初始元素的指针) E2 是一个整数,E1[E2] 表示 E1 的第 E2 元素 (从零开始计数)。
因此这个表达式
arr[i]
被评估为类似
*( arr + i )
在子表达式中的位置
arr + i
使用了指针算法,即此表达式指向分配的内存范围中的第 i 个元素。
如果您声明了一个数组,例如
int array[size];
那么在这个表达式中
array[i]
数组名称隐式转换为指向其第一个元素的指针。你可以想象成
int *p = array;
*( p + i )
因此,如果您有以下声明
int array[size];
int *p;
那么以下语句是等效的
array[1] = 10;
和
p = array;
*( p + 1 ) = 10;
Becuase操作array + i
是可交换的,那么您可以互换编写
array[i]
和
i[array]
例如,在你的函数中,你可以写
i[arr] = ll->value;
虽然这只会让读者感到困惑:)
初学者总是想知道何时看到这样的代码
int a[10];
0[a] = 5;