status c语言_STM32 嵌入式C语言教程--第四课C语言中的存储空间与位域

1.存储空间--堆和栈的区别

一个由C/C++编译的程序占用的内存分为以下几个部分

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放。

4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放

5、程序代码区—存放函数体的二进制代码。

例子:

#include

int a = 0;//全局初始化区

char *p1;//全局未初始化区

void main()

{

  int b;栈

char s[] = "abc";//栈

char *p2;栈

char *p3 = "123456"; //1234560在常量区,p3在栈上。

static int c =0; //全局(静态)初始化区

p1 = (char *)malloc(10);

p2 = (char *)malloc(20);//分配得来得10和20字节的区域就在堆区。   

strcpy(p1, "123456"); //1234560放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

}

注意:i++和++i单独时,没有区别。当作为右值时,i++是先赋值后加,而++i是先加后赋值。

栈空间的分配问题

如:

void fun(int a,int b)

{

int c; //栈

int d; //栈

} //在栈区的存储顺序是c,d,a,b; //分配顺序就是:顺序局部变量、顺序参数

注意:for循环中应该遵循左闭右开的区间规则

2.C 位域

如果程序的结构中包含多个开关量,只有 TRUE/FALSE 变量,如下:

struct{

unsigned int widthValidated;

unsigned int heightValidated;} status;

这种结构需要 8 字节的内存空间,但在实际上,在每个变量中,我们只存储 0 或 1。在这种情况下,C 语言提供了一种更好的利用内存空间的方式。如果您在结构内使用这样的变量,您可以定义变量的宽度来告诉编译器,您将只使用这些字节。例如,上面的结构可以重写成:

struct{

unsigned int widthValidated : 1;

unsigned int heightValidated : 1;} status;

现在,上面的结构中,status 变量将占用 4 个字节的内存空间,但是只有 2 位被用来存储值。如果您用了 32 个变量,每一个变量宽度为 1 位,那么 status 结构将使用 4 个字节,但只要您再多用一个变量,如果使用了 33 个变量,那么它将分配内存的下一段来存储第 33 个变量,这个时候就开始使用 8 个字节。让我们看看下面的实例来理解这个概念:

实例

#include

#include /* 定义简单的结构 */

struct {

unsigned int widthValidated;

unsigned int heightValidated;

} status1; /* 定义位域结构 */

struct {

unsigned int widthValidated : 1;

unsigned int heightValidated : 1;

} status2;

int main( ) {

printf( "Memory size occupied by status1 : %d", sizeof(status1));

printf( "Memory size occupied by status2 : %d", sizeof(status2));

return 0;

}

当上面的代码被编译和执行时,它会产生下列结果:

Memory size occupied by status1 : 8Memory size occupied by status2 : 4

位域声明

在结构内声明位域的形式如下:

struct{

type [member_name] : width ;};

下面是有关位域中变量元素的描述:

元素

描述

type

只能为 int(整型),unsigned int(无符号整型),signed int(有符号整型) 三种类型,决定了如何解释位域的值。

member_name

位域的名称。

width

位域中位的数量。宽度必须小于或等于指定类型的位宽度。

带有预定义宽度的变量被称为位域。位域可以存储多于 1 位的数,例如,需要一个变量来存储从 0 到 7 的值,您可以定义一个宽度为 3 位的位域,如下:

struct{

unsigned int age : 3;} Age;

上面的结构定义指示 C 编译器,age 变量将只使用 3 位来存储这个值,如果您试图使用超过 3 位,则无法完成。让我们来看下面的实例:

实例

#include

#include

struct {

unsigned int age : 3;

} Age;

int main( )

{

Age.age = 4;

printf( "Sizeof( Age ) : %d", sizeof(Age) );

printf( "Age.age : %d", Age.age );

Age.age = 7;

printf( "Age.age : %d", Age.age );

Age.age = 8; // 二进制表示为 1000 有四位,超出

printf( "Age.age : %d", Age.age );

return 0;

}

当上面的代码被编译时,它会带有警告,当上面的代码被执行时,它会产生下列结果:

Sizeof( Age ) : 4

Age.age : 4

Age.age : 7

Age.age : 0

未完待续........

78d88f77d92b8f908db2f233a5731b8d.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值