标签:c语言变量和变量属性 static auto const register volatile
数据类型
数据类型可以理解为固定内存大小的别名。
数据类型是创建变量的模子。
1byte char
2byte short
4byte int
变量本质
变量是一段实际连续存储空间的别名。
程序中通过变量来申请并命名存储空间。
通过变量的名字可以使用存储空间。
---------------------------------------------------------------
C语言中的变量可以有自己的属性。
在定义变量的时候可以加上 "属性" 关键字。
"属性" 关键字指明变量的特有意义。
auto即C语言中局部变量的默认属性
编译器默认所有的局部变量都是auto,在栈分配空间。
static 关键字指明变量的 "静态" 属性。
static 关键同时具有 "作用域限定符" 的意义。
1、static修饰的局部变量存储在程序静态区
2、static的另一个意义是文件作用域标示符
--static修饰的全局变量作用域只是声明的文件中。
--static修饰的函数作用域只是声明的文件中。
register关键字指明将变量存储于寄存器中。
register只是请求寄存器变量,但不一定请求成功。
--register变量的必须是CPU寄存器可以接受的值。
--不能用&运算符获取register变量的地址。
全局变量在程序全局静态数据去分配空间,其生命周期=程序运行周期。
static修饰局部变量,静态数据区分配空间,不在栈上。
static声明变量只会被初始化一次。
-------------------------------
test1.c
extern int test2_g;
printf("%d",test2_g);
test2.c
int test2_g = 1;//全局变量
gcc test1.c test2.c
./a.out
输出没问题
------------------------------------------
如果
test2.c
static int test2_g;
段错误 undefined reference to ‘test2_g‘
static修饰的全局变量作用域只是声明的文件中
--------------------------------------------
test1.c
extern int test2_fun();
printf("%d",test2_fun());
test2.c
static int test2_g = 1;
int test2_fun()
{
return test2_g;
}
封装一个函数则可以
-----------------------------------
如果
test2.c
static int test2_g = 1;
static int test2_fun()
{
return test2_g;
}
}
段错误 undefined reference to ‘test2_fun‘
static修饰的函数作用域只是声明的文件中
-------------------------------------------
test1.c
extern int test2_ff();
printf("%d",test2_fun());
test2.c
static int test2_g = 1;
static int test2_fun()
{
return test2_g;
}
int test2_ff()
{
return test2_fun();
}
再封装一个函数返回一个静态函数就可以。
-------------------------------------------
验证static的作用域
--static修饰的全局变量作用域只是声明的文件中。
--static修饰的函数作用域只是声明的文件中。
----------------------------------------------------------------------
const 修饰变量
在C语言中const修饰的变量是只读的,其本质还是变量。
const修饰的变量会在内存占用空间。
本质上const只对编译器有用,在运行时无用。
原来const不是真的常量。
------------------------------------------------
const int cc = 1;
cc = 3;
error:
assignment of read-only variable ‘cc‘
------------------------------------------------
const int cc = 1;
int *p = (int *)&cc;
printf("%d\n",cc);
*p = 3;
printf("%d\n",cc);
则输出3,代表可以改变
-------------------------------------------------
const修饰数组
在C语言中const修饰的数组是只读的。
const修饰的数组空间不可被改变。
const int A[5] = {1,2,3,4,5};
int *p = (int *)A;
int i = 0;
for(i = 0; i<5;i++)
{
p[i] = 5-i; //oops!
}
C标准编译器- gcc g++编译器
----------------------------------------------
const修饰指针
const int *p; //p可变,p指向的内容不可变
int const* p; //p可变,p指向的内容不可变
int* const p; //p不可改变,p指向的内容可变
const int* const p; //p和p指向的内容都不可变
左数右指(const在*左右边,是指向内容不变还是指针本身不变)
const 在 * 左边 -> 指针指向的数据为常量
const 在 * 右边 -> 指针本身为常量
--------------------------------------------------------
const 修饰函数参数和返回值
const 修饰函数参数表示在函数体内不希望改变参数的值
const 修饰函数返回值表示返回值不可改变,多用于返回指针的情形
const int* func()
{
static int count = 0;
count++;
return &count;
}
---------------------------------------
深藏不漏的volatile
volatile 可理解为 "编译器警告指示字"
volatile 用于告诉编译器必须每次去内存中取变量值
volatile 主要修饰可能被多个线程访问的变量
volatile 也可以修饰可能被未知因数更改的变量
int obj = 10;
int a = 0;
int b = 0;
a = obj;
sleep(100);
b = obj;
编译器在编译的时候发现obj没有被当作左值。
obj直接替换10,把a和b都赋值为10.这是编译器的优化。
如果在100ms间 产生硬件中断 obj = 100;
-------------------------------------------------------------
const 和 volatile 是否可以同时修饰一个变量
const valatile int i = 0;这个时候 i 具有什么属性?编译器如何处理这个变量?
表明这个对象体现常量语义,但同时可能被当前对象所在程序上下文意外的情况修改
本文出自 “8342724” 博客,转载请与作者联系!
标签:c语言变量和变量属性 static auto const register volatile
原文地址:http://8352724.blog.51cto.com/8342724/1828976