理解C语言中几个常见修饰符
写在前面
今天下午一个同事问「register」关键字是什么作用?噢,你说的是「register」啊,它的作用是……脑袋突然断片儿,我擦,啥意思来着,这么熟悉的陌生感。做C语言开发时间也不短了,不过好像没有用到过「register」,但作用还是知道的,一下子想不起来了,一万个草泥马飞奔过来。
其实C语言中除了register外,还包含常见的const、static、volatile、auto、extern等修饰符,现在一起再总结一下好了。
register 修饰符
register,寄存器变量,告诉编译器它所声明的变量在程序中使用的频率非常高,请编译器尽量将此变量放在寄存器中,这样程序执行速度更快。但实际上编译器不一定这么做,可以忽略此选项。
register 修饰符的几点注意点:
- 变量必须是 CPU 接受的类型,单个值,长度小于等于整数的长度
- 只能使用于局部变量和函数形参,全局(register)变量是非法的
- 无论寄存器变量是否存放在寄存器中,它地址都是不能访问的(取&)
- 其实过量的寄存器声明并没有什么坏处,寄存器可以忽略
const 修饰符
const修饰普通变量
有时候我们希望定义一个变量,它的值在整个作用域都不能变,比如定义缓冲区大小等,可以用 const 来修饰。
// 定义常量 strlen
const int strlen = 4096;
// 试图修改 strlen 变量,编译器会报错
strlen = 2048;
一般常量在定义时同时进行初始化,否则在定义完之后不能对其进行赋值操作,常见的初始化方式有:
const int num = get_num(); // 运行时初始化
const int num = n; // 运行时初始化
const int num = 10; // 编译时初始化
const 变量真的就不能修改吗?看个例子:
const int bufsize = 1024;
int *p = &bufsize;
*p = 2048;
printf("bufsize = %d\n", bufsize);
打印结果是2048。其实 const 修饰的变量不变的本质含义是程序中通过引用变量符号 bufsize 时不能够进行修改,而不是 bufsize 变量所指向那段内存数据不能修改。
const修改指针变量
const 可以与指针变量一起使用,可以限制指针变量,也可以限制指针变量指向的内容。
const int *ptr; // 指针指向内容不能修改
int const *ptr; // 与第1种等价
int* const ptr; // 指针ptr变量本身不能修改
const int* const ptr; // 指针变量和指针变量指向内容都不能修改
const修改函数参数
其实C语言中使用 const 定义常量并没有什么优势,完全可以使用#define来替代。const 通常用在函数形参中,当形参是一个指针,为了防止函数内部修改指针指向的内容时,就可以用 const 限制。
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
常见C语言标准库中都有const限制,在我们自定义函数中也可以适当使用 const 来保证程序的健壮性。
const 类型与非 const 类型转换
当一个指针类似const char *str1,表示str1指针指向内容不能修改;但如果将 str1 赋值给 str2,这时 str2 没有通过 const 限制,通过 str2 就可以修改指针指向内容,这就失去了 const 的意义,编译器是不提倡这么做的。
const 与非 const 是两种类型,将非 const 指针赋值给 const 指针,编译器接受;如果将 const 指针赋值给非 const 指针,这样将增加指针变量的权限,不安全,有可能发生写入的危险。所以我们在写程序时遵守,对指针类型尽可能加 const 修饰;不能将 const 指针赋值给 const 指针。
static 修饰符
static 修饰符在程序中使用最为广泛,它大概有如下几种用法:
- 修饰局部变量:增加了局部变量的生命周期,若定义未初始化,则默认初始化为0
- 修饰全局变量:缩小了全局变量的作用域,限制在本模块(文件)中访问
- 修饰函数:缩小了函数的作用于,限制函数只能被本模块调用
volatile 修饰符
关键字 volatile 感觉是和 register 有点相反的意思,表示变量随时可能被修改,且系统对实时性要求很高,请一定从内存中读取内容,不要直接拷贝寄存器中的数据,有可能数据老旧。常见的使用场合包括中断服务程序和嵌入式系统的寄存器相关操作。
extern 修饰符
关键字 extern 常用在变量和函数声明前,用来说明此变量或函数是在别处定义过的,要在此处引用。
在 hello.c 中:
void hello()
{
printf("Hello.\n");
}
在 main.c 文件中:
extern void hello();
hello(); // 声明之后调用 hello 函数
在 main.c 文件被编译时,告诉编译器hello()在别的地方定义过了,这里只是引用一下,放心编译好了,在程序最后链接的时候会去找hello实际定义的函数。
auto 修饰符
关键字 auto 其实可以理解为就是局部变量的显示说明,程序中很少去显示声明某个变量为 auto 的。
理解C语言中几个常见修饰符的更多相关文章
- Java语言中的访问权限修饰符
一个Java应用有很多类,但是有些类,并不希望被其他类使用.每个类中都有数据成员和方法成员,但是并不是每个数据和方法,都允许在其他类中调用.如何能做到访问控制呢?就需要使用访问权限修饰符. Java语 ...
- 深入理解C语言 - 指针使用的常见错误
在C语言中,指针的重要性不言而喻,但在很多时候指针又被认为是一把双刃剑.一方面,指针是构建数据结构和操作内存的精确而高效的工具.另一方面,它们又很容易误用,从而产生不可预知的软件bug.下面总结一下指 ...
- 【转载】理解C语言中的关键字extern
原文:理解C语言中的关键字extern 最近写了一段C程序,编译时出现变量重复定义的错误,自己查看没发现错误.使用Google发现,自己对extern理解不透彻,我搜到了这篇文章,写得不错.我拙劣的翻 ...
- 理解C语言中指针的声明以及复杂声明的语法
昨天刚把<C程序设计语言>中"指针与数组"章节读完,最终把心中的疑惑彻底解开了.如今记录下我对指针声明的理解.顺便说下怎样在C语言中创建复杂声明以及读懂复杂声明. 本文 ...
- 这样子来理解C语言中指针的指针
友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...
- Java语言中有4种访问修饰符
转载:http://wuhaidong.iteye.com/blog/851754 Java语言中有4种访问修饰符 在Java语言中有4中访问修饰符:package(默认).private.publi ...
- Java 中的 protected 访问修饰符你真的了解吗?
protected Java 中的 protected 访问修饰符 总结 在同一个包中,类中 protected 或 default 修饰的属性或方法可以在类外被其对象 (实例) 外部访问,也可以被子 ...
- iOS中copy和strong修饰符的区别
iOS中copy和strong修饰符的区别 //用copys修饰的生成的都是不可变的对象 ,如果调用可变类型方法的直接报错 @property(nonatomic,copy)NSString * cp ...
- 《挑战30天C++入门极限》入门教程:C++中的const限定修饰符
入门教程:C++中的const限定修饰符 const修饰符可以把对象转变成常数对象,什么意思呢? 意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用! ...
随机推荐
- 《设计模式之禅》--设计模式大PK
创建类模式包括工厂方法模式.建造者模式.抽象工厂模式.单例模式和原型模式. 其中单例模式要保持在内存中只有一个对象,原型模式是要求通过复制的方式产生一个新的对象. [工厂方法(抽象工厂) VS 建造者 ...
- hdu4825 01字典树+贪心
从高位向低位构造字典树,因为高位得到的数更大. AC代码: #include<cstdio> using namespace std; typedef long long LL; cons ...
- React——共享state
通常,一些组件需要反映相同的数据更改,这种情况推荐将共享state移动到它们最近的公共祖先上. 在这里有一个例子:有一个温度计算器计算在给定温度是否能让水沸腾,用户可以输入华氏温度也能输入摄氏温度,当 ...
- Service IP 原理 - 每天5分钟玩转 Docker 容器技术(137)
Service Cluster IP 是一个虚拟 IP,是由 Kubernetes 节点上的 iptables 规则管理的. 可以通过 iptables-save 命令打印出当前节点的 iptable ...
- web前端研发工程师编程能力成长之路
[背景] 如果你是刚进入WEB前端研发领域,想试试这潭水有多深,看这篇文章吧:如果你是做了两三年WEB产品前端研发,迷茫找不着提高之路,看这篇文章吧:如果你是四五年的前端开发高手,没有难题能难得住你的 ...
- 用Node.JS+MongoDB搭建个人博客(页面模板)(五)(结束)
<差不多先生> 我是差不多先生,我的差不多是天生.也代表我很天真,也代表我是个闲人.这差不多的人生,总是见缝插针. 求学的道路上总是孤独的,即使别人不理解我,认为我是奇葩!但没关系,我会坚 ...
- 用Node.JS+MongoDB搭建个人博客(model目录)(三)
model目录主要是封装一些经常使用的方法,便于使用. setting.js文件: 很简单,就单单封装了一个url作为公用,以后改就方便改了. md5.js(不推荐用): db.js文件: db.js ...
- jQuery手机发送验证码倒计时代码
<!DOCTYPE> <html> <head> <meta charset="UTF-8"> <script type=&q ...
- Linux OpenSSH后门的添加与防范
引言:相对于Windows,Linux操作系统的密码较难获取.不过很多Linux服务器配置了OpenSSH服务,在获取root权限的情况下,可以通过修改或者更新OpenSSH代码等方法,截取并保存其S ...
- mysql数据库字符集编码查看以及设置
show variables like %char% character_set_client | gb2312 character_s ...