目录
1.1数据类型本质分析
1.1.1数据类型概念
1.1.2数据类型的本质
1.1.3给类型起别名--typedef
1.1.4void类型
1.2变量的本质分析
1.2.1变量的概念
1.2.2变量的本质
1.3程序的内存四区模型
1.3.1栈区和堆区
1.3.2静态区
1.4函数的调用模型
1.5函数调用变main量传递分析
1.6栈的生长方向和内存存放方向
1.1数据类型本质分析
1.1.1数据类型概念
- “类型”是对数据的抽象
- 类型相同的数据有相同的表示形式、存储格式以及相关的操作
- 程序中使用的所有数据都必定属于某一种数据类型
数据类型的本质思考:
1.思考数据类型和内存有什么关系吗?
2.c/c++为什么会引入数据类型?
1.1.2数据类型的本质
- 数据类型可理解为创建变量的模具:是固定内存大小的别名
- 数据类型的作用:编译器预算对象(变量)分配的内存空间大小
- 注意:数据类型只是模具,编译器病美欧分配空间,只有根据类型(模具)创建变量(实物),编译器才会分配空间
举例:
#include<stdio.h>
int main()
{
int b[10]={0};
printf("b:%d,&b:%d",b,&b);
//b,&b的数组类型不一样
//b--数组首元素地址,一个元素4个字节 +1=+4
//&b--整个数组的首元素地址,一个数组4*10=40个字节 +1=+40
printf("b+1:%d,&b+1:%d",b+1,&b+1);
return 0;
}
1.1.3给类型起别名--typedef
//typedef和结构体结合使用
#include<stdio.h>
struct MyStruct
{
int a;
int b;
};
typedef struct MyStruct
{
int a;
int b;
}TMP;
int main()
{
//定义结构体变量,一定要加上struct关键字
struct MyStruct m1;
//
TMP m1;
return 0;
}
1.1.4void类型
- 函数参数为空,定义函数时,可以用void修饰,int fun(void)
- 函数没有返回值,void fun(void);
- 不能定义void类型的普通变量,void a;//err 因为编译器不能为变量分配具体的
- 可以定义void*变量,void* p; //ok
- 数据类型本质,固定内存块大小别名
- void* p万能指针,函数返回值,函数参数
1.2变量的本质分析
1.2.1变量的概念
概念:既能读又能写的内存对象,称为变量;若一旦初始化后不能修改的对象则称为常量。
变量定义形式:类型 标识符,标识符,标识符;
1.2.2变量的本质
1.程序通过变量来申请和命名内存空间 int a=0.
2.通过变了名访问内存空间
变量:一段连续内存空间的别名
1.3程序的内存四区模型
1.3.1栈区和堆区
用代码来分析:
#include<stdio.h>
#include<string.h>
char* get_str1(void)
{
char str[] = "ahjkajdihda";//栈区
printf("str=%s\n", str);
return str;
}
char* get_str2(void)
{
char* tmp = (char*)malloc(100);//堆区
if (tmp == NULL)
{
return NULL;
}
strcpy(tmp, "kasdjioasdjkas");
return tmp;
}
int main(void)
{
char buf[128] = { 0 };
strcpy(buf, get_str1());
printf("buf=%s\n", buf);//乱码,不确定
char* p = NULL;
p = get_str2();
if (p != NULL)
{
printf("p=%s\n", p);
free(p);
p = NULL;
}
return 0;
}
1.3.2静态区
#include<stdio.h>
int* getA()
{
static int a = 10;//变量a在静态区/全局区
return &a;
}
int main()
{
int* p = getA();
//函数getA()调用完之后a不会释放
printf("\n");
system("pause");
return 0;
}
1.4函数的调用模型
- main函数在栈区开辟的内存,所有子函数均可以使用
- main函数在堆区开辟的内存,所有子函数均可以使用
- 子函数1在栈区开辟的内存,子函数1和子函数2均可以使用
- 子函数2在全局区开辟的内存,子函数1和main均可以使用