5 C 语言常量的定义和分类、#define 和 const 定义常量的区别

news2024/12/24 20:36:51

目录

1 什么是常量

2 常量的分类

3 常量的定义

3.1 使用 #define 定义常量

3.1.1 介绍

3.1.2 定义格式

3.1.3 案例演示

3.1.4 执行时机

3.2 const 关键字

3.2.1 介绍

3.2.2 const 定义常量的格式

3.2.3 案例演示

3.2.4 执行时机

3.2.5 注意事项

4 #define 和 const 定义常量的区别

4.1 执行时机

4.2 类型检查

4.3 作用域和存储类别

4.4 调试和可读性

5 测试题


1 什么是常量

        程序运行时,其值不能改变的量,即为常量。


2 常量的分类

        字面量常量直接使用的常量,不需要定义或声明,包括整数常量、浮点数常量、字符常量。

        标识符常量,使用标识符作为常量名,包括 #define 定义的标识符常量 const 关键字定义的标识符常量以及枚举常量。 


3 常量的定义

        字面常量不需要定义或声明,我们主要学习如何定义标识符常量,习惯上常量名使用大写,方便与变量区分。

3.1 使用 #define 定义常量

3.1.1 介绍

        #define 来定义常量,也叫作宏定义,就是用一个标识符来表示一个常量值,如果在后面的代码中出现了该标识符,那么在预处理阶段就会全部替换成指定的常量值,即用宏体替换所有宏名,简称宏替换

        对于 #define 指令,预处理器会查找源代码中所有匹配宏定义名称的实例,并将它们替换为宏定义中指定的内容。这个过程是纯粹的文本替换,不进行语法检查或类型检查。因此,如果在宏替换后产生了语法错误,这些错误只有在预处理后的代码被编译器处理时才会被发现。

3.1.2 定义格式

#define 常量名 常量值
  • 不要以分号结尾,如有分号,分号会成为常量值的一部分。
  • #define 必须写在 main 函数的外面(有些编译器的扩展允许 #define 写在 main 函数里,但我们强烈不建议这么做)。

3.1.3 案例演示

#include <stdio.h>

// 使用宏定义定义常量 PI,常量值 3.14
#define PI 3.14

int main()
{
    double area;
    // 圆的半径
    double r = 1.2;
    // 计算圆的面积
    area = PI * r * r;
    // 输出面积
    printf("圆的面积是(保留到小数点后两位) : %.2f\n", area);

    // 将圆的半径扩大二倍
    r = 2.4;
    // 计算圆的面积
    area = PI * r * r;
    // 输出面积会扩大四倍
    printf("圆的面积是(保留到小数点后两位) : %.2f\n", area);

    return 0;
}

        输出结果:

3.1.4 执行时机

        在终端中输入预处理指令:gcc -E .\chapter04\define.c -o .\chapter04\define.i ,然后查看生成的 define.i 文件内容,会发现代码中的 PI 已经全部替换成了对应的数值,如下所示:

3.2 const 关键字

3.2.1 介绍

        C99 标准新增,这种方式跟定义一个变量是一样的,只需要在变量的数据类型前再加上一个 const 关键字

        跟使用 #define 定义宏常量相比,const 定义的常量有详细的数据类型,而且会编译阶段进行安全检查,在运行时才完成替换,所以会更加安全和方便。推荐使用!

3.2.2 const 定义常量的格式

const 数据类型 常量名 = 常量值;

3.2.3 案例演示

#include <stdio.h>

// 使用 const 关键字定义常量 PI
const double PI = 3.14;

int main()
{
    double area;    // 声明变量 area 用于存储圆的面积
    double r = 1.2; // 声明并初始化变量 r 为圆的半径

    // 计算圆的面积并赋值给变量 area
    area = PI * r * r;

    // 使用 printf 函数输出圆的面积,保留两位小数
    printf("圆的面积是(保留到小数点后两位) : %.2f\n", area); 
    return 0; // 程序正常结束
}

        输出结果:

3.2.4 执行时机

        在终端中输入预处理指令:gcc -E .\chapter04\const.c -o .\chapter04\const.i ,然后查看生成的 const.i 文件内容,会发现代码中的 PI 并没有替换成对应的数值,还是常量的形式,如下所示:

3.2.5 注意事项

        在 C 语言中,使用 const 关键字定义的常量需要在定义时进行初始化,不可以后续再赋值。const 关键字用于声明一个变量的值在初始化之后不能被修改,因此它必须在声明时就被赋予一个初始值。这个规则确保了常量在程序中的值在整个运行期间都是固定不变的。 


4 #define 和 const 定义常量的区别

4.1 执行时机

        #define:这是一个预处理指令,它在编译之前的预处理阶段执行。预处理器会扫描源代码,将所有 #define 指令中定义的宏(包括常量)替换为它们对应的文本。这个过程是文本替换,不涉及任何编译或类型检查。

        const:这是一个关键字,用于在编译时定义常量。与 #define 不同,const 常量是在编译过程中处理的,并且会进行类型检查。这意味着如果尝试将 const 常量赋值给不兼容类型的变量,编译器将报错。

