请选择 进入手机版 | 继续访问电脑版

[C 语言] 关于C语言 const 和 define 区别

[复制链接]
查看37 | 回复10 | 2021-9-12 18:32:42 | 显示全部楼层 |阅读模式
目次

一.const 使用

const 是 constant 的缩写,“恒定不变”的意思。被 const 修饰的东西都受到逼迫 保护,可以防备 不测 的变动,能进步 程序的健壮性。以是 很多 C++ 程序计划 册本 建议:“Use const whenever you need”。

1.const 修饰变量

  1. /******************************************************************************************/
  2. //@Author:猿说编程
  3. //@Blog(个人博客地址): www.codersrc.com
  4. //@File:C语言 const 和 define 区别
  5. //@Time:2021/07/04 08:00
  6. //@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
  7. /******************************************************************************************/
  8. #include <stdio.h>
  9. int main() {
  10. const int a = 20 ;
  11. printf("a = %d\n",a);
  12. a = 200 ;
  13. printf("a = %d\n",a);
  14. return 0;
  15. }
  16. /*
  17. 输出:
  18. Compilation Failed
  19. error: assignment of read-only variable 'a'
  20. 6 | a = 200 ;
  21. | ~~^~~~~
  22. */
复制代码

用 const 定义的

  1. 变量
复制代码
的值是不答应 改变的,即不答应 给它重新赋值,即使是赋雷同 的值也不可以。并且 const 修饰的变量在定义的时间 就给它赋初值,否则报错:

  1. error: uninitialized 'const ' [-fpermissive]
复制代码

具体 表明 可以直接跳转:const 修饰变量;

2.const 修饰指针

  1. //以下两者等价,表示 *p 不可变。*p 表示的是指针变量 p 所指向的内存单元里面的内容,此时这个内容不可变;
  2. const int *p
  3. int const *p
  4. //此时 const 修饰的是 p,所以 p 中存放的内存单元的地址不可变,而内存单元中的内容可变。即 p 的指向不可变,p 所指向的内存单元的内容可变;
  5. int * const p
  6. //*p 和 p 都被修饰了,那么 p 中存放的内存单元的地址和内存单元中的内容都不可变;
  7. const int * const p
复制代码

3.const 修饰在函数名前面当

const 在函数名前面的时间 修饰的是函数返回值;在函数名后面表示是 C++ 常成员函数,该函数不能修改对象内的任何成员,只能发生读操作,不能发生写操作。

  1. const char * GetString(void);
  2. const int GetInt(void);
  3. const float GetFloat(void);
  4. const double GetDdouble(void);
复制代码

假如 给以

  1. “指针传递”
复制代码
方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同范例 指针;

  1. const char * GetString(void);
  2. //如下语句将出现编译错误:
  3. //char *str = GetString();
  4. //正确的用法是
  5. const char *str = GetString();
复制代码

假如 函数返回值采用

  1. “值传递方式”,
复制代码
由于函数会把返回值复制到外部暂时 的存储单元中,加 const 修饰没有任何价值。

  1. int GetInt(void);
  2. const int GetInt(void);
复制代码

以上两个函数都是都是独立存在的,并非同一个函数;

4.const 修饰在函数名后面

当 const 在函数名前面的时间 修饰的是函数返回值;在函数名后面表示是 C++ 常成员函数,该函数不能修改对象内的任何成员,只能发生读操作,不能发生写操作。

  1. /******************************************************************************************/
  2. //@Author:猿说编程
  3. //@Blog(个人博客地址): www.codersrc.com
  4. //@File:C语言 const 和 define 区别
  5. //@Time:2021/07/04 08:00
  6. //@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
  7. /******************************************************************************************/
  8. class People
  9. {
  10. public:
  11. int talk(void);
  12. int eat(void) const; // const 成员函数
  13. private:
  14. int m_age;
  15. };
  16. int People::eat(void) const
  17. {
  18. ++m_age; // 编译错误,企图修改数据成员m_num
  19. talk(); // 编译错误,企图调用非const函数
  20. return m_age;
  21. }
复制代码
  • const 对象只能访问 const 成员函数,而非 const 对象可以访问恣意 的成员函数,包括 const 成员函数;
  • const 对象的成员是不可修改的,然而 const 对象通过指针维护的对象却是可以修改的;
  • const 成员函数不可以修改对象的数据,不管对象是否具有 const 性子 .它在编译时,以是否修改成员数据为依据,举行 检查;
  • 然而加上 mutable 修饰符的数据成员,对于任何环境 下通过任何本领 都可修改,天然 此时的 const 成员函数是可以修改它的;

5.const 修饰函数参数

假如 函数参数采用“指针传递”,那么加 const 修饰可以防止不测 地改动该指针,起到保护作用。

  1. void StringCopy (char*strDestination, const char *strSource);
复制代码

此中 strSource 是输入参数,strDestination 是输出参数。给 strSource 加上 const 修饰后,假如 函数体内的语句试图改动 strSource 的内容,编译器将指出错误。

假如 输入参数采用“值传递”,由于函数将自动 产生暂时 变量用于复制该参数,该输入参数本来就无需保护,以是 不要加 const 修饰。

  1. 例如不要将函数 void Func1(int x) 写成 void Func1(const int x)。
  2. 如果参数作为输出参数,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加 const 修饰,否则该参数将失去输出功能(因为有 const 修饰之后,不能改变他的值)。
  3. 如果参数作为输入参数,可以防止数据被改变,起到保护作用,增加程序的健壮性;
复制代码

二.define 使用

1.define 定义常量

C 语言中,可以用

  1. #define
