C/C++语法知识精华整理(2)-栈与堆、内存四大区域、 全局变量、线程技术、位字段、函数返回值副本机制等

1.栈与堆的区别



栈的内存区域只有默认1M

项目设置--连接器,系统,设置默认栈的大小


2.内存四大区域


常量字符串在代码区

char *p = "tasklist";//赋值地址

//p是一个栈上的指针变量,存储了代码区常量字符串的地址

printf("%d,%d", sizeof(p), sizeof("tasklist"));

printf("%p", p);

printf("\n%p", &p);

*p = 'x';//代码区只能读,不可以写


3.全局变量

全局变量与函数一样,有声明与定义,声明可以多个,定义只有一个。

局部变量没有声明与定义的差别

全局变量就有声明与定义的差别,int a没有赋值,视为声明,赋值视作定义

 

全局变量与函数一样,声明可以多个,定义仅有一个

全局变量如果有声明,没有定义,会自动初始化一个为0

 

头文件尽量存放声明,存放定义包含多次,就会触发重定义

 

全局变量可以跨文件使用

默认的函数都是全局函数

同一个工程,不同源文件,不能出现两个同名的全局变量定义

4.静态区,堆区,栈区对比

作用域非常大,生存期与程序共存放,内存不会被回收

静态区与程序共存亡,内存不会被回收再次利用,除非程序消亡

栈区,块语句执行完成,消亡

堆区,自己free也会消亡,

Staitc 限定全局变量,函数作用域局限在当前文件。默认全局变量,函数,都是一个工程所有原码共享。

Static,局部变量,每次仅仅初始化一次。用于软件工程避免全局变量被意外修改。

static   const  int  num = 100;//限制只能被当前的源文件所引用

静态全局变量,const意味着是常量

extern声明一个外部变量,没有定义报错

    int num1 = 10;

int num2 = 20;//栈区

 

void *p1 = malloc(1000);//p1在栈区,存储了堆区的地址

void *p2 = malloc(1000);

 

printf("%p,%p", &num1, &num2);

printf("\n%p,%p", &p1, &p2);//在堆区,存储了指针变量的地址 

printf("\n%p,%p", p1, p2);//在栈区,存储了堆区的地址


5.堆栈增长方向

栈顶由高地址到低地址方向增长 

存储非静态变量、函数参数、返回地址


6.线程技术

 

#include <windows.h>

#include <process.h> //进程的头文件

void  runmsg(void *p)

{

MessageBoxA(0, "hello china", "hello world", 0);

}

void  main()

{

_beginthread(runmsg, 0, NULL);//开启一个线程

_beginthread(runmsg, 0, NULL);

_beginthread(runmsg, 0, NULL);

getchar();

}


7.位字段的概念与用途

结构体加上整数,限定长度,节约内存

嵌入式开发必须节约内存,需要位域

struct MyStruct

{

unsigned char num:1;//限定只有一位,限定内存,节约内存

unsigned char data : 1;

};

位域,不能越界,溢出

 

位字段输出二进制数据

位字段可以把二进制数据处理为char进行简洁的处理

typedef struct 

{

unsigned char ch1:1;

unsigned char ch2:1;

unsigned char ch3:1;

unsigned char ch4:1;

unsigned char ch5:1;

unsigned char ch6:1;

unsigned char ch7:1;

unsigned char ch8:1;

}bit;

void main()

{

printf("%d", sizeof(bit));//位字段的方式输出整数的二进制码

int num;

scanf("%d", &num);

bit *p = #

for (int i = 3; i >= 0;i--)

{

printf("%d%d%d%d %d%d%d%d  ",

p[i].ch8,

p[i].ch7,

p[i].ch6,

p[i].ch5,

p[i].ch4,

p[i].ch3,

p[i].ch2,

p[i].ch1

);

}

system("pause");

}

字节分布:变量在内存,低字节低位,倒序排列


8.寄存器变量,寄存器变量不可以取地址

VC++会自动优化,不需要增加寄存器标识

GCC会实现寄存器优化


9.函数返回值副本机制

作为函数,不可以返回指向栈上的指针

返回值有副本机制,一般在寄存器

int  jia(int a, int b)

{

int c = a + b;//栈上,

printf("\n%p", &c);

return c;//return有副本机制

}

void main()

{

int res = jia(12, 19);

//int *p = &(jia(1, 2));

//返回值有副本机制,一般在寄存器,

printf("\n\n\n");

printf("%d", res);

}

 

9.函数返回地址特点

int * add(int a, int b)

{

int c = a + b;

return &c;

}

//作为函数,不可以返回指向栈上的指针

int * addm(int a, int b)

{

int *p = (int *)malloc(4);

*p = a + b;

return p;

}

//作为函数,但是可以返回指向堆上的指针

void mainA()

{

int *p = addm(3, 9);

//printf("\n\n");

printf("%d", *p);

}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值