当前位置: 首页 > news >正文

C语言动态数组

C语言,协议,和编译器配合起来问题好多,细节好多,好烦!!
想声明一个动态数组,C语言支持使用宏定义实现这个内容(宏定义写在函数体内依旧正确,但是作用范围依旧全局,所以充满了迷惑性,属于不良写法)
在传统的C语言(C89/C90标准)中,声明一个数组 int a[N] 要求 N 必须是一个编译时常量。在那个年代,const int N = 10; 这样的变量是不被视为编译时常量的,所以你不能用它来定义数组大小。因此,使用宏定义 #define N 10 是最主要、也是最普遍的方法。
现代C语言(从C99标准开始)为这个问题提供了更优雅、更安全的解决方案。你已经不再需要依赖宏定义了。
现代C语言的解决方案

方案一:VLA (Variable Length Array - 可变长度数组)

从C99标准开始,C语言允许在函数内部创建大小在运行时确定的数组。这种数组被称为VLA。这意味着 N 不再需要是编译时常量。

#include <stdio.h>void create_array_of_size(int n) {if (n <= 0) {printf("Invalid size.\n");return;}// 这就是VLA。数组 a 的大小由变量 n 在运行时决定。// a 是一个自动变量,在函数结束时会自动释放。int a[n];for (int i = 0; i < n; i++) {a[i] = i * 10;}printf("The last element is: %d\n", a[n - 1]);
}int main() {create_array_of_size(5);  // 创建一个有5个元素的数组create_array_of_size(20); // 创建一个有20个元素的数组return 0;
}

运行结果:

The last element is: 40
The last element is: 190

使用VLA的优势:

  1. 无需宏定义:彻底告别宏。
  2. 作用域正确:数组 a 和其大小 n 的作用域都严格限制在函数内部。
  3. 高度灵活:数组的大小可以由函数参数、用户输入或计算结果动态决定。
    注意: VLA必须是自动存储期的(不能是 static 或全局的),并且它的生命周期随着函数的结束而结束。

方案二:对于固定的局部常量,使用 const

如果你只是想用一个有名字的常量来代替魔法数字(Magic Number),而不是真的需要动态大小,const 变量在现代C编译器中通常也能工作,因为它会被当作VLA来处理。

void my_function() {const int N = 10;int a[N]; // 在C99+中,这被视为一个大小为10的VLAa[0] = 123;// ...
}

这种写法比在函数内部使用 #define N 10 要安全得多,因为它没有作用域污染的问题。

方案三:enum 技巧(传统且有效)

如果你需要一个真正的编译时常量(例如,不能使用VLA的场合,或者在使用一些比较老的C编译器时),但又想把这个常量限制在函数作用域内,有一个经典的技巧:使用匿名枚举 enum

void another_function() {// enum的成员是真正的编译时整型常量enum { N = 10 };// a 是一个普通的定长数组,而不是VLAint a[N];// 你甚至可以用它来定义静态数组static int static_array[N];a[0] = 456;static_array[0] = 789;// ...
}

enum 技巧的优势:

  1. 编译时常量:N 是一个真正的常量,就像宏一样,但它有类型。
  2. 作用域正确:N 的作用域被严格限制在函数内部。
  3. 无副作用:它是一个符号,而不是文本替换,更加安全。
方法示例作用域N 的类型推荐场景
宏定义 (在函数内)void f(){ #define N 10; ... }危险 (泄露至文件尾)文本强烈不推荐
VLAvoid f(int n){ int a[n]; }正确 (函数作用域)运行时变量当数组大小在运行时才能确定时
const 变量void f(){ const int N=10; int a[N]; }正确 (函数作用域)运行时变量 (但值固定)替代函数内的"魔法数字",代码清晰
enum 技巧void f(){ enum {N=10}; int a[N]; }正确 (函数作用域)编译时常量当需要一个真正的编译时常量,且不想污染全局作用域时

结论: 你完全不需要为了写 int a[N] 而在函数体内使用宏定义。根据你的具体需求,从 VLA、const 变量 或 enum 技巧 中选择一种,它们都是更安全、更现代、更专业的做法。

但是!!!!

在MSVC中方案一和方案二无效
这是C标准和C++标准之间的差异,以及MSVC编译器历史选择共同造成的问题。

问题的核心:C 和 C++ 对 const 的处理不同

  1. 在 C++ 中: const int N = 10; 声明的 N 是一个真正的编译时常量。编译器在编译时就知道 N 确切无疑就是 10。 因此,int a[N]; 在C++中是完全合法的,它创建了一个大小为10的、普通的栈数组。
  2. 在 C 语言 (C99) 中: const int N = 10; 声明的 N 是一个只读变量 (read-only variable),它不是一个编译时常量。 因此,int a[N]; 在C99标准中被视为 VLA (可变长度数组),因为 N 是一个变量。

真正的“凶手”:VS (MSVC) 对C标准的支持
你遇到的报错,很可能类似于 error C2057: expected constant expression (需要常量表达式)。

这是因为: Visual Studio (MSVC) 的 C 编译器(当你使用 .c 文件时)从来没有完整支持 C99 标准,尤其是 VLA。

当你在 void my_function() { const int N = 10; int a[N]; } 中这样写时:

  1. VS的 C 编译器 (编译 .c 文件时) 遵循C规则,认为 N 是个变量。
  2. 它又不支持C99的 VLA 特性。
  3. 它退回到C89/C90标准,该标准要求数组大小必须是编译时常量。
  4. 由于 N 不是编译时常量,所以编译器报错。
    (讽刺的是,如果你把文件后缀名改成 .cpp,VS会切换到C++编译器,const 就成了编译时常量,代码立刻就能通过了。但是VLA还是不行)
http://www.dtcms.com/a/509125.html

相关文章:

  • Linux小课堂: 系统监控与进程管理之深入解析 w、ps 与 top 命令
  • 一文解析软件项目管理:从核心概念到实战要点
  • 选择合适的电机试验平台的要点
  • 栅格系统做的网站怎么做手机app软件
  • 75.颜色分类
  • vue3知识点-setup返回值OptionsAPI以及其语法糖汇总
  • 专业的聊城做网站费用用凡科做网站的费用
  • 知道网站域名怎么联系免费网站模版
  • 蛋白表达标签:重组蛋白研究的精妙引擎
  • 网站建设广金手指排名番禺人才网招聿
  • 关于门户网站建设讲话酒庄企业网站
  • 建站公司联系电话wordpress 用户发帖
  • Nature Methods | GHIST vs LOKI:HE→表达的两条路径 | 单细胞级重建 vs spot级预测
  • 上海网站建设平台站霸网络多个网站给一个网站推广
  • 深圳的网站制作公司网站招聘怎么做
  • 网站建设推广渠道iis怎么做ip网站吗
  • Visual Basic 文件系统控件
  • Unity多层嵌套预设在SVN中的问题
  • 阳江房产网春天尚院wordpress seo设置
  • 如何做搞笑原创视频网站wordpress 4.7多用户
  • 怎么找网站帮我做推广网站怎么加内容
  • 肇庆网站seo外卖平台如何做推广效果好
  • 怎样创建公司网站wap网站模板下载
  • 19.map和set的封装
  • 【Python机器学习入门1】VSCode环境配置与Python基础
  • 网站建设的主要职责网站开发 接口还是ajax
  • 外贸独立站SEO技术架构深度优化指南
  • phython 做的网站怎样做网络营销推广
  • 旅游自媒体网站怎么做主页制作语言缩写
  • 金乡县网站开发中信建设有限责任公司历任董事长