博客
关于我
c学习-37 关键字const学习
阅读量:509 次
发布时间:2019-03-07

本文共 4675 字,大约阅读时间需要 15 分钟。

const修饰与常见用法解析

const关键字在C语言中具有重要作用,主要用于限定变量、数组、函数参数和返回值等,使其成为只读数据,防止意外修改。以下将从多个维度解析const的用法及其注意事项。

1. const修饰普通类型的变量

const修饰的普通变量不能被修改,即使通过指针操作也无法改变其值。例如:

void test_23_01() {    const int a23_01 = 1;  // 只读变量,不能被修改    int b23_01 = 1;        // 普通变量,可被修改    // a23_01 = 2; // 报错:向只读变量‘a23_01’赋值    b23_01 = 2;    printf("a23_01=%d\n", a23_01);    printf("b23_01=%d\n", b23_01);}

输出结果:

a23_01=1b23_01=2

2. const修饰普通类型的变量加上volatile关键字

当const与volatile结合使用时,变量仍然不能被修改,但volatile的作用是强制让编译器在每次访问时重新读取内存,通常用于多线程环境中。例如:

void test_23_02() {    const int a23_02 = 1;  // 只读常量,不能被修改    volatile const int b23_02 = 1;  // 只读常量,且强制重新读取内存    int *p1 = (int*)(&a23_02);  // 指针指向常量,无法修改    *p1 = 2;  // 修改失败,输出不变    int *p2 = (int*)(&b23_02);  // 指针指向常量,且可强制修改    *p2 = 2;  // 成功修改    printf("a23_02=%d\n", a23_02);    printf("b23_02=%d\n", b23_02);}

输出结果:

a23_02=1b23_02=2

3. const修饰数组

当const修饰数组时,数组整体不能被修改,但数组中的元素仍然可以通过指针访问。例如:

void test_23_03() {    const int a23[10] = {1, 2, 3, 4};  // 只读数组,不能修改    int b23[10] = {1, 2, 3, 4};       // 普通数组,可被修改    printf("a23[0]=%d\n", a23[0]);      // 输出数组元素    printf("b23[0]=%d\n", b23[0]);      // 输出数组元素    // a23[0] = 5; // 报错:向只读位置‘a23[0]’赋值    b23[0] = 5;                       // 成功修改    printf("a23[0]=%d\n", a23[0]);      // 输出数组元素    printf("b23[0]=%d\n", b23[0]);      // 输出数组元素}

输出结果:

a23[0]=1b23[0]=1a23[0]=1b23[0]=5

4. 常量指针与指针常量

  • 常量指针:指针本身是常量,指向的数据不能被修改。例如:
void test_23_04() {    int a1 = 4;    int b1 = 4;    const int* p1 = &a1;   // 常量指针,指向的数据不能被修改    int* p2 = &b1;        // 非常量指针,指向的数据可以被修改    printf("*p1=%d\n", *p1);  // 输出指针值    printf("*p2=%d\n", *p2);  // 输出指针值    // *p1 = 5; // 报错:常量指针不能修改指向的数据    *p2 = 5;               // 成功修改指向的数据    printf("*p1=%d\n", *p1);  // 输出指针值    printf("*p2=%d\n", *p2);  // 输出指针值    printf("a1=%d\n", a1);   // 输出数据    printf("b1=%d\n", b1);   // 输出数据}

输出结果:

*p1=4*p2=4a1=4b1=4*p1=4*p2=5a1=4b1=5
  • 指针常量:指针本身是常量,且指向的数据可以被修改。例如:
void test_23_05() {    int a1 = 4;    int b1 = 4;    int* const p1 = &a1;  // 指针常量,指针不能改变,指向的数据可以被修改    int* p2 = &b1;        // 非常量指针,指针可以改变,指向的数据可以被修改    printf("*p1=%d\n", *p1);  // 输出指针值    printf("*p2=%d\n", *p2);  // 输出指针值    int a2 = 5;    int b2 = 5;    // p1 = &a2; // 报错:指针常量不能改变指向的对象    p2 = &b2;        // 非常量指针可以改变指向的对象    printf("*p1=%d\n", *p1);  // 输出指针值    printf("*p2=%d\n", *p2);  // 输出指针值}

输出结果:

*p1=4*p2=4*p1=4*p2=5

5. const参数传递和函数返回值

  • const参数传递:函数参数如果被修饰为const,不能被修改。例如:
void test_23_06_01(const int x) {    // x++; // 报错:向只读形参‘x’自增    printf("x=%d\n", x);}void test_23_06_02(int y) {    y++;                       // 非常量参数可以被修改    printf("y=%d\n", y);}void test_23_06() {    int a1 = 4;    test_23_06_01(a1);        // const参数不能被修改    test_23_06_02(a1);        // 非常量参数可以被修改}

输出结果:

x=4y=5
  • const修饰函数返回值:函数返回值如果被修饰为const,返回的是常量,不能被修改。例如:
const int test_23_07_01() {    return 3;                   // 返回常量,不能被修改}int test_23_07_02() {    return 3;                   // 返回非常量,能被修改}void test_23_07() {    int a1 = test_23_07_01();  // 接收常量返回值    int b1 = test_23_07_02();  // 接收非常量返回值    printf("a1=%d\n", a1);     // 输出常量返回值    printf("b1=%d\n", b1);     // 输出非常量返回值    a1 = 5;                    // 修改非常量变量    b1 = 5;                    // 修改非常量变量    printf("a1=%d\n", a1);     // 输出常量返回值    printf("b1=%d\n", b1);     // 输出常量返回值}

输出结果:

a1=3b1=3a1=5b1=5
  • const修饰函数返回值为指针:当函数返回的是指针时,需要使用const修饰返回类型。例如:
const char* test_23_08_01() {    char* a = new char[10];    strcpy(a, "hello");    return a;}char* test_23_08_02() {    char* a = new char[10];    strcpy(a, "hello");    return a;}void test_23_08() {    // char* p1 = test_23_08_01(); // 报错:返回类型为const char*    const char* p1 = test_23_08_01();  // 正确接收返回值    char* p2 = test_23_08_02();      // 正确接收返回值    printf("p1=%s\n", p1);          // 输出返回值    printf("p2=%s\n", p2);          // 输出返回值}

输出结果:

p1=hellop2=hello

6. const修饰函数体

一个函数名字后有const,这个函数必定是成员函数,也就是说普通函数后面不能有const修饰。例如:

// 非成员函数不能使用const修饰void test_23_09_01() const {  // 报错:非成员函数‘void test_23_09_01()’不能拥有 cv 限定符    // 不能使用const修饰普通函数}void test_23_09_02() {    printf("this is test_23_09_02()\n");}void test_23_09() {    // test_23_09_01();  // 成员函数不能被调用的示例    test_23_09_02();}

注意:const修饰成员函数体时,函数内的成员变量和其他对象不能被修改。

7. const修饰类成员函数体

在类中,const修饰的成员函数体内不能修改对象的数据成员。例如:

class A23_10 {private:    int a1 = 1;public:    void fun1() const {  // 成员函数被const修饰        // a1++; // 报错:不能修改对象的数据成员        printf("a1=%d\n", a1);    }    void fun2() {  // 非const修饰,允许修改对象的数据成员        a1++;        printf("a1=%d\n", a1);    }};void test_23_10() {    A23_10 a23_10;    a23_10.fun1();       // 调用const修饰的成员函数    a23_10.fun2();       // 调用非const修饰的成员函数}

输出结果:

a1=1a1=2

总结

通过以上实例可以看出,const修饰的作用在于限定数据或指针的读取权限,防止意外修改,提升程序的健壮性。在实际编程中,合理使用const可以显著减少错误并提高代码质量。

转载地址:http://lomjz.baihongyu.com/

你可能感兴趣的文章
nullnullHuge Pages
查看>>
Numpy如何使用np.umprod重写range函数中i的python
查看>>
oauth2-shiro 添加 redis 实现版本
查看>>
OAuth2.0_JWT令牌-生成令牌和校验令牌_Spring Security OAuth2.0认证授权---springcloud工作笔记148
查看>>
OAuth2.0_JWT令牌介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记147
查看>>
OAuth2.0_介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记137
查看>>
OAuth2.0_完善环境配置_把资源微服务客户端信息_授权码存入到数据库_Spring Security OAuth2.0认证授权---springcloud工作笔记149
查看>>
OAuth2.0_授权服务配置_Spring Security OAuth2.0认证授权---springcloud工作笔记140
查看>>
OAuth2.0_授权服务配置_密码模式及其他模式_Spring Security OAuth2.0认证授权---springcloud工作笔记145
查看>>
OAuth2.0_授权服务配置_资源服务测试_Spring Security OAuth2.0认证授权---springcloud工作笔记146
查看>>
OAuth2.0_环境搭建_Spring Security OAuth2.0认证授权---springcloud工作笔记139
查看>>
OA系统多少钱?OA办公系统中的价格选型
查看>>
object detection错误之Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
查看>>
Object Oriented Programming in JavaScript
查看>>
OBJECTIVE C (XCODE) 绘图功能简介(转载)
查看>>
Objective-C——判断对象等同性
查看>>
Objective-C之成魔之路【7-类、对象和方法】
查看>>
Objective-C享元模式(Flyweight)
查看>>
Objective-C以递归的方式实现二叉搜索树算法(附完整源码)
查看>>
Objective-C实现1000 位斐波那契数算法(附完整源码)
查看>>