c语言中const对于define优点,为什么大多数C开发人员使用define而不是const?

这有一个非常可靠的原因:C中的const并不意味着一些常量。 这只是意味着一个variables是只读的。

在编译器需要一个常量的地方(例如非VLA数组的数组大小),使用constvariables(如fieldWidth是不可能的。

他们不一样

const只是一个限定符,它表示一个variables在运行时不能被改变。 但variables的所有其他function仍然存在:已经分配了存储空间,并且可以解决此存储空间问题。 因此,代码不仅仅把它当作一个文字来对待,而是通过访问指定的内存位置来引用variables(除非它是static const ,那么它可以被优化掉),并且在运行时加载它的值。 而作为一个constvariables已经分配了存储空间,如果你把它添加到一个头文件中,并将它包含在几个C源代码中,除非将其标记为extern否则将会出现“多符号定义”链接错误。 在这种情况下,编译器无法根据实际值优化代码(除非进行全局优化)。

#define只是用它的值replace一个名字。 此外,可以在预处理器中使用#ifdef常量:可以使用#ifdef根据其值进行条件编译,也可以使用string化运算符#来获取string的值。 而且由于编译器在编译时知道它的值,所以可以根据这个值优化代码。

例如:

#define SCALE 1 ... scaled_x = x * SCALE;

当SCALE被定义为1 ,编译器可以消除乘法,因为它知道x * 1 == x ,但是如果SCALE是( extern ) const ,则需要生成代码来获取值并执行乘法,因为值直到连接阶段才会知道。 ( extern需要使用来自多个源文件的常量。)

更接近于使用#define使用枚举:

enum dummy_enum { constant_value = 10010 };

但是这只限于整数值,并没有#define优点,所以没有被广泛的使用。

当你需要从编译它的某个库中导入一个常量值的时候, const是很有用的,或者如果它和指针一起使用的话。 或者,如果它是通过variables索引值访问的常量值数组。 否则, const比#define没有任何优势。

原因是大多数时候,你想要一个常量,而不是一个const限定的variables。 在C语言中,这两者并不是相同的。 例如,variables作为static持续时间对象的初始值设定项的一部分无效,例如非vla数组维度(例如结构中的数组大小或任何数组前C99)。

在R的答案稍微扩展一下: fieldWidth不是一个常量expression式 ; 这是一个const限定variables。 它的值直到运行时才build立,所以在需要编译时常量expression式的地方(比如在一个数组声明中,或者在一个switch语句中的一个case标签等),它不能被使用。

与预处理后扩展为常量expression式10的macrosFIELD_WIDTH比较; 这个值在编译时是已知的,所以它可以用于数组维度,案例标签等。

要添加到R.和Bart的答案:在C:枚举types常量中只有一种方法来定义符号编译时间常量。 这个标准规定这些是inttypes的。 我个人会写你的例子

enum { fieldWidth = 10 };

但是我觉得C程序员的口味差别很大。

虽然const int并不总是合适的,但是如果你定义了一个整型值,枚举通常会作为#define的替代。 这实际上是我在这种情况下的首选。

enum { FIELD_WIDTH = 16384 }; char buf[FIELD_WIDTH];

在C ++中,这是一个巨大的优势,因为您可以将枚举的范围限定在类或名称空间中,而不能将范围定义为#define。

在C中,你没有命名空间,也不能在一个结构体内枚举枚举的范围,甚至不能确定你的types是否安全,所以我实际上看不到任何主要的优点,尽pipe也许有些C程序员会指出。

根据K&R(第2版,第211页),“const和volatile属性是ANSI标准新增的”。 这可能意味着真正旧的ANSI代码根本就没有这些关键字,这实际上只是一个传统问题。 此外,它表示,编译器应该检测到更改constvariables的尝试,但除此之外可能会忽略这些限定符。 我认为这意味着一些编译器可能不会优化包含constvariables的代码,以便在机器代码中表示为中间值(就像#define一样),这可能会花费额外的时间访问远端内存并影响性能。

一些C编译器会将所有constvariables存储在二进制文件中,如果准备大量的系数可以在embedded式世界中占用大量的空间。

相反:使用const允许在现有的程序上闪烁来改变特定的参数。

在C中定义数字常量的最好方法是使用枚举 。 阅读K&R的The C Programming Language,第39页的相应章节。

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

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

相关文章

c语言程序设计期末试卷A,《C语言程序设计》期末试卷(A)..doc

《C语言程序设计》期末试卷(A).2011-12-1学期《C语言程序设计》期末试卷(A)班级____________姓名____________学号________________大题号一二三四总分得 分判卷 /核分人“一、选择题”使用答题卡选择。“二、看程序写运行结果”答题处:题号答 案二、1二、2二、3“三…

codeforces B. Strongly Connected City(dfs水过)

题意:有横向和纵向的街道,每个街道只有一个方向,垂直的街道相交会产生一个节点,这样每个节点都有两个方向, 问是否每一个节点都可以由其他的节点到达.... 思路:规律没有想到,直接爆搜&#xff0…

c语言数组两个值交换,如可交换两个数组中的元素?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include #include int main(void){int a[]{1,2,3,4,5,6,7,8};int b[]{9,10,11,12,13,15};int lena,lenb,randa,randb,randtimes;int i,temp;srand((unsigned)time(NULL));lena sizeof(a)/sizeof(int);lenb sizeof(b)/s…

Uvaoj 11248 Frequency Hopping(Dinic求最小割)

题意:1到n节点(节点之间有一定的容量),需要流过C的流量,问是否可以?如果可以输出possible, 否则如果可以扩大任意一条边的容量 可以达到目的,那么输出possible option:接…

随机数归并排序c语言,用C语言实现归并排序

#include#include#include#include#define random(i) (rand()%i)#define N 12#define INFINITY 99999999//要排序的数存放在a数组汇总,p,q,r是数组下标void Merge(int *a,int p,int q,int r){int n1q-p1;int n2r-q;int *L(int *)malloc(sizeof(int)*n1);int *R(int …

UVAoj 11324 - The Largest Clique(tarjan + dp)

题意&#xff1a;给定一个有向图&#xff0c;寻找一个点数最大集合&#xff0c;使得这个集合中的任意两个点 u,v, 都有u->v 或者 v->u 或者u<>v 思路&#xff1a;首先将强连通分量通过tarjan算法求出来&#xff0c;然后进行缩点&#xff0c;也就是每一个缩点 所组成…

android开发蓝牙自动连接电脑上,Android蓝牙开发之自动连接设备

自动连接使用的是SharedPreferences这个来解决。private void Automaticconnection() {SharedPreferences sp getSharedPreferences("Dizhi", MODE_PRIVATE);String address sp.getString("address", "");if (!address.equals("")) …

hdu 2014鞍山赛区 5073 Galaxy

题意&#xff1a;就是给你 n 个数&#xff0c;代表n个星球的位置&#xff0c;每一个星球的重量都为 1 &#xff01; 开始的时候每一个星球都绕着质心转动&#xff0c;那么质心的位置就是所有的星球的位置之和 / 星球的个数 现在让你移动 k 个星球到任意位置&#xff08;多个星球…

android onitemclicklistener 参数,android – 对listview中的项使用setOnItemClickListener

大家好,有一个应用程序,可以在SD卡上保存音频.我创建了一个listview,它从sdcard中检索文件名.我正在尝试设置一个监听器,所以当单击文件名时,我可以启动另一个播放该文件的意图.当我尝试设置监听器并传入一个新的OnItemClickListener()时,eclipse是红色的下划线.我知道我必须实…

DRF之请求与响应

目录 一、模块与包回顾 二、反序列化校验源码分析(了解) 三、断言 四、drf之请求 【1】源码分析 【2】配置视图类能处理的编码格式 五、drf之响应 【1】源码 【2】响应编码格式 一、模块与包回顾 模块与包 什么是模块&#xff1f; 一个py文件&#xff0c;被别的py文件…

android 常用注解,Android 开发小工具之:注解 Annotation

Android Support 包之一的 support-annotations是通过静态编译检测来提高代码质量的一个注解工具。里面包含了 Android 开发中常用的代码检测注解&#xff0c;帮助开发者提高代码质量。通过 SDK Manager下载 Android Support Repository 后&#xff0c;在 Gradle 中通过如下声明…

codeforces B. Friends and Presents(二分+容斥)

题意&#xff1a;从1....v这些数中找到c1个数不能被x整除&#xff0c;c2个数不能被y整除&#xff01; 并且这c1个数和这c2个数没有相同的&#xff01;给定c1, c2, x, y&#xff0c; 求最小的v的值&#xff01; 思路&#xff1a; 二分容斥&#xff0c;二分找到v的值&#xff0c;…

android音量键广播,音量控制键控制的音频流(setVolumeControlStream)描述

音量控制键控制的音频流(setVolumeControlStream)描述2021-01-03 16:18Android教程网 Android当开发多媒体应用或者游戏应用的时候&#xff0c;需要使用音量控制键来设置程序的音量大小,在Android系统中有多种音频流,感兴趣的朋友可以了解下当开发多媒体应用或者游戏应用的时候…

eclipse的使用

eclipse如何打开一个已存在的工程&#xff01;先给eclipse创建一个workspace,这个workspace就是一个文件夹用来管理eclipse项目的&#xff0c;或者修改eclipse的workspace,选择菜单file->switch workspace->other,选择一个已经存在的workspace。将已经存在的项目导入到wo…

Android延伸布局到状态栏,Android 状态栏透明

前言&#xff1a;最近项目大量用到状态栏透明&#xff0c;网上也出现很多库可以直接拿来用&#xff0c;个人认为没有必要那么重引用到一个库(有木有同学和我有一样的想法)&#xff0c;所以研究了一番&#xff0c;在此做个记录加强记忆也便后期查阅&#xff0c;如果无意中有幸能…

glassfish服务器默认的网页所在的位置

http://localhost:8080/ 默认打开的网页所在的位置 E:/glassfish-4.1/glassfish/domains/domain1/docroot/index.html 转载于:https://www.cnblogs.com/hujunzheng/p/4052920.html

华为HarmonyOS 鸿蒙,华为鸿蒙HarmonyOS2.0手机开发者Beta版正式发布

据悉&#xff0c;本次手机开发者Beta测试支持以下中国境内主制式手机及平板电脑。手机&#xff1a;全网通(5G双卡)P40 、 全网通版P40 Pro、Mate30、Mate30(5G) 、Mate30 Pro、Mate30 Pro(5G)&#xff0c;型号清单为ANA-AN00、ELS-AN00、TAS-AL00、TAS-AN00、LIO-AL00、LIO-AN0…

http协议客户端向服务器端请求时一般需要发送的内容

out.println("GET /shopping/index.html HTTP/1.1");//请求行 包括请求方式&#xff0c;文件路径&#xff0c; http协议版本&#xff08;必写&#xff09;请求头.... out.println("Aceept: */*");//客户端能够处理的文件类型&#xff08;不是必须&#xff…

android oneshot自动播放bug,移动端常见bug汇总001

前言本文是摘录整理了移动端常见的一些bug以及解决方案&#xff0c;第一篇&#xff0c;后面还会有持续的文章更新整理。点击样式闪动Q: 当你点击一个链接或者通过Javascript定义的可点击元素的时候&#xff0c;它就会出现一个半透明的灰色背景。A:根本原因是-webkit-tap-highli…

int.class 与 Integer.class

TYPE 表示的引用类型所对应的基本类型的Class对象&#xff01; 转载于:https://www.cnblogs.com/hujunzheng/p/4055471.html