C语言—对形式参数使用const
作者:追风剑情 发布于:2019-10-10 20:01 分类:C
示例
//Visual Studio中加上这句才可以使用scanf() //否则只能使用scanf_s() #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdbool.h> #define SIZE 5 void show_array(const double ar[], int n); void mult_array(double ar[], int n, double mult); //argc: 参数个数 argv[]: 参数数组 int main(int argc, char *argv[]) { double dip[SIZE] = {20.0, 17.66, 8.2, 15.3, 22.22}; printf("The original dip array:\n"); show_array(dip, SIZE); mult_array(dip, SIZE, 2.5); printf("The dip array after calling mult_array():\n"); show_array(dip, SIZE); system("pause"); return 0; } /* 显示数组的内容 */ void show_array(const double ar[], int n) { //形参ar加上const后,在函数中修改数组元素的值,将会引起报错。 int i; for (i = 0; i < n; i++) printf("%8.3f ", ar[i]); putchar('\n'); } /* 把数组的每个元素都乘以相同的值 */ void mult_array(double ar[], int n, double mult) { int i; for (i = 0; i < n; i++) ar[i] *= mult; }
const的其他内容
1、使用const创建变量
const double PI = 3.14159;
const int nochange = 12;
//不可修改数组的值
const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
虽然用#define指令可以创建类似功能的符号常量,但是const的用法更加灵活。可以创建const数组、const指针和指向const的指针。
C99标准中在一条声明中多次使用同一个限定符,多余的限定符将被忽略,例如const const const int n = 6;等效于const int n = 6;这允许我们编写类似下面的代码:
typedef const int zip;
const zip q = 8;
void ofmouth(int * const a1, int * restrict a2, int n); //C99之前的风格
void ofmouth(int a1[const], int a2[restrict], int n); //C99允许,在声明函数形参时,指针表示法和数组表示法都可以使用这两个限定符。
duble stick(double ar[static 20]); //C99允许,参数是一个指向数组首元素的指针,且该数组至少有20个元素。
2、使用const保护数组
#define MONTHS 12
const int days[MONTHS] = {31,28,31,30,31,30,31,31,30,31,30,31};
days[9] = 44; /* 编译错误 */
double rates[5] = {88.9,100.12,59.45,183.11,340.5};
const double * pd = rates; //pd指向数组首元素
*pd = 29.89; // 不允许
pd[2] = 222.22; //不允许
rates[0] = 99.99;//允许,因为rates未被const限定
pd++; //允许
指向const的指针通常用于函数形参中,表明该函数不会使用指针改变数据。例如
void show_array(const double *ar, int n);
关于指针赋值和const需要注意一些规则。首先,把const数据或非const数据的地址初始化为指向const的指针或为其赋值是合法的:
double rates[5] = {88.99,100.12,59.45,183.11,340.5};
const double locked[4] = {0.08, 0.075, 0.0725, 0.07};
const double * pc = rates; //有效
pc = locked; //有效
pc = &rates[3];//有效
然而,只能把非const数据的地址赋给普通指针:
double * pnc = rates; //有效
pnc = locked; //无效
pnc = &rates[3];//有效
这个规则非常合理,否则,通过指针就能改变const数组中的数据。
show_array(rates, 5); //有效
show_array(locked, 4); //有效
因此,对 函数的形参使用const不仅能保护数据,还能让函数处理const数组。
另外,不应该把const数组名作为实参传递给mult_array()这样的函数:
mult_array(rates, 5, 1.2); //有效
mult_array(locked, 4, 1.2); //不要这样做
C标准规定,使用非const标识符(如,mult_array()的形参ar)修改const数据(如,locked)导致的结果是未定义的。
const还有其他的用法。例如,可以声明并初始化一个不能指向别处的指针,关键是const的位置:
double * const pc = rates; //pc指向数组的开始
pc = &rates[2]; //不允许,因为该指针不能指向别处
*pc = 92.99; //没问题 -- 更改rates[0]的值
可以用这种指针修改它所指向的值,但是它只能指向初始化时设置的地址。
最后,在创建指针时还可以使用const两次,该指针既不能更改它所指向的地址,也不能修改指向地址上的值:
const double * const pc = rates;
pc = &rates[2]; //不允许
*pc = 92.99; //不允许
3、在指针和形参声明中使用const
const float * pf; //pf指向的值不能被修改,而pf本身的值可以改变
float * const pt; //pt本身的值不能更改,但它所指向的值可以改变
const float * const ptr; //指针本身及它指向的值都不能改变
float const * pfc; //与const float * pfc;相同
把const放在类型名之后、*之前,说明该指针不能用于改变它所指向的值。简而言之,const放在*左侧任意位置,限定了指针指向的数据不能改变;const放在*的右侧,限定了指针本身不能改变。
4、对全局数据使用const
使用全局变量是一种冒险的方法,因为这样做暴露了数据,程序的任何部分都能更改数据。如果把数据设置为const,就可避免这样的危险,因此用const限定符声明全局数据很合理。可以创建const变量、const数组和const结构。
然而,在这文件间共享const数据要小心。可以采用两个策略。第一,遵循外部变量的常用规则,即在一个文件中使用定义式声明,在其他文件中使用引用式声明(用extern关键字):
/* file1.c --定义了一些外部const变量 * const double PI = 3.14159; const char * MONTHS[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
/* file2.c --使用定义在别处的外部const变量 */ extern const double PI; extern const * MONTHS [];另一种方案是,把const变量放在一个头文件中,然后在其他文件中包含该头文件:
/* constant.h --定义了一些外部const变量 */ static const double PI = 3.14159; static const char * MONTHS[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
/* file1.c --使用定义在别处的外部const变量 */ #include "constant.h" /* file2.c --使用定义在别处的外部const变量 */ #include "constant.h"这种方案必须在头文件中用关键字static声明全局const变量。如果去掉static那么在file1.c和file2.c中包含constant.h将导致每个文件中都有一个相同标识符的定义式声明,C标准不允许这样做(然而,有些编译器允许)。实际上,这种方案相当于给每个文件提供了一个单独的数据副本。由于每个副本只对该文件可见,所以无法用这些数据和其他文件通信。不过没关系,它们都是完全相同(每个文件都包含相同的头文件)的const数据(声明时使用了const关键字),这不是问题。
头文件方案的好处是,方便你偷懒,不用惦记着在一个文件中使用定义式声明,在其他文件中使用引用式声明。所有的文件都只需要包含一个头文件即可。但它的缺点是,数据是重复的。对于前面的例子而言,这不算什么问题,但是如果const数据包含大的数组,就不能视而不见了。
注意,以static声明的文件作用域变量具有内部链接属性。
标签: C语言
日历
最新文章
随机文章
热门文章
分类
存档
- 2024年11月(3)
- 2024年10月(5)
- 2024年9月(3)
- 2024年8月(3)
- 2024年7月(11)
- 2024年6月(3)
- 2024年5月(9)
- 2024年4月(10)
- 2024年3月(11)
- 2024年2月(24)
- 2024年1月(12)
- 2023年12月(3)
- 2023年11月(9)
- 2023年10月(7)
- 2023年9月(2)
- 2023年8月(7)
- 2023年7月(9)
- 2023年6月(6)
- 2023年5月(7)
- 2023年4月(11)
- 2023年3月(6)
- 2023年2月(11)
- 2023年1月(8)
- 2022年12月(2)
- 2022年11月(4)
- 2022年10月(10)
- 2022年9月(2)
- 2022年8月(13)
- 2022年7月(7)
- 2022年6月(11)
- 2022年5月(18)
- 2022年4月(29)
- 2022年3月(5)
- 2022年2月(6)
- 2022年1月(8)
- 2021年12月(5)
- 2021年11月(3)
- 2021年10月(4)
- 2021年9月(9)
- 2021年8月(14)
- 2021年7月(8)
- 2021年6月(5)
- 2021年5月(2)
- 2021年4月(3)
- 2021年3月(7)
- 2021年2月(2)
- 2021年1月(8)
- 2020年12月(7)
- 2020年11月(2)
- 2020年10月(6)
- 2020年9月(9)
- 2020年8月(10)
- 2020年7月(9)
- 2020年6月(18)
- 2020年5月(4)
- 2020年4月(25)
- 2020年3月(38)
- 2020年1月(21)
- 2019年12月(13)
- 2019年11月(29)
- 2019年10月(44)
- 2019年9月(17)
- 2019年8月(18)
- 2019年7月(25)
- 2019年6月(25)
- 2019年5月(17)
- 2019年4月(10)
- 2019年3月(36)
- 2019年2月(35)
- 2019年1月(28)
- 2018年12月(30)
- 2018年11月(22)
- 2018年10月(4)
- 2018年9月(7)
- 2018年8月(13)
- 2018年7月(13)
- 2018年6月(6)
- 2018年5月(5)
- 2018年4月(13)
- 2018年3月(5)
- 2018年2月(3)
- 2018年1月(8)
- 2017年12月(35)
- 2017年11月(17)
- 2017年10月(16)
- 2017年9月(17)
- 2017年8月(20)
- 2017年7月(34)
- 2017年6月(17)
- 2017年5月(15)
- 2017年4月(32)
- 2017年3月(8)
- 2017年2月(2)
- 2017年1月(5)
- 2016年12月(14)
- 2016年11月(26)
- 2016年10月(12)
- 2016年9月(25)
- 2016年8月(32)
- 2016年7月(14)
- 2016年6月(21)
- 2016年5月(17)
- 2016年4月(13)
- 2016年3月(8)
- 2016年2月(8)
- 2016年1月(18)
- 2015年12月(13)
- 2015年11月(15)
- 2015年10月(12)
- 2015年9月(18)
- 2015年8月(21)
- 2015年7月(35)
- 2015年6月(13)
- 2015年5月(9)
- 2015年4月(4)
- 2015年3月(5)
- 2015年2月(4)
- 2015年1月(13)
- 2014年12月(7)
- 2014年11月(5)
- 2014年10月(4)
- 2014年9月(8)
- 2014年8月(16)
- 2014年7月(26)
- 2014年6月(22)
- 2014年5月(28)
- 2014年4月(15)
友情链接
- Unity官网
- Unity圣典
- Unity在线手册
- Unity中文手册(圣典)
- Unity官方中文论坛
- Unity游戏蛮牛用户文档
- Unity下载存档
- Unity引擎源码下载
- Unity服务
- Unity Ads
- wiki.unity3d
- Visual Studio Code官网
- SenseAR开发文档
- MSDN
- C# 参考
- C# 编程指南
- .NET Framework类库
- .NET 文档
- .NET 开发
- WPF官方文档
- uLua
- xLua
- SharpZipLib
- Protobuf-net
- Protobuf.js
- OpenSSL
- OPEN CASCADE
- JSON
- MessagePack
- C在线工具
- 游戏蛮牛
- GreenVPN
- 聚合数据
- 热云
- 融云
- 腾讯云
- 腾讯开放平台
- 腾讯游戏服务
- 腾讯游戏开发者平台
- 腾讯课堂
- 微信开放平台
- 腾讯实时音视频
- 腾讯即时通信IM
- 微信公众平台技术文档
- 白鹭引擎官网
- 白鹭引擎开放平台
- 白鹭引擎开发文档
- FairyGUI编辑器
- PureMVC-TypeScript
- 讯飞开放平台
- 亲加通讯云
- Cygwin
- Mono开发者联盟
- Scut游戏服务器引擎
- KBEngine游戏服务器引擎
- Photon游戏服务器引擎
- 码云
- SharpSvn
- 腾讯bugly
- 4399原创平台
- 开源中国
- Firebase
- Firebase-Admob-Unity
- google-services-unity
- Firebase SDK for Unity
- Google-Firebase-SDK
- AppsFlyer SDK
- android-repository
- CQASO
- Facebook开发者平台
- gradle下载
- GradleBuildTool下载
- Android Developers
- Google中国开发者
- AndroidDevTools
- Android社区
- Android开发工具
- Google Play Games Services
- Google商店
- Google APIs for Android
- 金钱豹VPN
- TouchSense SDK
- MakeHuman
- Online RSA Key Converter
- Windows UWP应用
- Visual Studio For Unity
- Open CASCADE Technology
- 慕课网
- 阿里云服务器ECS
- 在线免费文字转语音系统
- AI Studio
- 网云穿
- 百度网盘开放平台
- 迅捷画图
- 菜鸟工具
- [CSDN] 程序员研修院
- 华为人脸识别
- 百度AR导航导览SDK
- 海康威视官网
- 海康开放平台
- 海康SDK下载
- git download
交流QQ群
-
Flash游戏设计: 86184192
Unity游戏设计: 171855449
游戏设计订阅号