结构化链表到数组

时间:2015-05-14 05:47:03

标签: c arrays pointers malloc

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或其他东西那样单独更改它。

3 个答案:

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

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

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

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

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

    当您声明b时,您分配了 SAME 空间量,但是您已从堆中分配。此外,您可以随时更改b以指向其他任何内容。您还可以realloc()记忆来更改存储空间。

  5. 正如您可以使用索引语法a[i]一样,您使用完全相同的语法b[i]

  6. 此链接可能有助于解释: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;