C语言 const 和 define 区别 - C语言零基础入门教程

目录

  • 一.const 使用
    • 1.const 修饰变量
    • 2.const 修饰指针
    • 3.const 修饰在函数名前面
    • 4.const 修饰在函数名后面
    • 5.const 修饰函数参数
  • 二.define 使用
    • 1.define 定义常量
    • 2.define 定义函数
    • 3.define 定义多行函数
    • 4.define 防止头文件重复包含
  • 三.const 和 define 区别
    • 1.就起作用的阶段而言
    • 2.就起作用的方式而言
    • 3.就存储方式而言
    • 4.从代码调试的方便程度而言
    • 5.从效率程度而言
  • 四.const 优点
  • 五.猜你喜欢

零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门

一.const 使用

const 是 constant 的缩写,“恒定不变”的意思。被 const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多 C++ 程序设计书籍建议:“Use const whenever you need”。

1.const 修饰变量

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言 const 和 define 区别
//@Time:2021/07/04 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/#include <stdio.h>int main() {const int a = 20 ;printf("a = %d\n",a);a = 200 ;printf("a = %d\n",a);return 0;
}/*输出:Compilation Failederror: assignment of read-only variable 'a'6 |     a = 200 ;|     ~~^~~~~*/

用 const 定义的变量的值是不允许改变的,即不允许给它重新赋值,即使是赋相同的值也不可以。并且 const 修饰的变量在定义的时候就给它赋初值,否则报错:

error: uninitialized 'const ' [-fpermissive]

详细解释可以直接跳转:const 修饰变量

2.const 修饰指针

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

详细解释可以直接跳转:const修饰指针

3.const 修饰在函数名前面

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

const char * GetString(void);
const int    GetInt(void);
const float  GetFloat(void);
const double GetDdouble(void);

如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同类型指针;

const char * GetString(void);//如下语句将出现编译错误:
//char *str = GetString();//正确的用法是
const char  *str = GetString();

如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加 const 修饰没有任何价值。

int GetInt(void);const int GetInt(void);

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

4.const 修饰在函数名后面

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

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言 const 和 define 区别
//@Time:2021/07/04 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/class People
{public:int talk(void);int eat(void) const; // const 成员函数private:int m_age;};
int People::eat(void) const
{++m_age; // 编译错误,企图修改数据成员m_numtalk();  // 编译错误,企图调用非const函数return    m_age;
}
  • const 对象只能访问 const 成员函数,而非 const 对象可以访问任意的成员函数,包括 const 成员函数;
  • const 对象的成员是不可修改的,然而 const 对象通过指针维护的对象却是可以修改的;
  • const 成员函数不可以修改对象的数据,不管对象是否具有 const 性质.它在编译时,以是否修改成员数据为依据,进行检查;
  • 然而加上 mutable 修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的 const 成员函数是可以修改它的;

5.const 修饰函数参数

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

void StringCopy (char*strDestination, const char *strSource);

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

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

例如不要将函数 void Func1(int x) 写成 void Func1(const int x)。

如果参数作为输出参数,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加 const 修饰,否则该参数将失去输出功能(因为有 const 修饰之后,不能改变他的值)。

如果参数作为输入参数,可以防止数据被改变,起到保护作用,增加程序的健壮性;

二.define 使用

1.define 定义常量

C 语言中,可以用 #define 定义一个标识符来表示一个常量,用 #define 定义标识符的一般形式为:

#define  标识符  常量   //注意define最后没有分号
//例如:
#define MAX_VALUE 100       //定义整型变量MAX_VALUE值为100
#define USER_NAME "huge"    //定义字符串变量USER_NAME值为"huge"
#define PI 3.1415926        //定义浮点数变量PI值为3.1415926

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

2.define 定义函数

//定义常量
#define MAX_VALUE 100       //定义整型变量MAX_VALUE值为100
#define USER_NAME "huge"    //定义字符串变量USER_NAME值为"huge"
#define PI 3.1415926        //定义浮点数变量PI值为3.1415926//定义函数
#define MAX(a,b) (a>b)?a:b  //取两个数最大值
#define MIN(a,b) (a<b)?a:b  //取两个数最小值

3.define 定义多行函数

//定义常量
#define MAX_VALUE 100       //定义整型变量MAX_VALUE值为100
#define USER_NAME "huge"    //定义字符串变量USER_NAME值为"huge"
#define PI 3.1415926        //定义浮点数变量PI值为3.1415926//定义简单函数
#define MAX(a,b) (a>b)?a:b  //取两个数最大值
#define MIN(a,b) (a<b)?a:b  //取两个数最小值//定义复杂多行的函数
#define   MACRO(arg1,   arg2)   do   {   \\
stmt1;   \
stmt2;   \\
}   while(0)//关键是要在每一个换行的时候加上一个 "\ "

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

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

