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

calloc函数返回值可赋值类型:数组指针、元素指针或二者均可?

calloc返回值的合法赋值类型分析

根据C17标准草案7.22.3.2,calloc函数的原型为:

void *calloc(size_t nmemb, size_t size);

它的作用是分配一块能容纳nmemb个大小为size的对象的数组空间,并且会将空间内的所有位初始化为0。

常见用法

对于分配T类型的数组,最常见的写法是将返回值赋值给指向元素的指针:

T *p = calloc(nmemb, sizeof(T));

或者分开初始化与赋值:

T *p;
p = calloc(nmemb, sizeof(T));

指向数组的指针写法

考虑到calloc本质是为数组分配空间,以下将返回值赋值给指向数组的指针的写法同样合法:

T (*arrp)[nmemb] = calloc(nmemb, sizeof(T));

或者分开写:

T (*arrp)[nmemb];
arrp = calloc(nmemb, sizeof(T));

注:每组的第一种写法严格来说属于初始化,而非赋值操作。

核心问题解答

calloc的返回值是void*类型,根据C标准规则,void*可以隐式转换为任意对象指针类型。因此:

  • 既可以赋值给指向数组元素的指针(T*)
  • 也可以赋值给指向数组的指针(T (*)[])

两种写法均符合C17标准要求,且在GCC(编译参数gcc -std=c17 -pedantic -Wall -Wextra)和MSVC(编译参数cl /std:c17 /Wall)环境下都能正常编译,运行输出符合预期。

补充背景知识

对于T类型数组arr,以下三个表达式的类型与值特点:

  • arr:退化前类型为T[],退化后为T*(指向数组首元素)
  • &arr[0]:类型为T*,与退化后的arr值相同
  • &arr:类型为T (*)[](&运算符阻止数组类型退化,指向整个数组)

前两者的地址值完全相同,C标准仅保证(void *)&arr == (void *)&arr[0]成立,理论上&arr的地址表示可能与前两者不同,但转换为void*后必须相等。

内容的提问来源于stack exchange,提问作者Lover of Structure

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:03:16