c语言给变量附带属性,C语言变量和变量属性

数据类型

数据类型可以理解为固定内存大小的别名。

数据类型是创建变量的模子。

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;    //内存地址访问没问题。

A[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 具有什么属性?编译器如何处理这个变量?

表明这个对象体现常量语义,但同时可能被当前对象所在程序上下文意外的情况修改

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值