c中的常量

前两天和冬哥讨论100这样的常量能不能取地址,当时我认为可以,后来查了一些资料,整理成这篇文章,总结关于c语言中关于常量的存储及表示的内容。

有三种常量,存储各有不同特点:1、类似于汇编中的立即数的常量;2、不能更改的带const修饰符的量;3、字符串常量

一、立即数

        这种类型可能有不同的处理方法,较为简单的数可能直接放到指令中去,复杂一点的数就放在静态数据区里。以下是一本教材的一段话,我找到的关于这个内容的资料只有这么一段《编译原理及实践教程》 P168,黄贤英,清华大学出版社:

        “在组织全局/静态数据区时,出现的一个问题是它设计编译时已知的一些常量,包括C和Pascal中用const声明及代码本身所用的文字值,例如C语句printf(“hello%d\n”,12345)中的字符窜“hello%d\n”和整型值12345,对于较小的在编译时的已知常量(如0或1),通常由编译程序直接插入到代码中(本人注:应该写作指令),不为其分配任何数据空间;对于大型的整型值、浮点值,特别是字符串就必须将其分配到存储器的全局/静态数据区中。(在C中字符串被看做指针,因此必须按这种方式保存)。

         应该说这段话有些细节上表述不妥,但对我们这里关心的问题,交代的比较明确:有的直接写进指令,有的存在静态数据区,字符串常量全在静态数据区。

         另外值得一提的是,即使一个复杂的浮点数,如3333.2345L,这几乎是最大的类型了,按上述说法,应该存在于静态数据存储区,但它仍然是不能取地址的——那么做也没有什么意义,如果打算在程序里修改它,直接定义成变量就行了。

