c语⾔volatile结构体,volatile⼀般⽤来修饰结构体中的成员变量
吗?
保留字肯定就是关键字撒,
(1)auto
这个这个关键字⽤于声明变量的⽣存期为⾃动,即将不在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,⽽在函数中定义的变量视为局部变量。这个关键字不怎么多写,因为所有的变量默认就是auto的。
(2)register
这个关键字命令编译器尽可能的将变量存在CPU内部寄存器中⽽不是通过内存寻址访问以提⾼效率。
(3)static
常见的两种⽤途:
1>统计函数被调⽤的次数;
2>减少局部数组建⽴和赋值的开销.变量的建⽴和赋值是需要⼀定的处理器开销的,特别是数组等含有较多元素的存储类型。在⼀些含有较多的变量并且被经常调⽤的函数中,可以将⼀些数组声明为static类型,以减少建⽴或者初始化这些变量的开销.
详细说明:
1>、变量会被放在程序的全局存储区中,这样可以在下⼀次调⽤的时候还可以保持原来的赋值。这⼀点是它与堆栈变量和堆变量的区别。
2>、变量⽤static告知编译器,⾃⼰仅仅在变量的作⽤范围内可见。这⼀点是它与全局变量的区别。
3>当static⽤来修饰全局变量时,它就改变了全局变量的作⽤域,使其不能被别的程序extern,限制在了当前⽂件⾥,但是没有改变其存放位置,还是在全局静态储存区。
使⽤注意:
1>若全局变量仅在单个C⽂件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
2>若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
3>设计和使⽤访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重⼊问题(只要输⼊数据相同就应产⽣相同的输出)
(4)const
被const修饰的东西都受到强制保护,可以预防意外的变动,能提⾼程序的健壮性。它可以修饰函数的参数、返回值,甚⾄函数的定义体。
作⽤:
1>修饰输⼊参数
a.对于⾮内部数据类型的输⼊参数,应该将“值传递”的⽅式改为“const引⽤传递”,⽬的是提⾼效率。例如将void Func(A a) 改为void Func(const A &a)。
b.对于内部数据类型的输⼊参数,不要将“值传递”的⽅式改为“const引⽤传递”。否则既达不到提⾼效率的⽬的,⼜降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。
2>⽤const修饰函数的返回值
a.如果给以“指针传递”⽅式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。
如对于: const char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();//cannot convert from 'const char *' to 'char *';
正确的⽤法是:
const char *str = GetString();
b.如果函数返回值采⽤“值传递⽅式”,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。 如不要把函数int GetInt(void) 写成const int GetInt(void)。
3>const成员函数的声明中,const关键字只能放在函数声明的尾部,表⽰该类成员不修改对象.
说明:
const type m; //修饰m为不可改变
⽰例:
typedef char * pStr; //新的类型pStr;
char string[4] = "abc";
const char *p1 = string;
p1++; //正确,上边修饰的是*p1,p1可变
const pStr p2 = string;
p2++; //错误,上边修饰的是p2,p2不可变,*p2可变
同理,const修饰指针时⽤此原则判断就不会混淆了。
const int *value; //*value不可变,value可变
int* const value; //value不可变,*value可变
const (int *) value; //(int *)是⼀种type,value不可变,*value可变
/
/逻辑上这样理解,编译不能通过,需要tydef int* NewType;
const int* const value;//*value,value都不可变
(5)volatile
表明某个变量的值可能在外部被改变,优化器在⽤到这个变量时必须每次都⼩⼼地重新读取这个变量的值,⽽不是使⽤保存在寄存器⾥的备份。它可以适⽤于基础类型如:int,也适⽤于C的结构和C++的类。当对结构或者类对象使⽤volatile修饰的时候,结构或者类的所有成员都会被视为volatile.
该关键字在多线程环境下经常使⽤,因为在编写多线程的程序时,同⼀个变量可能被多个线程修改,⽽程序通过该变量同步各个线程。
简单⽰例:
DWORD __stdcall threadFunc(LPVOID signal)
{
int* intSignal=reinterpret_cast(signal);
*intSignal=2;
while(*intSignal!=1)
sleep(1000);
return 0;
}
该线程启动时将intSignal 置为2,然后循环等待直到intSignal 为1 时退出。显然intSignal的值必须在外部被改变,否则该线程不会退出。但是实际运⾏的时候该线程却不会退出,即使在外部将它的值改为1,看⼀下对应的伪汇编代码就明⽩了:
mov ax,signal
label:
if(ax!=1)
goto label
对于C编译器来说,它并不知道这个值会被其他线程修改。⾃然就把它cache在寄存器⾥⾯。C 编译器是没有线程概念的,这时候就需要⽤到volatile。volatile 的本意是指:这个值可能会在当前线程外部被改变。也就是说,我们要在threadFunc中的intSignal前⾯加上volatile关键字,这时候,编译器知道该变量的值会在外部改变,因此每次访问该变量时会重新读取,所作的循环变为如下⾯伪码所⽰:
label:
mov ax,signal
if(ax!=1)
goto label
注意:⼀个参数既可以是const同时是volatile,是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
c++string类型(6)extern
extern 意为“外来的”···它的作⽤在于告诉编译器:有这个变量,它可能不存在当前的⽂件中,但它肯定要存在于⼯程中的某⼀个源⽂件中或者⼀个Dll的输出中。
参考
另外:C语⾔中的关键字
auto :声明⾃动变量 ⼀般不使⽤
double :声明双精度变量或函数
int: 声明整型变量或函数
struct:声明结构体变量或函数
break:跳出当前循环
else :条件语句否定分⽀(与 if 连⽤)
long :声明长整型变量或函数
switch :⽤于开关语句
case:开关语句分⽀
enum :声明枚举类型
register:声明积存器变量
typedef:⽤以给数据类型取别名(当然还有其他作⽤)
char :声明字符型变量或函数
extern:声明变量是在其他⽂件正声明(也可以看做是引⽤变量)
return :⼦程序返回语句(可以带参数,也看不带参数)
union:声明联合数据类型
const :声明只读变量
float:声明浮点型变量或函数
short :声明短整型变量或函数
unsigned:声明⽆符号类型变量或函数
continue:结束当前循环,开始下⼀轮循环
for:⼀种循环语句(可意会不可⾔传)
signed:⽣命有符号类型变量或函数
void :声明函数⽆返回值或⽆参数,声明⽆类型指针(基本上就这三个作⽤) default:开关语句中的“其他”分⽀
goto:⽆条件跳转语句
sizeof:计算数据类型长度
volatile:说明变量在程序执⾏中可被隐含地改变
do :循环语句的循环体
while :循环语句的循环条件
static :声明静态变量
if:条件语句
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论