通过 #ifndef / #define 解决头文件重复包含

#ifndef __XXX_H__
#define __XXX_H__int a=1;#endif

上面的伪代码如下:

如果(没有定义宏__XXX_H__)
{那么直接定义宏__XXX_H__定义变量a 并且赋值为 1
}
结束程序
  • 假如第一次包含时,由于没有定义宏 __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 可节省空间,避免不必要的内存分配,提高效率

五.猜你喜欢

  1. C 语言 数组下标越界和内存溢出区别
  2. C 语言 指针声明和定义
  3. C 语言 指针 p++ / p–
  4. C 语言 p++/§++/_(p++)/_p++
  5. C 语言 使用指针遍历数组
  6. C 语言 指针和数组区别
  7. C 语言 指针数组和数组指针区别
  8. C 语言 空指针 NULL
  9. C 语言 void 指针
  10. C 语言 野指针
  11. C 语言 函数值传递和址传递
  12. C 语言 函数缺省参数
  13. C 语言 函数不定长参数
  14. C 语言 函数指针
  15. C 语言 指针函数
  16. C 语言 回调函数 callback
  17. C 语言 typedef
  18. C 语言 define 定义常量
  19. C 语言 define 防止头文件重复包含
  20. C 语言 #pragma once
  21. C 语言 #include <> 与 #include “” 区别
  22. C 语言 const 修饰变量
  23. C 语言 const 修饰指针
  24. C语言 const 修饰函数
  25. C 语言 const 修饰函数参数
  26. C 语言 const 和 define 区别

未经允许不得转载:猿说编程 » C 语言 const 和 define 区别

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

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

相关文章

jq之animate()队列

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>jq之demo</title><!--线上jq库--><script src"https://code.jquery.com/jquery-3.4.1.min.js"></script><scrip…

云重磅栏目专题汇总

嗨&#xff0c;大家好&#xff0c;头条君带来的【云重磅】特别栏目&#xff0c;会在每周二第一时间为大家带来头条新闻。把握技术风向标&#xff0c;了解行业应用与实践&#xff0c;就交给我头条君吧&#xff01; 云重磅 | 阿里云开源Blink&#xff1b;华为发布5G Cloud VR&am…

C语言 __STDC__ - C语言零基础入门教程

目录 一.__STDC__简介二.__STDC__实战三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.__STDC__简介 ANSI C 定义了许多宏。在编程中您可以使用这些宏&#xff0c;但是不能直接修改这些预定义的宏。 __DATE__ 当前日期&#xff0c;一个以 “…

C语言 __LINE__ - C语言零基础入门教程

目录 一.__LINE__简介二.__LINE__实战三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.__LINE__简介 ANSI C 定义了许多宏。在编程中您可以使用这些宏&#xff0c;但是不能直接修改这些预定义的宏。 __DATE__ 当前日期&#xff0c;一个以 “…

云漫圈栏目精华汇总

云漫圈&#xff0c;用漫画的形式&#xff0c;帮你轻松掌握云中知识&#xff0c;从此周末不在寂寞。 云漫圈 | 学Python还是Java, 8张漫画带你全面分析 Java和Python两门语言都是目前非常热门的语言&#xff0c;可谓北乔峰南慕容&#xff0c;二者不分上下&#xff0c;棋逢对手…

Rust 生命周期

Rust 第17节 生命周期 先看一段错误代码 /* //一段错误的代码 // Rust 编译时会报错&#xff1b; */let r;{let x 5;r &x;}println!("{}",r);Rust 在编译时使用 借用检查器&#xff0c; 比较作用域来检查所有的借用是否合法&#xff1b; 很明显&#xff1b;r…

