5. const和volatile分析

const----修饰变量

标准C对常量的处理:const(修饰的)不是真的常量,他只是告诉编译器这是个只读的变量,即在:程序里不能直接将他作为左值(不能直接对一个const修饰的变量直接赋值)。但是本质还是变量,仍然会占用内存空间。

我们可以通过取地址操作符来得到他的地址,通过地址改变他内存里的值。const只对编译器有用,在运行时无用。

int main(){
const int a=1;
int *p = (int*)&a;//作为右值,取地址访问。在程序运行的时候,此时会到内存里面,找到a这块内存地址,让p指向这块地址。int *定义指针p
//只要出现一次&,就按这种方式,到内存里去取值,对吗?
printf("%d",a);//到内存里去取a的值,没被改,还是1
*p = 3;//通过指针,更改了a的值
printf("%d",a);
return 0;
}
result: 1, 3

const----修饰数组----修饰的数组是只读的(不能出现在赋值符号的左边)

const修饰的数组空间不可被改变----不是绝对的,有些编译器可以通过指针改变(编译器做的不规范)----记住不可以改变

const----修饰指针

口诀:左数右指

当const出现在*左侧的时候,指针指向的数据为常量

当const出现在*右侧的时候,指针本身为常量

指针补充:

int a = 3;   // 声明一个整数变量 a,并初始化为值 3
int *p;      // 声明一个整型指针 p
p = &a;      // 将变量 a 的地址赋值给指针 p
*p = a;      // 通过指针 p 修改变量 a 的值,*p是解指针

例子:

int main()

{  

    int i = 1;

    const int* p = &i;//将变量 i 的地址赋值给了 p,使得 p 指向 i

    *p = 3;    //const限定了p 无法修改指向的整数的值;*p是解指针

    printf("%d\n", i);

    return 0;

}

int main()

{  

    int i = 1;

    int const* p = &i;  //与const int*没有区别

    *p =3;

    printf("%d\n", *p);

    return 0;

}

int main()

{  

    int i = 1;

    int* const p = &i;  

    *p =3;//指针指向的内容可以改变

    p = NULL; //指针不可以改变

    printf("%d\n", *p);

    return 0;

}

int main()

{  

    int i = 1;

    const int* const p = &i;   

    *p =3; //指针指向的内容不可以改变

    p = NULL; //指针不可以改变

    printf("%d\n", *p);

    return 0;

}

const----修饰函数参数和返回值

  • 修饰函数参数  表示在函数体内不希望改变参数的值
  • 修饰函数返回值  表示函数返回值不可以被改变,多用于返回指针的情形
const int* func()//函数返回值类型是const int*,是一个指向常量整数的指针
{
    static int count = 3;
    count++;
    return &count;//返回的是 count 变量的地址,这与返回类型是指针类型相符合
}
//注意:当函数返回值类型中有const时,应该考虑是指针不变,还是指向的内容不变
int main()
{  
    int i = 1;
    //const int* p = &i;//指针可以两次指向吗? 可以更换指向
    const int* p = func();  //本质是将 func() 函数返回的指向常量整数的指针赋值给变量 p,与上边作类比
     int* p = func();  //函数的发返回值是const类型的指针,数据是不可以改变的,不能用int*接收
    printf("%d\n",*p);
}

volatile----防止编译器自我为是的优化

  • volatile可理解为“编译器警告指示字”
  • volatile用于告诉编译器必须每次去内存中取变量值
  • volatile主要修饰可能被多个线程访问的变量
  • volatile也可以修饰可能被未知因数更改的变量
例如:
若此时,在sleep(100)时发生一个中断,将obj改为20,那么编译器还错误的将obj当成10。
解决方法:在最开始
volatile int obj = 10;//volatile用于告诉编译器必须每次去内存中取变量值

* const和volatile是否可以同时修饰一个变量?

可以,const他只是告诉编译器这是个只读的变量,volatile用于告诉编译器必须每次去内存中取变量值,两者不冲突。使用 const volatile 修饰的变量表示它是一个同时具有常量性和易变性的变量。

* const volatile int i = 0; 这个时候i具有什么属性?编译器如何处理这个变量?

变量 i 是一个既具有常量性又具有易变性的整数。
const:编译器会确保 i 在初始化后不会被修改。任何尝试修改 i 的行为都会在编译时被捕获并报错。
volatile:编译器会禁止对 i 进行优化,保证每次访问都能获取到最新的值。这意味着,即使看起来代码中没有对 i 的修改,编译器也不会将其缓存,而是每次都会从内存中读取最新的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值