知识点锦集(二)

三.volatile在程序设计中的作用

  • 当读取一个变量时,为提高存取速度,编译器优化过程中有时会先把变量读取到一个寄存器内;当再取变量值时,直接从寄存器中取值;当变量值在本线程里改变时,会同时把变量的新值复制到该寄存器中,保持一致。(本线程中变量值改变,本线程中寄存器值改变)
  • 编译器优化时可能出现问题,如遇到多线程编程时,变量的值可能因为别的线程而改变了,而寄存器的值不会相应改变(其他线程中变量值改变,本线程中寄存器值不改变),从而造成应用程序读取的值和实际的变量值不一致。
  • volatile是一个类型修饰符,用来修饰被不同线程访问和修改的变量。被volatile类型定义的变量,系统每次使用时直接从内存中提取,不会利用cache中的原有数值,系统对volatile变量的处理不会做优化(volatile变量防止编译器优化)。
  • 运用:
    • 中断服务程序中修改的供其它程序检测的变量需要加volatile;
    • 多线程间被多个任务共享的变量需要加volatile;
    • 存储器映射的硬件寄存器(并行设备硬件寄存器)通常也要加volatile说明,因为每次对它的读写都可能有不同意义。
#include <iostream>
using namespace std;
int main(int argc,char* argv[]){
    int i=10;
    int a=i;
    cout<<a<<endl;
    // 下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道
    __asm {
        mov dword ptr [ebp-4], 20h
    }
    int b=i;
    cout<<b<<endl;
    getchar();
    return 0;
}
//在Debug版本模式运行程序:10,32;在Release版本模式运行程序(编译器对代码进行了优化):10,10
//将语句 int i=10;改为 volatile int i=10;在Release版本模式运行程序(volatile变量不优化):10,32

四. extern的作用

  • 对外部变量进行声明

    • (一)中对全局变量介绍时提及extern关键字。编译器一般采用文件编译的方式,在编译阶段,全局变量的可见域在本文件内部。一般会出现变量未定义或重定义错误。
    • extern作用:避免未定义和重定义错误,即只在一个文件中定义,其他文件不必再定义,使用即可
//未定义错误(编译阶段)
//编译器按文件方式编译,在编译阶段,只有本文件可见,即编译A.cpp时,并不知道B.cpp中定义了i。
//链接后文件中定义的全局变量的可见性扩展到整个程序
//A.cpp
int main(int argc,char* argv[]){
    cout<<i<<endl;
}

//B.cpp
int i=1;
int main(int argc,char* argv[]){
    cout<<i<<endl;
}
//重定义错误(链接阶段)
//编译器按文件方式编译,在编译阶段,只有本文件可见,A不知道B定义了i,B不知道A定义了i,编译通过。
//在链接阶段,各个文件“合并”,如果有相同的变量名时,就会出现重定义错误。
//A.cpp
int i=1;
int main(int argc,char* argv[]){
    cout<<i<<endl;
}

//B.cpp
int i=1;
int main(int argc,char* argv[]){
    cout<<i<<endl;
}
  • 在C++文件中调用C方式编译的变量或函数

    • C++调用被C编译器编译后的变量或函数,要加extern”C”
    • C++支持重载,因此C++编译后在库中的名字与C语言不同。如:声明一个函数float f(int a,char b),C++编译器会在库中将这个名字变为_f_int_char之类的东西以支持函数重载,但C语言编译器的内部名为_f。
//未定义错误:库中名字不相同
//A.cpp(C++)
extern int functionA();
extern int i;
int main(int argc,char* argv[])
 {
    functionA();
    cout<<i<<endl;
 }

//B.c(C)
int i=1;
int functionA(){}
//告诉编译器:变量i和functionA()函数是C编译器编译的
//A.cpp(C++)
extern "c"
{
    int functionA();
}
extern "C"
{
    int i;
}
int main(int argc,char* argv[])
 {
    functionA();
    cout<<i<<endl;
 }

//B.c(C)
int i=1;
int functionA(){}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值