4.2 类型检查

        #define:由于 #define 只是简单的文本替换,它不涉及类型检查。因此,如果宏定义被错误地用于不兼容的上下文(例如,将整数宏用于浮点数运算),编译器可能不会在宏替换后立即报错,而是在后续的代码检查中才发现问题。

        const:const 常量需要指定数据类型,并且会在编译时进行类型检查。这有助于防止类型不匹配的错误,并提高了代码的类型安全性。

4.3 作用域和存储类别

        #define:#define 定义的宏没有作用域的概念,它们在整个编译单元(通常是源文件)中都是可见的。此外,#define 宏也没有存储类别(如自动、静态或外部),因为它们在预处理阶段就被替换了。

        const:const 常量可以具有作用域和存储类别。它们可以定义在函数内部(具有自动存储期),也可以定义在全局作用域中(具有静态或外部存储期,取决于是否使用了 static 关键字)。这允许更精细的控制常量的可见性和生命周期。

4.4 调试和可读性

        #define:由于 #define 宏只是文本替换,它们在调试时可能会隐藏一些重要的信息。例如,如果宏被错误地替换,调试器可能无法显示原始宏名称,而是显示替换后的文本。

        const:const 常量在调试时更容易识别和理解,因为它们保留了类型信息和作用域信息。此外,const 常量还可以被调试器直接显示其名称和值。


5 测试题

        请写出以下代码的运行结果:

#include <stdio.h>
const int PI = 300;

int main()
{
    PI = 250;
    printf("%d", PI);
}

        【答案】报错

        【解析】常量的值不能修改!

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

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

相关文章

Spring事务管理和事务传播机制详解

目录 一.简单理解事务 二.Spring中事务的实现 编程式事务 声明式事务 三.Transactional 详解 ▐ 异常回滚属性 rollbackFor ▐ 事务隔离级别 Isolation ▐ 事务的传播机制 propagation 一.简单理解事务 事务是⼀组操作的集合&#xff0c;是⼀个不可分割的操作。 事务会…

CORS解决前端跨域案例学习

跨域的概念不再解释&#xff0c;直接演示下出现跨域的情况&#xff1a; 前端代码&#xff08;index.html&#xff09;: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" conten…

comfyUI工作流也能变现了,“SD变现宝”把工作流转为小程序,重塑内容创作者的商业之路

前言 在数字化浪潮的推动下&#xff0c;内容创作行业正经历着前所未有的变革。如何在这个充满竞争与机遇的时代中脱颖而出&#xff0c;成为每个创作者必须面对的挑战。 SD变现宝&#xff0c;作为ComfyUI的最新插件&#xff0c;凭借其独特的功能与优势&#xff0c;为创作者们开…

赋能未来制造:三品图文档管理软件在大连船推图文档管理中的深度应用与成效

在信息化浪潮席卷全球的今天&#xff0c;企业的研发管理能力已经成为衡量其核心竞争力的重要标尺。三品软件与大连船用推进器有限公司携手合作&#xff0c;成功实施了EDM图文档协同管理系统项目&#xff0c;为企业在激烈的市场竞争中提供强有力的支持&#xff0c;确保其始终处于…

RCE绕过练习

一.了解eval与assert eval与assert区别_eval assert-CSDN博客https://blog.csdn.net/qq_53568983/article/details/129782507 看了php官方文档,assert中提到的许多名词不明白,转而搜索文章,这篇是解释的是最直白的 其中提到eval不是一个函数,是语言构造器,不能被可变函数调用…

Git代码管理规范

1. 简介 git 分支分为集成分支、功能分支和修复分支&#xff0c;分别命名为 develop、feature 和 hotfix&#xff0c;均为单数。不可使用 features、future、hotfixes、hotfixs 等错误名称。 master&#xff08;主分支&#xff0c;永远是可用的稳定版本&#xff0c;不能直接在…

数据中台运营与实战案例集锦(125页PPT)

方案简介&#xff1a; 本篇通过理论讲解与实战案例相结合的方式&#xff0c;深入剖析了数据中台的概念、架构、关键技术、实施路径以及运营策略。内容覆盖从数据中台规划到落地的全过程&#xff0c;包括数据治理、数据资产管理、数据服务化、数据分析与挖掘、以及如何通过数据…

PythonStudio 控件使用常用方式(二十六)TProgressBar

PythonStudio是一个极强的开发Python的IDE工具&#xff0c;官网地址是&#xff1a;https://glsite.com/ &#xff0c;在官网可以下载最新版的PythonStudio&#xff0c;同时&#xff0c;在使用PythonStudio时&#xff0c;它也能及时为用户升到最新版本。它使用的是Delphi的控件&…