复制代码
定义一个标识符来表示一个常量,用 #define 定义标识符的一样平常 情势 为:

  1. #define 标识符 常量 //注意define最后没有分号
  2. //例如:
  3. #define MAX_VALUE 100 //定义整型变量MAX_VALUE值为100
  4. #define USER_NAME "huge" //定义字符串变量USER_NAME值为"huge"
  5. #define PI 3.1415926 //定义浮点数变量PI值为3.1415926
复制代码

凡是以 # 开头的均为预处理指令,预处理又叫预编译。预编译不是编译,而是编译前的处理。这个操作是在正式编译之前由体系 自动 完成的。

2.define 定义函数

  1. //定义常量
  2. #define MAX_VALUE 100 //定义整型变量MAX_VALUE值为100
  3. #define USER_NAME "huge" //定义字符串变量USER_NAME值为"huge"
  4. #define PI 3.1415926 //定义浮点数变量PI值为3.1415926
  5. //定义函数
  6. #define MAX(a,b) (a>b)?a:b //取两个数最大值
  7. #define MIN(a,b) (a<b)?a:b //取两个数最小值
复制代码

3.define 定义多行函数

  1. //定义常量
  2. #define MAX_VALUE 100 //定义整型变量MAX_VALUE值为100
  3. #define USER_NAME "huge" //定义字符串变量USER_NAME值为"huge"
  4. #define PI 3.1415926 //定义浮点数变量PI值为3.1415926
  5. //定义简单函数
  6. #define MAX(a,b) (a>b)?a:b //取两个数最大值
  7. #define MIN(a,b) (a<b)?a:b //取两个数最小值
  8. //定义复杂多行的函数
  9. #define MACRO(arg1, arg2) do { \
  10. \
  11. stmt1; \
  12. stmt2; \
  13. \
  14. } while(0)
  15. //关键是要在每一个换行的时候加上一个 "\ "
复制代码

使用 define定义一个多行的复杂函数,关键是要在每一个换行的时间 加上一个 \;

4.define 防止头文件重复包含

通过 #ifndef / #define 办理 头文件重复包含

  1. #ifndef __XXX_H__
  2. #define __XXX_H__
  3. int a=1;
  4. #endif
复制代码

上面的伪代码如下:

  1. 如果(没有定义宏__XXX_H__)
  2. {
  3.     那么直接定义宏__XXX_H__
  4.     定义变量a 并且赋值为 1
  5. }
  6. 结束程序
复制代码
  • 假如第一次包含时,由于没有定义宏 __XXX_H,以是 做了两件事,定义宏 __XXX_H,然后定义 int a = 1;
  • 假如第二次包含时,由于已经定义宏 __XXX_H__,以是 啥都不做;
  • 假如第 N 次包含时,由于已经定义宏 __XXX_H__,以是 啥都不做;
  • 整个过程,无论头文件被包含多少次,变量 a 只被定义一次,不会有重复包含重复定义的标题 存在!

三.const 和 define 区别

1.就起作用的阶段而言
define 是在编译的预处理阶段起作用,而 const 是在 编译、运行的时间 起作用。
2.就起作用的方式而言
define 只是简单的字符串更换 ,没有范例 检查。而 const 有对应的数据范例 ,是要举行 判定 的,可以避免一些低级的错误。
3.就存储方式而言
define 只是举行 睁开 ,有多少地方使用 ,就更换 多少次,它定义的宏常量在内存中有多少 个备份; const 定义的只读变量在程序运行过程中只有一份备份。
4.从代码调试的方便程度而言
const 常量可以举行 调试的,define 是不能举行 调试的,由于 在预编译阶段就已经更换 掉了。

5.从服从 程度而言

编译器通常不为平凡 const 常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的服从 也很高

四.const 长处

  • 1.const 常量有数据范例 ,而宏常量没有数据范例 。编译器可以对前者举行 范例 安全检查。而对后者只举行 字符更换 ,没有范例 安全检查,并且在字符更换 大概 会产买卖 料 不到的错误。
  • 2.有些集成化的调试工具可以对 const 常量举行 调试,但是不能对宏常量举行 调试。
  • 3.const 可节省 空间,避免不必要的内存分配,进步 服从

到此这篇关于关于C语言 const 和 define 区别的文章就先容 到这了,更多干系 C语言 const 和 define 区别 内容请搜索 脚本之家从前 的文章或继续欣赏 下面的干系 文章渴望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

avatar 潘金麟 | 2021-9-17 07:56:01 | 显示全部楼层
楼上的很有激情啊!
回复

使用道具 举报

avatar gnmpmnuy35327 | 2021-9-23 04:24:11 | 显示全部楼层
admin楼主练了葵花宝典吧?
回复

使用道具 举报

avatar 悦悦782 | 2021-9-23 04:24:15 | 显示全部楼层
每次看到admin楼主的帖子都有惊吓!
回复

使用道具 举报

avatar 缥缈的绽放山 | 2021-10-4 09:44:55 | 显示全部楼层
哥回复的不是帖子,是寂寞!
回复

使用道具 举报

avatar 小饱1 | 2021-10-4 10:31:02 | 显示全部楼层
有机会找admin楼主好好聊聊!
回复

使用道具 举报

avatar 加菲猫419 | 2021-10-7 00:02:37 | 显示全部楼层
楼上的别说的那么悲观好吧!
回复

使用道具 举报

avatar 冷专问 | 2021-10-8 19:39:53 | 显示全部楼层
经典!
回复

使用道具 举报

avatar 萍381 | 5 天前 | 显示全部楼层
在这个版块混了这么久了,第一次看见这么给你的帖子!
回复

使用道具 举报

支持楼上的!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则