一、const的作用
- const修饰的量为一个常量即不能被修改的量
比如:
int a=1;指定义了一个变量a并初始化为1,但是后面可以对a的值进行修改。
但是 const int a = 1;指的是定义了一个常量1,后面并不能被修改。 - 被const修饰的变量是只读的
- 被const修饰的变量本质还是变量,具有内存空间,不是常量
二、const修饰变量
代码:
#include <stdio.h>
void test_const()
{
const int a = 10;
a = 20; //报错
}
int main()
{
test_const();
return 0;
}
可以看到编译器提示我们试图对一个const变量进行赋值
三、const修饰指针
修饰指针有几种情况,我们先看看以下代码:
const int* p; //p可变,p指向的内容不可变
int const* p; //p可变,p指向的内容不可变
int* const p; //p不可变,p指向的内容可变
const int* const p; //p和p指向的内容都不可变
可以看到const修饰谁,谁就是不可变的,比如const int* p,const修饰int类型,标明p指向的内容不可变,int* const p,const修饰p,标明p不可以变,也就是地址不可变。
我们看一个代码例子:
#include <stdio.h>
void test_const()
{
const int a = 10;
//a = 20; //报错, 对常量赋值
int b = 10;
int c = 20;
const int* p1; //p可变,p指向的内容不可变
int const* p2; //p可变,p指向的内容不可变
int* const p3; //p不可变,p指向的内容可变
const int* const p4; //p和p指向的内容都不可变
p1 = &b;
*p1 = 11; //报错,p指向的内容不可变
p2 = &b;
*p2 = 11; //报错,p指向的内容不可变
p3 = &b;
p3 = &c; //报错,p不可变
p4 = &b;
*p4 = 11; //报错,p指向的内容不可变
p4 = &c; //报错,p不可变
}
int main()
{
test_const();
return 0;
}
编译的时候可以看到:
编译器遵循被const修饰的指针规则
四、const修饰函数
- const修饰函数参数表示在函数体内不希望改变参数的值
- const修饰函数返回值表示返回值不可改变,,多用于返回 多用于返回指针的情形
我们来看一个例子:
const int* test_const2(const int n)
{
static int ret = 1;
ret++;
n += 1;
return &ret;
}
int main()
{
int i = 5;
int* p = NULL;
test_const();
p = test_const2(i);
*p = 10; //一般不这样做
return 0;
}
可以看到n += 1;试图对const修饰的变量进行修改,编译器会报错:
五、const和define的区别
-
作用地点不同:#define在编译预处理时起作用,const在编译和运行过程中起作用
-
作用方式不同:#define进行字符的替换,const进行数据检查
-
存储方式不同:#define有若干个备份,占了代码段空间,const只有一个备份,占了数据段空间
六、代码分析:
C语言部分:
#include <stdio.h>
void test_const()
{
const int a = 10;
//a = 20; //报错, 对常量赋值
int b = 10;
int c = 20;
const int* p1; //p可变,p指向的内容不可变
int const* p2; //p可变,p指向的内容不可变
int* const p3; //p不可变,p指向的内容可变
const int* const p4; //p和p指向的内容都不可变
p1 = &b;
*p1 = 11; //报错,p指向的内容不可变
p2 = &b;
*p2 = 11; //报错,p指向的内容不可变
p3 = &b;
p3 = &c; //报错,p不可变
p4 = &b;
*p4 = 11; //报错,p指向的内容不可变
p4 = &c; //报错,p不可变
}
const int* test_const2(const int n)
{
static int ret = 1;
ret++;
n += 1;
return &ret;
}
int main()
{
int i = 5;
int* p = NULL;
test_const();
p = test_const2(i);
*p = 10; //一般不这样做
return 0;
}
makefile部分:
CC = gcc
CFLAGS = -g -Wall -O
main:test.o
$(CC) $^ -o $@
%.o:%.c
$(CC) $(CFLAGS) -c $^
clean:
rm -rf test.o