You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于C语言双向链表创建代码中while(size--)与指针转换的疑问

双向链表创建代码解析

问题背景

用户提供了一段从整数数组创建双向链表的C语言代码,对其中的while (size--)循环退出时机、tmp = (int *)&node->n语句,以及代码整体工作原理存在疑问:

#include <stdio.h>
#include <stdlib.h>

/**
 * struct listint_s - Doubly linked list node
 *
 * @n: Integer stored in the node
 * @prev: Pointer to the previous element of the list
 * @next: Pointer to the next element of the list
 */
typedef struct listint_s // generating a structure
{
    const int n;
    struct listint_s *prev;
    struct listint_s *next;
} listint_t;

/**
 * create_listint - Creates a doubly linked list from an array of integers
 *
 * @array: Array to convert to a doubly linked list
 * @size: Size of the array
 *
 * Return: Pointer to the first element of the created list. NULL on failure
 */
listint_t *create_listint(const int *array, size_t size)
{
    listint_t *list;
    listint_t *node;
    int *tmp;

    list = NULL;
    while (size--)
    {
        node = malloc(sizeof(*node));
        if (!node)
            return (NULL);
        tmp = (int *)&node->n;
        *tmp = array[size];
        node->next = list;
        node->prev = NULL;
        list = node;
        if (list->next)
            list->next->prev = list;
    }
    return (list);
}

1. while (size--)循环的退出时机

size是size_t类型(无符号整数),循环执行逻辑如下:

  • 先判断当前size的值是否非零,非零则进入循环体
  • 循环体执行完毕后,size自减1
  • 当size自减到0时,下一次循环判断条件不成立,循环退出

举个例子:如果初始size为3,循环会执行3次:

  • 第一次:判断size=3≠0,进入循环,之后size变为2
  • 第二次:判断size=2≠0,进入循环,之后size变为1
  • 第三次:判断size=1≠0,进入循环,之后size变为0
  • 第四次:判断size=0,不满足条件,退出循环

也就是说,循环会完整执行初始size的次数,刚好覆盖数组的所有元素。

2. tmp = (int *)&node->n语句的作用

结构体里的n被声明为const int,意味着它是只读变量,正常情况下无法直接赋值。这段代码通过强制类型转换绕过了const的限制:

  • &node->n取到const int类型的地址,再强制转换为int*类型赋值给tmp
  • 通过*tmp间接修改node->n的值

这种写法虽然能实现初始化,但破坏了const的语义,属于不规范用法——如果结构体设计时需要初始化n,更合理的做法是去掉const修饰,或者通过构造逻辑直接初始化。

3. 代码整体工作原理

这段代码核心逻辑是从数组末尾向前遍历,逐个创建节点并插入链表头部,最终生成与原数组顺序一致的双向链表:

  1. 初始化list为NULL,表示初始链表为空
  2. 循环处理数组的每一个元素(从最后一个到第一个):
    • 用malloc分配新节点内存,分配失败则直接返回NULL
    • 绕过const限制,给新节点的n赋值为当前数组元素
    • 新节点的next指向当前链表头list
    • 新节点的prev设为NULL(因为它是新的链表头,前面无节点)
    • 更新list为新节点,使其成为新的链表头
    • 如果原链表不为空(list->next存在),将原链表头的prev指向新节点,完成双向链接
  3. 循环结束后,返回链表头指针list,此时链表节点顺序与原数组完全一致。

内容的提问来源于stack exchange,提问作者JOSHUA AISIEN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:31:06