局部变量,全局变量,static局部变量,static全局变量,extern全局变量, volatile, const

1.There are many topics in the C language that often confuse developers but the use of the static keyword seems to be one of the more common. One of the points of confusion is how static affects variables that are local and variables that are global. In each instance the static keyword has a different effect on where the data is stored and how it persists throughout the life of the program. There are three primary uses for the static keyword; local variable in a function, global variable in a module and a function in a module. In this post we will examine all three uses and how they affect not only where variables are stored but also the use of static can increase code quality.

A definition of static
In general, static is a storage class specifier that can be applied to any data type. While static has many definitions, the definition that best applies to all three uses is that static tells the compiler to make the variable or function limited in scope while allowing it to persist throughout the life of the program. This allows static to be used to encapsulate or hide variables from the rest of the program to prevent inadvertent access. The developer is then able to strictly control how variables are accessed within a module which is considered good programming practice.

The variable
When a variable is declared within a function without the use of static, the variable is considered to be an automatic variable. Automatic variables are created and stored on the stack (or within a CPU register) and destroyed when the function returns. If a developer wanted the variable within the function to retain its value between calls, the variable would be declared as static. In this case, the variable would no longer be stored on the stack but would instead be stored in the global memory space; however, even though the variable itself is stored in global space the compiler enforces a local scope on the variable causing it to only be visible within that function! Other functions within the module will be unaware that the variable exists. Not only will the variable retain its value throughout the life of the program, the static variable will also only be initialized the first time the function is called.

Defining a variable within the global scope of a module (outside of any function) implicitly declares the variable as extern. This causes the variable to be defined within the global memory space and for the linker to link other extern definitions to it. If the variable is only going to be used within the current module then it should be explicitly declared with static. Good programming practice indicates that a variable should be declared within the most local, applicable scope. Therefore, if the variable is only used within a single function then the more appropriate location to declare the variable may be within the function itself rather than the module scope. Static variables declared at the module level are initialized only once during the C copy down that occurs when the processor is being initialized.

Function within a module
Static can also be applied to a function within a module By default, functions are implicitly declared as extern. This means that if a function is defined within a c file and not prototyped within a header file, the compiler will still be able to link to the function (with perhaps a few warnings to the developer). In order to only make a function usable within a single module, the developer can place the static keyword before the function declaration. This will effectively hide the function from the external world and protect the use of that function and its variables.

Summary
The use of the static keyword has many uses. Its most effective use is to limit the scope of variables defined within a module or function. Through the use of static, variables and functions can be hidden from the external program, resulting in behavior that is similar to the use of private and public in more modern object oriented languages.

2.volatile means the variable may change, and the compiler must NOT assume it will stay the same value - this is applied at optimization. For example, if the value is a hardware status register memory-mapped into the address space, the value can change as the device operates. The volatile keyword was added because of C in embedded systems.

volatile uint8_t *stat_reg = 0x1234; // Create a pointer to the status reg, address 0x1234

uint8_t stat; // create a variable

stat = *stat_reg; // read the status register

while( *stat_reg & STAT_BUSY ) /WAIT/ ; // wait until the device is not busy - the status can change

3.The best definition a C developer can use for const is that it provides “read-only” access to the memory location that the symbol represents.Despite the peculiarities of const, it is still important to use it where appropriate and to protect symbols that should be read-only. One area of recommended heavy use is to protect parameters being passed to a function from being written to.

What is a developer to do to make sure that the pointer can’t be changed to point to anything but x? A confusing declaration such as the following can be used:

const int * const y = &x;

The above declaration is defining the symbol y to be a read-only pointer to an integer that is read-only. Confused yet?

const char * const foo; // constant pointer to constant data

const char * foo; // pointer to constant data

char * const foo; // constant pointer to data

In embedded systems, this lets you control where the values are stored - in RAM or FLASH (EEPROM). NOTE: every embedded system (MPU family) is slightly different!

int foo = 5; // copied from FLASH to RAM before main()

const int bar = 6; // store the 6 in FLASH and bar has a flash address.

the “int foo = 5;” case is interesting. The 5 is stored in FLASH, then on boot, copied to RAM at address 'foo". You can change the RAM value as you wish. BUT, on reboot, the FLASH copy is not changed so foo = 5 again.

4.extern最基本的用法是声明全局变量的。这里需要注意两点,一是“声明”,二是“全局变量”;我们先来分析这两个概念。
声明:声明和定义是有区别的。声明不等于定义,声明只是指出了变量的名字,并没有为其分配存储空间;定义指出变量名字同时为变量分配存储空间,定义包含了声明。例如:
extern int i; //声明变量i,但没分配存储空间,还不能使用。
int i; //定义了变量i,并分配了空间,可以使用。
注意:在程序中一个变量可以声明多次,但只能定义一次。

如果声明时有初始化式,也会被当做定义,例如:

extern int i = 5; //定义了变量5
后面的程序中若再出现extern int i = 5;或者int i;的语句,就会出错,因为变量只能定义一次。
全局变量:通俗讲,在函数内部定义的变量称为局部变量,它的作用域是从定义处知道函数结束;在函数外部定义的称为全局变量,它的作用域是从定义处直到文件结束。
注意:不管是全局变量还是局部变量,作用域都是从定义处开始的。例如:
int main()
{
cout<<i<<endl; //错误,会提示变量i未定义
int i=5; //变量i的作用域从这里开始
return 0;
}
理解了这两个概念,我们回过头看extern的作用。extern的作用是扩大全局变量的作用域,本来全局变量的作用域是从定义处开始直到文件结束,使用extern提前声明之后就变成从声明处开始,直到文件结束。那么,对于上面这个程序,作如下修改是不是就对了呢?
int main()
{
extern int i;
cout<<i<<endl;
int i=5;
return 0;
}
其实是错误的,因为前面说了,extern是用来声明全局变量的,而i是局部变量,如果将变量i在main函数外部定义就对了,如下:
int main()
{
extern int i; //声明之后,变量i的作用域从该处开始直到文件结束。
cout<<i<<endl;
return 0;
}
int i=5;
使用:在实际编程中,有时程序需要包含多个源文件,若这些文件有共同使用的变量,那么这个变量就遵循“一次定义,多次声明”的形式。即在一个文件中定义,其他文件使用时先进行声明。例如在文件file1中定义了一个变量:
file1:
int i =5;
若想在文件file2也使用这个变量,就可以如下:
file2
extern int i; //此时,编译器就知道i是一个已在其他地方定义的变量,会自动在本文件
//或其他文件中搜寻
i=6; //声明之后,就可在file2中对变量操作
注意:这种使用对于const变量是个例外。Const类型变量默认为当前文件的局部变量,即便在其他文件中声明了也不能使用。要想在其他文件中使用,定义const类型变量时必须在前面显式指出是extern。例如:
file1:
extern const int i=5;
此时就能在其他文件中声明并使用了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值