jq之animate() toggle

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>jq之demo</title><!--线上jq库--><script src"https://code.jquery.com/jquery-3.4.1.min.js"></script><scrip…

C语言 __FILE__ - C语言零基础入门教程

目录 一.__FILE__简介二.__FILE__实战三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.**__FILE**__简介 ANSI C 定义了许多宏。在编程中您可以使用这些宏&#xff0c;但是不能直接修改这些预定义的宏。 __DATE__ 当前日期&#xff0c;一个以…

Kafka精华问答 | kafka的使用场景是什么?

戳蓝字“CSDN云计算”关注我们哦&#xff01;Kafka是由Apache软件基金会开发的一个开源流处理平台&#xff0c;由Scala和Java编写。作为一种高吞吐量的分布式发布订阅消息系统&#xff0c;有着诸多特性。今天&#xff0c;就让我们一起来看看关于它的精华问答吧&#xff01;1Q&a…

jq之animate()操作多个属性

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>jq之demo</title><!--线上jq库--><script src"https://code.jquery.com/jquery-3.4.1.min.js"></script><scrip…

C语言 __DATE__ - C语言零基础入门教程

目录 一.__DATE__简介二.__DATE__实战三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.__DATE__简介 ANSI C 定义了许多宏。在编程中您可以使用这些宏&#xff0c;但是不能直接修改这些预定义的宏。 __DATE__ 当前日期&#xff0c;一个以 “…

要闻君说:微软拿下五角大楼超大云服务订单!恒大玩儿起了充电桩and新能源汽车?苹果公司要放弃自动驾驶业务?...

关注并标星星CSDN云计算每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 嗨&#xff0c;大家好&#xff01;偶是要闻君。新年说着说着就要到啦&#xff0c;在逐渐缩短的工作日中&#xff0c;我们还是继续哼着歌儿look look新闻吧&#xff01;文/要闻君“过…

jq之slideToggle

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>jq之demo</title><!--线上jq库--><script src"https://code.jquery.com/jquery-3.4.1.min.js"></script><scrip…

C语言 __TIME__ - C语言零基础入门教程

目录 一.__TIME__简介二.__TIME__实战三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.__TIME__简介 ANSI C 定义了许多宏。在编程中您可以使用这些宏&#xff0c;但是不能直接修改这些预定义的宏。 __DATE__ 当前日期&#xff0c;一个以 “…

云漫圈 | 有趣的海盗问题 (完整版)

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者&#xff1a;小灰来源&#xff1a;程序员小灰小灰发布的关于海盗问题的漫画&#xff0c;得到了大家的热烈讨论&#xff0c;很感谢大家的支持。这一次&#xff0c;小灰做了如下更新&#xff1a;1.修正了小灰面试阶段的一个数字错…

jq之slideup()

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>jq之demo</title><!--线上jq库--><script src"https://code.jquery.com/jquery-3.4.1.min.js"></script><scrip…

C语言 __FUNCTION__ - C语言零基础入门教程

目录 一.__FUNCTION__简介二.__FUNCTION__实战三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.__FUNCTION__简介 ANSI C 定义了许多宏。在编程中您可以使用这些宏&#xff0c;但是不能直接修改这些预定义的宏。 __DATE__ 当前日期&#xff…

jq之slidedown()

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>jq之demo</title><!--线上jq库--><script src"https://code.jquery.com/jquery-3.4.1.min.js"></script><scrip…

请重视!服务器这几个“异常”可能性预警

戳蓝字“CSDN云计算”关注我们哦&#xff01;原文&#xff1a;https://mp.weixin.qq.com/s/qAkoG-Hut9Tfd9tOFRwafg提到服务器宕机检测&#xff0c;大家会想到&#xff0c;宕机能够很快知道&#xff0c;这个有什么可做的?实际上&#xff0c;很多时候服务器宕机&#xff0c;并不…

jq之fadeTo

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>jq之demo</title><!--线上jq库--><script src"https://code.jquery.com/jquery-3.4.1.min.js"></script><scrip…