C语言 数据类型、变量、内存四区本质分析

1.1.1数据类型本质分析

数据类型概念
  • “类型”是对数据的抽象
  •  类型相同的数据有相同的表示形式、存储格式以及相关的操作
  •  程序中使用的所有数据都必定属于某一种数据类型
数据类型的本质思考
  •  思考数据类型和内存有关系吗?
  •  C/C++为什么会引入数据类型?
数据类型的本质
  • 数据类型可理解为创建变量的模具(模子);是固定内存大小的别名
  • 数据类型的作用:编译器预算对象(变量)分配的内存空间大小
  • 程序举例,如何求数据类型的大小sizeof(int *)
  •  请问:数据类型可以有别名吗?数据类型可以自定义吗?
数据类型大小

int main()

{

int a = 10;

int b[10] ;

printf("int a:%d \n", sizeof(a));

printf("int a:%d \n", sizeof(int *));

printf("int b:%d \n", sizeof(b));

printf("int b:%d \n", sizeof(b[0]));

printf("int b:%d \n", sizeof(*b));

printf("hello.....\n");

getchar();

return 0;

}

sizeof是操作符,不是函数;sizeof测量的实体大小为编译期间就已确定

数据类型别名
  • 数据类型可以理解为固定大小内存块的别名,请问数据类型可以起别名吗?

int main()

{

//Teacher t1;

printf("Teacher:%d \n", sizeof(Teacher));

printf("u32:%d \n", sizeof(u32));

printf("u8:%d \n", sizeof(u8));

printf("hello.....\n");

getchar();

return 0;

}

数据类型的封装
  • 1、void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。
  • 2、用法1:数据类型的封装

     int InitHardEnv(void **handle);

     典型的如内存操作函数memcpy和memset的函数原型分别为

void * memcpy(void *dest, const void *src, size_t len);

void * memset ( void * buffer, int c, size_t num );  

  • 3、用法2:  void修饰函数返回值和参数,仅表示无。

       如果函数没有返回值,那么应该将其声明为void型

       如果函数没有参数,应该声明其参数为void

       int function(void)

       {return 1;}

  • 4、void指针的意义

      C语言规定只有相同类型的指针才可以相互赋值

      void*指针作为左值用于“接收”任意类型的指针

      void*指针作为右值赋值给其它指针时需要强制类型转换

      int *p1 = NULL;

      char *p2 = (char *)malloc(sizoeof(char)*20);

  • 5、不存在void类型的变量

      C语言没有定义void究竟是多大内存的别名

  • 6、扩展阅读《void类型详解.doc》
数据类型总结与扩展
  • 1、数据类型本质是固定内存大小的别名;是个模具,c语言规定:通过数据类型定义变量。
  • 2、数据类型大小计算(sizeof)
  • 3、可以给已存在的数据类型起别名typedef
  • 4、数据类型封装概念(void 万能类型)

思考1:

C一维数组、二维数组有数据类型吗?int array[10]。

若有,数组类型又如何表达?又如定义?

若没有,也请说明原因。

抛砖:数组类型,压死初学者的三座大山

1、数组类型

2、数组指针

3、数组类型和数组指针的关系

思考2:

C语言中,函数是可以看做一种数据类型吗?

a)若是,请说明原因

并进一步思考:函数这种数据类型,能再重定义吗?

b)若不是,也请说明原因。

抛砖:

1.1.2变量本质分析

变量概念
  • 概念:既能读又能写的内存对象,称为变量;若一旦初始化后不能修改的对象则称为常量。
  •  变量定义形式:     类型  标识符, 标识符, … , 标识符 ;
  • 例如:

int   x ;

int   wordCut ,  Radius ,  Height  ;  

double   FlightTime ,  Mileage ,  Speed  ;

变量本质 

1、程序通过变量来申请和命名内存空间 int a = 0

2、通过变量名访问内存空间

(一段连续)内存空间的别名(是一个门牌号)

  1. 修改变量有几种方法?

1、直接

2、间接。内存有地址编号,拿到地址编号也可以修改内存;于是横空出世了!(编程案例)

