1.3.1数据类型本质分析
数据类型概念
- “类型”是对数据的抽象
- 类型相同的数据有相同的表示形式、存储格式以及相关的操作
- 程序中使用的所有数据都必定属于某一种数据类型
数据类型的本质思考
- 思考数据类型和内存有关系吗? yes
- C/C++为什么会引入数据类型?
数据类型的本质
- 数据类型可理解为创建变量的模具(模子);是固定内存大小的别名。
- 数据类型的作用:编译器预算对象(变量)分配的内存空间大小
- 程序举例,如何求数据类型的大小sizeof(int *)
- 请问:数据类型可以有别名吗?引用
- 数据类型可以自定义吗?typedef
void:数据类型的封装
-
-
void的字面意思是“无类型”,void *则为“无类型指针”,void
*可以指向任何类型的数据。 -
用法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 ); -
用法2: void修饰函数返回值和参数,仅表示无。
如果函数没有返回值,那么应该将其声明为void型
如果函数没有参数,应该声明其参数为void
int function(void)
{return 1;} -
void指针的意义
C语言规定只有相同类型的指针才可以相互赋值
void*指针作为左值用于“接收”任意类型的指针
void*指针作为右值赋值给其它指针时需要强制类型转换
int *p1 = NULL;
char p2 = (char )malloc(sizoeof(char)*20); -
不存在void类型的变量
C语言没有定义void究竟是多大内存的别名
-
1.3.2变量本质分析
变量概念
- 概念:既能读又能写的内存对象,称为变量;若一旦初始化后不能修改的对象则称为常量。
- 变量定义形式: 类型 标识符, 标识符, … , 标识符 ;
- 例如:
int x ;
int wordCut , Radius , Height ;
double FlightTime , Mileage , Speed ;
变量本质
1、程序通过变量来申请和命名内存空间 int a = 0;
2、通过变量名访问内存空间
(一段连续)内训空间的别名(是一个门牌号)
3、修改变量有几种方法:
1直接
2间接(内存有地址编号,拿到地址编号也可以修改内存;于是横空出世了!(编程案例)
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int a; int *p; a = 10; printf("&a:%d\n",&a);//打印a地址 { //间接赋值 *((int*)&a) = 200; printf("a:%d \n",a); //通过指针修改a的值 { p = &a; *p = 200; printf("%d",a); } } }
3、内存空间可以再取给别名吗? 可以c++抛砖引玉
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、操作系统把物理硬盘代码加载到内存
2、操作系统把c代码分成4个区
3、操作系统找到main函数入口执行
静态区实验
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> char * getStr1() { char *p1 = "abcdefg2"; return p1; } char *getStr2() { char *p2 = "abcdefg2"; return p2; } void main55() { char *p1 = NULL; char *p2 = NULL; p1 = getStr1(); p2 = getStr2(); //打印p1 p2 所指向内存空间的数据 printf("p1:%s , p2:%s \n", p1, p2); //打印p1 p2 的值 printf("p1:%d , p2:%d \n", p1, p2); printf("hello...\n"); system("pause"); return ; }
堆栈区实验
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> //堆 char *getMem(int num)//声明一个函数 { char *p1 = NULL; p1 = (char*)malloc(sizeof(char) * num); if (p1 == NULL) { return NULL; } return p1; } //栈 char *getMem2() { char buf[64]; //临时变量 strcpy(buf, "12456789");//把地址拷贝给buf数组首地址 //printf("buf:%s \n", buf);//打印buf地址 return buf; } void main() { char *tmp = NULL; tmp = getMem(10);//函数调用 if (tmp == NULL) { return ; } printf("tmp:%d \n", tmp); //栈的使用 tmp = getMem2(); printf("tmp:%d \n", tmp); //这里打印tmp是乱码 //因为堆栈是不能把内存的块给转换到全局变量的 //局部变量是不能把内存的块给转换到全局变量的 }
1.4.2内存四区模型和函数调用模型变量传递分析
1、一个主程序有n函数组成,c++编译器会建立有几个堆区?有几个栈区?
2、函数嵌套调用时,实参地址传给形参后,C++编译器如何管理变量的生命周期?
分析:函数A,调用函数B,通过参数传递的变量(内存空间能用吗?)