C和指针学习笔记(一)——const常量

这个系列主要是我学习《C和指针》这本书的一些笔记,主要关于一些小的细节,目的是供自己学习和参考,详细地部分建议大家可以阅读一下《C和指针》这本书

一般情况

我们在编程的过程中,可能会遇到一种量,它的值不会被改变,或者说我们不希望在之后的代码执行过程中改变这个值。C 中通过引入 const 修饰符来表示这种量,即常量。如果在代码的执行过程中修改了常量,那么编译器就会报错(暂且算是一种对数据自动的保护机制吧)。
例如

const int N = 100; //定义一个值为100的常量

和指针联用

一般情况非常容易理解,但 const 修饰符也可以和指针联用来达到一些目的,会有以下三种情况

const int * point1;
int const * point2;
int * const point3;

前面两种情况即 point1point2 都表示指针指向的数据是只读的,但指针本身是可以更改的(改变其指向的地址)
最后一种情况,即 point3 表示指针本身是只读的(不可以改变其指向的地址),但指针指向的数据的值是可以改变的。
一个具体的栗子

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int b = 100;
    int c = 100;
    const int a = 100;
    const int * point1;
    int const * point2;
    int * const point3 = &b;
    *point3 = 101;
    point1 = &a;
    // *point1 = 101; // 报错
    b = 101;
    // point3 = &c; // 报错
    int * const point4 = &a; // 如果指向一个常量那么可以通过指针修改这个常量
    *point4 = 101;
    printf("%d\n", *point4); // 输出 101
    printf("%d\n", a); //输出 101
    return 0;
}


还可以用两个 const 表示一个指向常量的只读指针。

const int * const point5;
int const * const point6;

const和函数形参

const 通常用在函数形参中,如果形参是一个指针,为了防止在指针内部修改指针指向的数据,就可以用 const 来限制
例如C语言标准库,有很多参数的形参被const限制

size_t strlen ( const char * str );
int strcmp ( const char * str1, const char * str2 );
char * strcat ( char * destination, const char * source );
char * strcpy ( char * destination, const char * source );

自己也可以使用 const 来限制形参。
一个具体的栗子

#include <stdio.h>
#include <stdlib.h>

int output(const int * a)
{
    // *a = 101; // 报错
    printf("%d\n", *a); // 输出 100
}
int main()
{
    int b = 100;
    output(&b);
    return 0;
}


const 和 非const 类型转换

当一个指针变量 point1const 限制时,并且类似 const int *point1 这种形式,说明指针指向的数据不能被修改;如果将 point1 赋值给另外一个未被 const 修饰的指针变量 point2,就有可能发生危险。因为通过 point1 不能修改数据,而赋值后通过 point2 能够修改数据了,意义发生了转变,所以编译器不提倡这种行为,会给出错误或警告 (实测有的编译器并不会给出警报和错误,并且能正常运行,比如CB)。
也就是说,const int *int * 是不同的类型,不能将 const int * 类型的数据赋值给 int * 类型的变量。但反过来是可以的,编译器允许将 int * 类型的数据赋值给 const int * 类型的变量。
这种限制很容易理解,int * 指向的数据有读取和写入权限,而 const int * 指向的数据只有读取权限,降低数据的权限不会带来任何问题,但提升数据的权限就有可能发生危险。
C语言标准库中很多函数的参数都被 const 限制了,但我们在以前的编码过程中并没有注意这个问题,经常将非 const 类型的数据传递给 const 类型的形参,这样做从未引发任何副作用,原因就是上面讲到的,将非 const 类型转换为 const 类型是允许的。


下面是一个将 const 类型赋值给非 const 类型的例子:

#include <stdio.h>
#include <stdlib.h>

void output(int * point2)
{
    *point2 = 101;
    printf("%d\n", *point2); //输出101
}
int main()
{
    const int b = 100;
    const int * point1 = &b;
    output(point1);
    printf("%d\n", b); //输出101
    return 0;
}


参考博客
C语言const的用法详解,C语言常量定义详解

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值