3、内存空间可以再取给别名吗?

4、数据类型和变量的关系

  • 通过数据类型定义变量

5、总结及思考题

1 对内存,可读可写;2通过变量往内存读写数据;3 不是向变量读写数据,而是向变量所代表的内存空间中写数据。问:变量跑哪去了?

思考1:变量三要素(名称、大小、作用域),变量的生命周期? 

思考2:C++编译器是如何管理函数1,函数2变量之间的关系的?

====》引出两个重要话题:

内存四区模型

函数调用模型

重要实验:

int  main333()

{

//

//2种方法,通过变量直接操作内存

// 通过内存编号操作内存

int i = 0;

printf("&i:%d\n", &i);

*((int *)(1245024)) = 10;

printf("i:%d", i);

printf("hello....\n");

getchar();

return 0;

}

1.1.3程序的内存四区模型

内存四区的建立流程

流程说明

1、操作系统把物理硬盘代码load到内存

2、操作系统把c代码分成四个区

3、操作系统找到main函数入口执行

各区元素分析

1.4函数调用模型

1.4.1基本原理

1.4.2内存四区模型和函数调用模型变量传递分析

1、一个主程序有n函数组成,c++编译器会建立有几个堆区?有几个栈区?

2、函数嵌套调用时,实参地址传给形参后,C++编译器如何管理变量的生命周期?

分析:函数A,调用函数B,通过参数传递的变量(内存空间能用吗?)

1.4.3提示学好C语言的关键

1.4.4如何建立正确的程序运行内存布局图

  • 内存四区模型&函数调用模型
  • 函数内元素
    • 深入理解数据类型和变量“内存”属性
    • 一级指针内存布局图(int *,char*)
    • 二级指针内存布局图(int ** char **)
  • 函数间
    • 主调函数分配内存,还是被调用函数分配内存
    • 主调函数如何使用被调用函数分配的内存(技术关键点:指针做函数参数)

======》学习指针的技术路线图

1.5内存四区强化训练

01全局区训练

  • char *p1= “abcdefg”;

02 堆栈区生命周期训练

  • Char p1[]= “abcdefg”;
  • 返回基本类型
  • 返回非基本类型

03堆栈属性训练

  • 测试heap生长方向
  • 测试stack生长方向
    • Heap、stack生长方向和内存存放方向是两个不同概念
    • 野指针
    • Malloc得到指针释放问题测试
      • free(p)
      • free(p+1),深入理解 

1.6作业强化

训练1划出内存四区

void main26()

{

char buf[100];

//byte b1 = new byte[100];

int a = 10; //分配4个字节的内存 栈区也叫临时区

int *p;//分配4个字节的内存

p = &a; //cpu执行的代码,放在代码区

*p = 20; //

{

char *p = NULL; //分配4个字节的内存 栈区也叫临时区

p = (char *)malloc(100); //内存泄露概念

if (p != NULL)

{

free(p);

}

}

system("pause");

}

全局区代码测试

char * getstring1()

{

char *p1 = "abcde";

return p1;

}

char * getstring2()

{

char *p2 = "abcde";

return p2;

}

void main()

{

int i= 0;

//指针指向谁就把谁的地址赋给指针变量。

char *p1 = getstring1();

char *p2 = getstring2();

char *******    p3 = NULL; //p3 是个变量

//指针变量和它所执行的内存空间变量是两个不同的概念

strcmp(p1, p2);

system("pause");

}

训练2 划出内存四区

void main01()

{

char buf[100];

//byte b1 = new byte[100];

int a = 10; //分配4个字节的内存 栈区也叫临时区

int *p;//分配4个字节的内存

p = &a; //cpu执行的代码,放在代码区

*p = 20; //

{

char *p2 = NULL; //分配4个字节的内存 栈区也叫临时区

p2 = (char *)malloc(100); //内存泄露概念

if (p2 != NULL)

{

free(p2);

//p2 = NULL;  若不写,实验效果,分析原因

}

if (p2 != NULL)

{

free(p2);

}

}

system("pause");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高亚奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值