c语言修饰符总结const、static、volatile、auto、extern、register

写在前面

今天下午一个同事问「register」关键字是什么作用?噢,你说的是「register」啊,它的作用是……脑袋突然断片儿,我擦,啥意思来着,这么熟悉的陌生感。做C语言开发时间也不短了,不过好像没有用到过「register」,但作用还是知道的,一下子想不起来了,一万个草泥马飞奔过来。

其实C语言中除了register外,还包含常见的conststaticvolatileautoextern等修饰符,现在一起再总结一下好了。

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 的。

转载:https://www.cnblogs.com/liwei0526vip/p/8620595.html

转载于:https://www.cnblogs.com/piterzhang/p/9026330.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在C语言中,autostaticextern、registerconstvolatile是用来定义变量和函数的存储类别和属性的关键字。\[2\] auto是默认的存储类别,用于定义自动变量,它的生命周期与所在的代码块相同。static用于定义静态变量,它的生命周期在程序运行期间都存在,但作用域仅限于所在的代码块。extern用于声明外部变量或函数,它表示该变量或函数是在其他文件中定义的。register用于定义寄存器变量,它的值存储在寄存器中,以提高访问速度。const用于定义常量,一旦被赋值后就不能再修改。volatile用于定义易变的变量,每次都会从内存中获取值,而不是从缓存中获取值,适用于对硬件寄存器的访问、多线程中访问全局变量和中断中访问非自动类型的变量。\[3\] 关键字constvolatile的使用可以提高程序的可读性和可靠性,因此在编写程序时,我们应该根据需要合理地使用这些关键字。 #### 引用[.reference_title] - *1* *2* [C中的autostatic、registerexternconst和volitate](https://blog.csdn.net/m0_70888041/article/details/128286925)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [c语言中的六个存储类型:auto register static extern const volatile](https://blog.csdn.net/a2998658795/article/details/125958396)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值