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
或其他东西那样单独更改它。
答案 0 :(得分:5)
你的确是一个非常好的问题。当然,已经有人问过并多次回答SO。但仍然是一个很好的问题。
来自C / C ++ FAQ:
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
)时,您尚未分配 ANY 存储空间。
您可以同时声明和初始化指针:
int *b = NULL; /* Initialize to 0 */
... OR ...
int *b = malloc (5 * sizeof (int)); /* Allocate storage for 5 "int" elements */
当您声明数组a
时,您从堆栈中分配了空间。分配无法更改。
当您声明b
时,您分配了 SAME 空间量,但是您已从堆中分配。此外,您可以随时更改b
以指向其他任何内容。您还可以realloc()
记忆来更改存储空间。
正如您可以使用索引语法a[i]
一样,您使用完全相同的语法b[i]
。
此链接可能有助于解释:http://www.geeksforgeeks.org/g-fact-5/
PS:
如果你有指针",你肯定 CAN "单独更改它,如arr[i] = 5
或其他"。
答案 1 :(得分:2)
int *arr = malloc(size * sizeof(int));
不提供数组,它会为您提供足够大的内存块来保存size
个整数。
arr[i] = ll->value;
语句使用指针算法:表达式arr + 5
表示获取arr
指向的整数的内存地址,并从中移动5个位置那里。现在,因为编译器知道它正在使用int
指针,并假设32位int
s,它将知道在arr
的值中添加20(= 5 * 4bytes)找到第6个元素。
接下来,C语言具有语法糖,表达式arr[5]
等同于*(arr + 5)
。
这也是为什么C中的数组从0开始索引的原因,以及为什么C数组的名称也可以用作指向数组第一个元素的指针。
答案 2 :(得分:1)
在本声明中
int* arr = malloc(size*sizeof(int));
function malloc分配一个内存范围,该内存范围能够存储size
类型的int
对象,并返回指向此范围的指针(或指向int类型对象的范围中的第一个插槽)因为在声明标识符void *
的左侧有类型int *
,因此类型arr
被隐式转换为int *
类型。
根据C标准(6.5.2.1阵列下标)
2 ...下标运算符[]的定义是E1 [E2] 与(*((E1)+(E2)))相同。由于转换规则 如果E1是数组对象,则应用于binary +运算符 (等效地,指向数组对象的初始元素的指针) 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;
因为操作array + i
是可交换的,那么你可以互换地编写
array[i]
和
i[array]
例如,在您的函数中,您可以编写
i[arr] = ll->value;
虽然只会让读者感到困惑。:)
初学者总是想知道何时看到这样的代码
int a[10];
0[a] = 5;