二、const常量

        其实应该叫做const变量,《c primer plus》、《c 和指针》都这么叫,但是说const常量也不会误解。

        显然,如下例,const变量是分配了内存的,可以取地址的,可以通过其他方式来改变其值的,所谓的const不同于一般变量的地方就是不能通过其标号修改,其他没啥不同。如下是我的依据,vc2010:

             int _tmain(int argc, _TCHAR* argv[])
             {
                      float const pi=3.14f;
                      float *a=(float *)π
                      printf("at first,pi=%f\n",pi);
                      *a=6.24;
                      printf("then it become%f\n",pi);
                      return 0;
              }

          用const来代替宏定义有一个好处:节省空间,如

           #define pi 3.14

           float a=pi;

           float b=pi;

           这是,经过预处理,程序变成:

           float a=3.14;

           float b=3.14;

           这是程序如果优化得不好,就会在静态数据区出现两个3.14,分别用来给a、b赋值。若将宏定义改为float const pi=3.14,不但能在赋值时类型检查,还能节省存储空间,因为在给a、b赋值之前只有一个地方存储了3.14,那就是pi的存储单元。

           

        网上关于const常量有一些说法,下边两个流传很广,但是不对。

        这种常量是存在内存中的,和变量的唯一区别就是不能更改其值。但是又有人说(http://blog.youkuaiyun.com/lixiang100824/article/details/7473890),定义了const常量并初始化后,再通过其他的指针修改其存储单元的值,然后再用常量标号,其值并没有改变——这不知是c语言的标准还是某些编译器的做法。

         C++的编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作。http://blog.youkuaiyun.com/sptoor/article/details/6578893

         我认为,这两种说法基本都不对。第二个帖子流传很广,被大量转载。提符号表是多此一举,在编译的时候,建立符号表示当然的,const变量当然不例外,但是没有理由说编译器就把const当成了宏一样的东西直接替代。

三、字符串常量

        字符串常量是存储在内存中的静态存储区的,所以可以对一个字符串常量取地址,如&“i love you”

四、常量的表示

进制

        默认十进制,0开头表示八进制,0x开头表示十六进制

整形

        编译器通过写法来识别其类型,如果int足以表示,就默认为int型,不行就是long int,还不行就只好unsigned long,乃至long long甚至unsigned long long。

        也可以通过后缀告诉编译器用什么类型来存储,L或者l后缀表示long,LL或者ll是long long,u或者U是unsigned的意思

浮点型

         没有后缀就是double型,可以使用f或者F后缀变成float型,l或者L后缀变成long double型。

字符型

         转义序列\n等

         \07和\7一样,都是通过八进制表示字符(7前没有0仍然会理解为8进制)

         \ x7,这个事16进制表示ASCII码

转载于:https://www.cnblogs.com/lxjsailor/archive/2012/09/04/2793479.html

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
<think> 首先,用户的问题是关于C语言中常量的定义的。我需要基于提供的引用来构建一个结构清晰的回答。引用包括几个来源,描述了常量的类型、定义方法和使用示例。 关键点从引用中提取: - **引用[1]**: 定义了常量作为程序执行期间不变的数值。提到了三种定义方法:字面常量、const关键字和#define宏。 - **引用[2]**: 详细介绍了常量的类型:整数、浮点数、字符、字符串常量,并提供了示例代码。 - **引用[3]**: 解释了两种定义常量的方式:#define预处理器和const关键字。 - **引用[4]**: 给出了#define的示例代码,展示如何定义和使用宏常量。 - **引用[5]**: 讨论了符号常量(如#define和const),强调常量值固定后不能修改,并提到常变量的概念。 用户的问题直接是:“我想了解C语言中常量的定义 请问C语言中常量的定义”。所以,我需要全面覆盖常量的概念、类型和定义方法。 回答结构要清晰,逐步解释: 1. **介绍常量的概念**: 解释什么是常量,为什么重要。 2. **常量的类型**: 根据引用[2],列出整数、浮点数、字符、字符串常量。 3. **定义常量的方法**: 基于引用[1]和[3],讨论字面常量、const关键字和#define宏。 4. **示例**: 提供代码示例来说明定义和使用,参考引用[2]、[4]、[5]。 5. **注意事项**: 引用[5]提到常变量和符号常量的区别。 系统指令要求: - 所有行内数学表达式用$...$格式。在C语言上下文中,可能涉及数值或表达式,如$10$, $3.14$等。 - 独立公式用$$...$$格式,但C语言常量定义可能不涉及复杂数学公式,所以可能不常用。 - 使用中文回答。 - 生成相关问题:在回答末尾添加相关问题。 - 引用标识:在回答中引用的段落末尾添加引用标识,如[^1]。 - 回答结构清晰,帮助用户逐步解决问题。 构建回答大纲: - **开头**: 定义常量。 - **主体**: - 常量的类型(整数、浮点数等)。 - 定义方法: - 字面常量。 - const关键字。 - #define宏。 - 示例代码。 - 注意事项(如常量值不可变)。 - **结尾**: 总结并添加相关问题。 确保语言自然,引用标识自然地添加。 相关问题生成:基于主题,如常量类型、定义方法的比较、使用场景等。 最终回答格式: - 文本解释。 - 代码块(如果需要)。 - 相关问题列表。 </think>### C语言中常量的定义 在C语言中,常量是指在程序执行期间值保持不变的量。与变量不同,常量一旦定义后,其值就不能被修改。使用常量可以提高代码的可读性、维护性和安全性,特别适用于固定配置(如数学常数π)或避免意外值更改的场景[^1]。常量可以是数字、字符或字符串,C语言提供了多种定义方法,包括字面常量、`const`关键字和`#define`宏。下面我将逐步解释常量的定义、类型和实现方式。 #### 1. **常量的基本概念** - 常量是程序中的固定值,编译后其值被硬编码,无法在运行时改变。例如,整数`10`、浮点数`3.14`或字符`'A'`都是常量[^2]。 - 在C语言中,常量分为以下几种主要类型: - **整数常量**: 无小数部分的数字,可以是十进制(如$10$)、八进制(以`0`开头,如$012$)或十六进制(以`0x`开头,如$0xA$)[^2]。 - **浮点数常量**: 带小数部分的数字,可以是十进制形式(如$3.14$)或指数形式(如$1e-5$,表示$1 \times 10^{-5}$)[^2]。 - **字符常量**: 用单引号括起来的单个字符,例如`'A'`或转义字符`'\n'`(换行符)[^2]。 - **字符串常量**: 用双引号括起来的一串字符,例如`"Hello, World!"`[^2]。 - 常量与变量不同:变量在声明后可被赋值多次,而常量在定义后值固定,编译器会阻止修改操作[^1][^5]。 #### 2. **定义常量的方法** C语言提供了三种主要方法来定义常量,每种方法适用于不同场景: - **字面常量(Literal Constants)**: 直接在代码中使用数值或字符,无需额外声明。这是最基础的形式,但可读性较差,适合简单场景。 - 示例:在赋值语句中使用整数$10$或浮点数$3.14$[^1]。 ```c int num = 10; // 整数字面常量 float pi = 3.14; // 浮点数字面常量 char letter = 'A'; // 字符字面常量 ``` - **`const`关键字**: 使用`const`修饰符定义只读变量,也称为“常变量”。这种方法在编译时分配存储空间,但值不可修改。优点是类型安全,且支持编译器优化。 - 规则:必须在声明时初始化值,后续不能改变[^3][^5]。 - 示例:定义圆周率常量。 ```c const float PI = 3.14159; // 常变量定义 // PI = 3.14; // 错误:常量值不能修改 ``` - **`#define`宏常量**: 使用预处理指令定义符号常量,编译时会被直接替换为值。不分配存储空间,适合全局配置。但需注意:宏是文本替换,可能导致意外错误(如运算符优先级问题)[^3][^4]。 - 规则:通常用大写字母命名,以区分变量。 - 示例:定义最大尺寸常量。 ```c #define MAX_SIZE 100 // 宏常量定义 #define PI 3.14159 int array[MAX_SIZE]; // 编译时替换为 int array[100]; ``` - 注意:宏替换可能引发问题,如`#define TWO ONE+ONE`在表达式`ONE+TWO*b+a`中,可能因替换规则导致错误计算(参考引用[4]的示例)[^4]。 #### 3. **方法比较和注意事项** - **选择建议**: - 优先使用`const`关键字,因为它提供类型检查,减少错误[^5]。 - `#define`宏适合简单值或跨文件共享,但避免用于复杂表达式。 - 字面常量适用于临时值,但不利于代码重用。 - **重要规则**: - 常量值必须在定义时初始化,且不能重新赋值[^1][^5]。 - 使用常量能避免“幻数”(magic numbers),使代码更易读[^2]。 - 在数学表达式中,常量常用于计算,例如计算圆面积:$ \text{area} = \pi \times r^2 $,其中$\pi$是常量[^2]。 #### 4. **完整代码示例** 以下示例展示了所有常量类型和定义方法的综合使用: ```c #include <stdio.h> // 使用#define定义宏常量 #define MAX_USERS 50 #define GREETING "Welcome!" int main() { // 使用字面常量 int count = 10; // 整数常量 float rate = 0.05; // 浮点数常量 // 使用const关键字定义常变量 const float PI = 3.14159; const char NEWLINE = '\n'; // 使用宏常量和字符串常量 char* message = GREETING; // 字符串常量 // 输出结果 printf("Max users: %d\n", MAX_USERS); printf("Pi value: %.5f%c", PI, NEWLINE); printf("Message: %s\n", message); // 错误示例:尝试修改常量 // PI = 3.14; // 编译错误:assignment of read-only variable return 0; } ``` 在此代码中: - `MAX_USERS`和`GREETING`是宏常量,编译时被替换。 - `PI`和`NEWLINE`是常变量,值不可变。 - 字面常量如`10`和`0.05`直接嵌入代码[^2][^3][^5]。 #### 总结 C语言中的常量通过固定值提升代码可靠性,主要通过字面常量、`const`关键字和`#define`宏来实现。核心规则是常量值不可修改,且定义时需初始化。推荐优先使用`const`以增强安全性[^1][^5]。如果您有具体使用场景(如嵌入式系统),可以进一步探讨优化技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值