c语言 - 数组的结构化链表


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)。

  1. 当您声明数组(例如int a[5]),您已经为五个"int"元素分配了存储空间。 您可以像a[i]一样访问每个元素。

  2. 当您声明指针(例如int *b) 您尚未分配任何存储空间。

  3. 您可以同时声明和初始化指针:

    int *b = NULL;  /* Initialize to 0 */
    ... OR ...
    int *b = malloc (5 * sizeof (int)); /* Allocate storage for 5 "int" elements */
    
  4. 当您声明数组a时,您从堆栈中分配了空间。 无法更改分配。

    当您声明b时,您分配了相同数量的空间,但您从堆中分配了空间。 此外,您可以随时更改b以指向其他任何内容。 您还可以realloc()内存以更改存储大小。

  5. 正如您可以使用索引语法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 位ints,所以它将知道在arr的值中添加 20(=5*4 字节)以找到第 6 个元素。

接下来,C 语言具有句法糖,其中表达式arr[5]等效于*(arr + 5)

这也是为什么 C 中的数组从 0 开始索引,以及为什么 C 数组的名称也可以用作指向数组第一个元素的指针。

在此语句中

int* arr = malloc(size*sizeof(int));

函数 malloc 分配一个能够存储sizeint类型的对象的内存范围,并返回指向此范围的指针(或指向可以容纳 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;

相关内容

  • 没有找到相关文章

最新更新