C语言 const使用详解
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 const使用详解相关的知识,希望对你有一定的参考价值。
文章目录
const前导知识
定义
它是定义只读变量的关键字,或者说 const 是定义常变量的关键字。
const 定义的是变量,但又相当于常量;说它定义的是常量,但又有变量的属性,所以叫常变量
基本用法
用 const 定义的变量的值是不允许改变的,即不允许给它重新赋值,即使是赋相同的值也不可以。所以说它定义的是只读变量。这也就意味着必须在定义的时候就给它赋初值。
修饰变量
用 const 修饰的变量,无论是全局变量还是局部变量,生存周期都是程序运行的整个过程。全局变量的生存周期为程序运行的整个过程这个是理所当然的。而使用 const 修饰过的局部变量就有了静态特性,它的生存周期也是程序运行的整个过程。我们知道全局变量是静态的,静态的生存周期就是程序运行的整个过程。但是用const修饰过的局部变量只是有了静态特性,并没有说它变成了静态变量。
(补充一下:局部变量存储在栈中,静态变量存储在静态存储区中,而经过 const 修饰过的变量存储在内存中的“只读数据段”中。只读数据段中存放着常量和只读变量等不可修改的量。)
变量?常量?
前面说过 const 是定义只读变量的关键字,所以归根结底这个定义的只读变量最后也是变量,但是我们用的时候就相当于是定义一个常量
const定义的是变量,而define定义的是常量。
const与define的区分:
这一点他和 define
是有区分的:
- define是预编译指令,而const是普通变量的定义。define定义的宏是在预处理阶段展开的,而const定义的只读变量是在编译运行阶段使用的。
- define定义的宏在编译后就不存在了,它不占用内存,因为它不是变量,系统只会给变量分配内存。但const定义的常变量本质上仍然是一个变量,具有变量的基本属性,有类型、占用存储单元。
- const定义的是变量,而宏定义的是常量,所以const定义的对象有数据类型,而宏定义的对象没有数据类型。
代码应用
const 定义变量
定义
const int i = 0;
//i = 100; //如果下面加这句的话为 错误,只读变量初始化之后不能修改
并且定义const变量最好初始化,下面的代码在vs中就会报错。
const int j; // 报错
修改const 变量值
c语言的const是一个只读变量,并不是一个常量,可通过指针间接修改。
参考下面的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test01() {
// c语言的const是一个只读变量,并不是一个常量,可通过指针间接修改
const int k = 10;
//k = 100; //错误,不可直接修改,我们可通过指针间接修改
printf("k:%d\\n", k);
int* p = (int *)(&k);
*p = 100;
printf("k:%d\\n", k);
}
int main()
{
test01();
return 0;
}
更详细的探究可以参考这篇博文,我没有在g++里面试,我在VS里试不能改
https://blog.csdn.net/heyabo/article/details/8745942
const 修饰指针
const放在*号左侧,修饰指针指向的内存空间不能修改,但可修改指针的指向,这里相当于修饰 普通数据变量,不可以修改变量的存的值。
const放在*号的右侧,修饰指针的指向不能修改,但是可修改指针指向的内存空间,这里相当于修饰的指针变量,不可以修改指针的值,但可以修改存的值。
const放在*号的左右两侧,那么就是说明指针的指向和指针指向的内存空间都不能修改,也就是存的数据值和指针的指向都不能改。
看下面的代码理解一下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
int a = 10;
int b = 20;
//const放在*号左侧 修饰p_a指针指向的内存空间不能修改,但可修改指针的指向
const int* p_a = &a;
printf("修改前 *p_a:%d\\n",*p_a);
//*p_a = 100; //不可修改指针指向的内存空间
p_a = &b; //可修改指针的指向
printf("修改后 *p_a:%d\\n", *p_a);
printf("-------------------\\n", *p_a);
//const放在*号的右侧, 修饰指针的指向不能修改,但是可修改指针指向的内存空间
int* const p_b = &a;
printf("修改前 *p_b:%d\\n", *p_b);
//p_b = &b; //不可修改指针的指向
*p_b = 100; //可修改指针指向的内存空间
printf("修改后 *p_b:%d\\n", *p_b);
//指针的指向和指针指向的内存空间都不能修改
const int* const p_c = &a;
}
int main()
{
test();
return 0;
}
const 与 struct 的爱恨情仇
例如下面的结构体,
struct Person {
char name[64];
int id;
int age;
int score;
};
如果我想打印结构体变量的信息,普通的写法就是这样写
// 每次都对对象进行拷贝,效率低,应该用指针
void printPersonByValue(struct Person person) {
printf("Name:%s\\n", person.name);
printf("Name:%d\\n", person.id);
printf("Name:%d\\n", person.age);
printf("Name:%d\\n", person.score);
}
但是这样,每次传入的是形式参数,形式参数每次都对 对象进行拷贝,效率低,那么我们应该要用指针
// 但是用指针会有副作用,可能会不小心修改原数据
void printPersonByPointer(struct Person *person) {
printf("Name:%s\\n", person->name);
printf("Name:%d\\n", person->id);
printf("Name:%d\\n", person->age);
printf("Name:%d\\n", person->score);
}
但是直接用指针会有副作用,可能会不小心修改原数据,如果我在打印函数里去使用结构体变量的话,那么就可能会对原来的数据造成破坏。
这里我们就要用到const,来修饰传入的参数,作为只读实际参数,不让用户对其进行修改
// 解决
void printPersonByPointer(const struct Person *person) {
printf("Name:%s\\n", person->name);
printf("Name:%d\\n", person->id);
printf("Name:%d\\n", person->age);
printf("Name:%d\\n", person->score);
}
全部代码我也放在这
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//const指针用法
struct Person {
char name[64];
int id;
int age;
int score;
};
//每次都对对象进行拷贝,效率低,应该用指针
void printPersonByValue(struct Person person) {
printf("Name:%s\\n", person.name);
printf("Name:%d\\n", person.id);
printf("Name:%d\\n", person.age);
printf("Name:%d\\n", person.score);
}
//但是用指针会有副作用,可能会不小心修改原数据
void printPersonByPointe(struct Person *person) {
printf("Name:%s\\n", person->name);
printf("Name:%d\\n", person->id);
printf("Name:%d\\n", person->age);
printf("Name:%d\\n", person->score);
}
//但是用指针会有副作用,可能会不小心修改原数据
void printPersonByPointer(const struct Person *person) {
printf("Name:%s\\n", person->name);
printf("Name:%d\\n", person->id);
printf("Name:%d\\n", person->age);
printf("Name:%d\\n", person->score);
}
void test() {
struct Person p = { "Obama", 1101, 23, 87 };
//printPersonByValue(p);
printPersonByPointe(&p);
printPersonByPointer(&p);
}
int main()
{
test();
return 0;
}
以上是关于C语言 const使用详解的主要内容,如果未能解决你的问题,请参考以下文章