MySQL:复杂查询(一)——聚合函数分组查询联合查询01

目录 1、聚合查询 1.1 聚合函数 1.1.1 COUNT() 1.1.2 SUM() 1.1.3 AVG() 1.1.4 MAX()&#xff0c;MIN() 1.2 分组查询 1.2.1 GROUP BY子句 1.2.1.1 round() 1.2.2 HAVING 1.2.3 示例 2、联合查询&#xff08;表连接查询&#xff09; 2.1 内连接 2.1.1 ①取相关表笛…

机器学习——全连接(MLP多层感知机)的理解

全连接即是矩阵乘&#xff0c;因此在transformer中获取QKV理论上是输入与QKV权重矩阵相乘&#xff0c;但实际操作则是使用全连接即nn.Linear()&#xff0c;注意这里的输入和输出都是二维的[batch,d_model]&#xff0c;即每个样本是一维的。

【Echarts】custom自定义图表实现甘特图

效果图 主要注意点&#xff1a; 1、右上角图例visualMap实现 2、visualMap增加formatter 3、series使用custom自定义图表&#xff0c;encode解析四维数组。核心是renderItem方法&#xff0c;必填项&#xff0c;且需要注意要全部定义在options里面&#xff01;&#xff01;&…

程序员如何平衡日常编码工作与提升式学习?

程序员的两难&#xff1a;如何平衡日常编码与持续学习 在科技日新月异、更新迭代迅速的编程世界中&#xff0c;程序员面临的一个重要挑战是如何在繁忙的日常编码工作和持续的专业提升之间找到平衡。是否应当在工作时间全身心投入到项目推进中&#xff0c;还是应该抽出时间学习…

第38篇 冒泡排序<二>

Q&#xff1a;如何设计C语言程序对数组进行降序排列&#xff1f; A&#xff1a;基本原理&#xff1a;通过不断的比较和交换数组中的数据元素&#xff0c;最终使得最大的数据“冒泡”排到到数组最末&#xff0c;并逐步缩小待排序的范围直到所有数据都排列正确位置。首先定义简单…

行业大模型:信用评分大模型、生产优化大模型、库存管理大模型、物流行业大模型、零售行业大模型

金融行业大模型&#xff1a;信用评分大模型 信用评分模型在金融行业中扮演着至关重要的角色&#xff0c;它通过对个人或企业的信用状况进行评估&#xff0c;帮助金融机构有效控制风险&#xff0c;提高业务效率。以下是信用评分模型的特点及案例介绍&#xff1a; 信用评分模型…

git放弃本地add/commit

git放弃本地add/commit 还未添加add的情况已经执行git add缓存了的&#xff1a;可以用命令 还未添加add的情况 # 放弃某个文件git checkout <filename># 放弃所有文件git checkout .已经执行git add缓存了的&#xff1a;可以用命令 git reset HEAD filepathname &#x…

【开端】如何高效记录并整理编程学习笔记

如何高效记录并整理编程学习笔记&#xff1f; 在编程学习的海洋中&#xff0c;高效的笔记记录和整理方法就像一张珍贵的航海图&#xff0c;能够帮助我们在浩瀚的知识中找到方向。如何建立一个既能快速记录又易于回顾的笔记系统&#xff1f;如何在繁忙的学习中保持笔记的条理性…

巴黎奥运会中国奖牌数据分析

目录 一、每个比赛日奖牌变化数据分析 二、奖牌项目占比数据分析 2.1金牌中项目占比分析 2.2 银牌中项目占比分析 2.3 铜牌中项目占比分析 2.4 奖牌总数中项目占比分析 在巴黎奥运会上&#xff0c;中国队的表现可谓亮眼&#xff0c;各项比赛日的奖牌总数和不同项目的奖牌…

【软件测试】功能测试理论基础

目录 项目的测试流程&#x1f3f4; 需求评审 评审形式 测试人员在需求评审中职责 测试计划与方案 测试计划 问题 测试方案&#x1f3f4; 测试计划与方案的对比 功能测试设计&#x1f3f4; 测试设计的步骤 项目的测试流程&#x1f3f4; 作用&#xff1a; 有序有效开展…

js 深拷贝、浅拷贝深度解析

赋值操作&#xff1a; let obj{a:1,b:[1,2,3],c:{m:2}}let newObjobjnewObj.a2newObj.b.push(4)newObj.c.m3console.log(obj,newObj); 将一个对象赋值给一个变量&#xff0c;其实就是将这个对象在栈内存中的引用地址复制给了这个变量&#xff0c;这两个对象指向堆内存中的同一个…

基于SpringBoot+Vue的产业园区智慧公寓管理系统(带1w+文档)

基于SpringBootVue的产业园区智慧公寓管理系统(带1w文档) 基于SpringBootVue的产业园区智慧公寓管理系统(带1w文档) 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包…