#define 和 const 定义常量的区别

文章目录

    • 一、数组定义
      • 1.1 全局作用域中定义数组
      • 1.2 局部作用域定义数组
    • 二、细节补充
      • 2.1 `#define` 和 `const` 的区别
      • 2.2 全局数组和局部数组的区别
      • 2.3 编译时常量 vs 运行时常量
      • 2.4 为什么局部作用域不要求编译时常量
    • 总结

一、数组定义

1.1 全局作用域中定义数组

在全局作用域中定义数组大小,只能使用预处理器宏#define

const变量在代码中表现得像常量,但它们实际上并不是编译时常量。在全局作用域中,不能使用const变量来定义数组大小。编译器要求在编译时就知道数组的大小,而const变量在编译时可能没有固定的值。

#include <stdio.h>#define NUM_ADJACENT_FRAMES 5
int ADJACENT_FRAMES[2 * NUM_ADJACENT_FRAMES + 1];int main() {// 示例初始化for (int i = 0; i < 2 * NUM_ADJACENT_FRAMES + 1; i++) {ADJACENT_FRAMES[i] = i; // 示例初始化}// 打印数组内容for (int i = 0; i < 2 * NUM_ADJACENT_FRAMES + 1; i++) {printf("%d ", ADJACENT_FRAMES[i]);}printf("\n");return 0;
}

1.2 局部作用域定义数组

在局部作用域中定义数组大小,可以使用预处理器宏#define 或者 const

#include <stdio.h>// #define NUM_ADJACENT_FRAMES 5   
const int NUM_ADJACENT_FRAMES = 5;void process_frames() {int ADJACENT_FRAMES[2 * NUM_ADJACENT_FRAMES + 1];// 示例初始化for (int i = 0; i < 2 * NUM_ADJACENT_FRAMES + 1; i++) {ADJACENT_FRAMES[i] = i;}// 打印数组内容for (int i = 0; i < 2 * NUM_ADJACENT_FRAMES + 1; i++) {printf("%d ", ADJACENT_FRAMES[i]);}printf("\n");
}int main() {process_frames();return 0;
}

二、细节补充

2.1 #defineconst 的区别

特性#defineconst
类型无类型,仅文本替换有类型,进行类型检查
作用域从定义点到文件结束,或使用 #undef根据定义位置,全局或局部
生命周期编译时定义,在整个编译过程中有效程序运行时有效,根据定义位置决定
初始化不进行初始化,只做文本替换需要显式初始化
内存分配无内存分配,仅文本替换有内存分配,根据定义位置决定(栈或全局)
编译时常量是,可以用于定义全局数组大小不是,在全局作用域不能用于定义数组大小
优点简单、直接、灵活类型安全,易于调试和优化
缺点没有类型检查,容易引起难以发现的错误不能在全局作用域定义数组大小
示例定义#define SIZE 10const int SIZE = 10;
全局数组定义int array[SIZE];无法在全局作用域定义数组大小
局部数组定义int array[SIZE];int array[SIZE];
适用场景简单常量定义,宏函数,编译时常量使用类型检查,需要类型信息的常量,局部数组定义

2.2 全局数组和局部数组的区别

(1)局部数组的内存分配

  • 局部变量(包括局部数组)在函数调用时分配内存。它们通常分配在栈上。
  • 由于栈内存是在运行时管理的,因此局部数组的大小可以基于运行时的值(如函数参数或局部计算结果)。

(2)全局数组的内存分配

  • 全局变量在程序启动时分配内存,它们分配在数据段(.data 或 .bss 段)。
  • 由于数据段的大小必须在编译时确定,因此全局数组的大小必须是编译时常量。

2.3 编译时常量 vs 运行时常量

编译时常量:值在编译时已知,并且编译器可以在编译过程中使用这些值进行优化和内存分配。

运行时常量:值在运行时确定,并且在程序运行过程中使用这些值进行内存分配和操作。

2.4 为什么局部作用域不要求编译时常量

在C语言中,局部作用域定义的数组不要求编译时常量,这主要是因为局部变量在函数调用时分配内存,而不是在编译时分配。这允许更灵活的内存管理和运行时行为。

总结

#define 宏定义:用于编译时常量替换,可以在全局范围内定义数组大小。

const 变量:在编译时不能作为编译时常量,不能在全局范围内定义数组大小,只能在局部作用域(如函数内部)使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/23765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Android面试八股文】Java异常机制中,异常Exception与错误Error区别是什么?

Java异常机制中,异常Exception与错误Error区别是什么? 这道题想考察什么? 在开发时需要时候需要自定义异常时,应该选择定义Excption还是Error? 编写的代码触发Excption或者Error分别代表什么? 考察的知识点 Java异常机制 考生应该如何回答 在Java中存在一个 Throwa…

Git - 详解 创建一个新仓库 / 推送现有文件夹 / 推送现有的 Git 仓库 到私有Gitlab

文章目录 【推送现有文件夹】详细步骤指令说明Git 全局设置设置Git全局用户名设置Git全局电子邮件地址 推送现有文件夹1. 进入现有文件夹2. 初始化Git仓库并设置初始分支为main3. 添加远程仓库4. 添加所有文件到暂存区5. 提交更改6. 推送代码到远程仓库并设置上游分支 创建一个…

ESXi内安装OpenWrt

目录 0、前言 1、环境 2、转换格式 3、创建虚拟机 4、OpenWrt设置 5、单臂流量测试 6、总结 0、前言 前几天在ESXi中先安装了PVE,然后在PVE中安装OpenWrt,没有来得及深入测试,仅仅作为安装和熟悉PVE的过程。后来转念一想为什么不在ES…

js之this

最近写代码学习了this&#xff0c;这个非常好用啊&#xff0c;今天拿出来给大家分享一下&#xff0c;根据我的理解以及前辈们的讲解 this 关键字代表当前执行上下文中的对象。它通常指向调用函数的对象&#xff0c;但其值可能取决于函数的调用方式。 全局上下文中的 this&…

项目经验,用什么思路去叙述?

文章目录 前言一、项目经验二、关于自学 前言 如果你的项目掌握的不高&#xff0c;面试官对项目的拷打&#xff0c;hold不住怎么办&#xff1f;首先一定要把项目说通透&#xff0c;一定要会说&#xff0c;就算可能没真实做过一个项目&#xff0c;会说出来讲通透就行。写在简历…

CS1061 “HtmlHelper”未包含“Partial”的定义,并且找不到可接受第一个“HtmlHelper”类型参数的可访问扩展方法“Partial”

严重性 代码 说明 项目 文件 行 禁止显示状态 错误 CS1061 “HtmlHelper”未包含“Partial”的定义&#xff0c;并且找不到可接受第一个“HtmlHelper”类型参数的可访问扩展方法“Partial”(是否缺少 using 指令或程序集引用?) 14_Views_Message_E…

找嵌入式软件工作,freertos要掌握到什么程度?

对于嵌入式软件工程师来说&#xff0c;掌握RTOS&#xff08;实时操作系统&#xff09;的程度并不是决定性因素&#xff0c;而更重要的是工程思维和解决问题的能力。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习嵌入式…

GitHub个人访问令牌登录

生成个人访问令牌 登录 GitHub。访问 Personal Access Tokens 页面。点击 “Generate new token”。为令牌选择一个描述性名称。选择 repo 权限。点击 “Generate token” 生成令牌。复制生成的令牌。 推送命令 设置存储库 URL&#xff08;如果需要&#xff09;&#xff1a;…

Angular封装高德地图组件实现输入框搜索,地图点击选地点

Angular封装高德地图组件实现输入框搜索,地图点击选地点(Angular17版本) 话不多说直接上代码 创建一个独立组件 html代码: <div style"position: relative;"><input #searchInput nz-input placeholder"请输入地址"/><div #mapContaine…

PostgreSql创建数据库,用户以及权限分配

1.创建用户 CREATE USER newuser WITH PASSWORD password;2.创建数据库 CREATE DATABASE newdatabase;3.给用户赋权 GRANT ALL PRIVILEGES ON DATABASE newdatabase TO newuser;给用户newuser数据库(newdatabase)的所有权限

vue3之基于el-image实现图片预览

实现的功能&#xff1a; 图片可放大预览&#xff0c;支持放大、缩小、向左向右旋转查看可点击任意一张图后进行左右切换查看大图 主要使用的方法&#xff1a;splice和concat 主要代码 // template中 <div><el-imagev-for"(item, index) in imgsData":src&q…

力扣 48.旋转图像

题目描述&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],…

CLion配置

下载环境&#xff1a;MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net 解压后找一个位置存放&#xff0c;一般放在和ide同一目录&#xff0c;方便查找 个人习惯配置调整&#xff1a; 项目创建 修改ide解码形式 项目右下角一般默认是utf8 文件编码改…

数据结构:共享栈

实现思想 共享栈&#xff08;Shared Stack&#xff09;是一种内存管理技术&#xff0c;通常用于操作系统和编程语言的运行时环境中&#xff0c;以支持多线程或多进程的程序。共享栈允许多个执行线程或进程共享同一个内存区域&#xff0c;这个内存区域用于存储局部变量、函数调用…

小白学Linux | Debian系系统与RedHat系系统日志区别

Debian系系统&#xff08;如Ubuntu&#xff09;的日志 包管理器相关日志: /var/log/apt/: 包含与APT包管理器相关的日志&#xff0c;如软件包安装和更新的详细信息。 /var/log/apt/history.log: 记录了通过APT命令安装、删除或升级的包的历史。/var/log/apt/term.log: 记录了AP…

VS2019 QT无法打开 源 文件 “QTcpSocket“

VS2019 QT无法打开 源 文件 "QTcpSocket" QT5.15.2_msvc2019_64 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E1696 无法打开 源 文件 "QTcpSocket" auto_pack_line_demo D:\vs_qt_project\auto_pack_line_de…

【区块链】truffle测试

配置区块链网络 启动Ganache软件 使用VScode打开项目的wordspace 配置对外访问的RPC接口为7545&#xff0c;配置项目的truffle-config.js实现与新建Workspace的连接。 创建项目 创建一个新的目录 mkdir MetaCoin cd MetaCoin下载metacoin盒子 truffle unbox metacoincontra…

如何减少Apache Spark日志的数量

修改log4j配置文件&#xff0c;没有就创建&#xff1a; 内容&#xff1a; # 设置日志记录器 log4j.rootCategoryWARN, console log4j.appender.consoleorg.apache.log4j.ConsoleAppender log4j.appender.console.targetSystem.err log4j.appender.console.layoutorg.apache.lo…

【栈】1096. 花括号展开 II

本文涉及知识点 栈 LeetCode 1096. 花括号展开 II 如果你熟悉 Shell 编程&#xff0c;那么一定了解过花括号展开&#xff0c;它可以用来生成任意字符串。 花括号展开的表达式可以看作一个由 花括号、逗号 和 小写英文字母 组成的字符串&#xff0c;定义下面几条语法规则&…

laravel8使用中间件实现xss处理

1、创建中间件 php artisan make:middleware XSSClean 2、编辑app/Http/Middleware/XSSClean.php文件 <?phpnamespace App\Http\Middleware;use Closure; use Illuminate\Http\Request;class XSSClean {/*** Handle an incoming request.** param \Illuminate\Http\Requ…