数据类型
数据类型的概念:
“类型”是对数据的抽象,类型相同的数据有相同的表现形式、存储格式以及相关的操作。程序当中使用的所有数据都必定属于某一种数据类型。
数据类型的本质:
数据类型可以理解为创建变量的模具,是固定内存大小的别名。数据类型为编译器预算对象(变量)分配指定的内存空间大小。
数据类型的别名:
#include <iostream>
int main(void)
{
//typedef 原数据类型 新数据类型
typedef char myChar1; //给字符类型起一个别名myChar1
typedef myChar1 myChar2; //给别名再起一个别名myChar2
myChar2 c2 = 'c'; //使用自定义的数据类型(新数据类型)
printf("c2 = %c\n", c2); //printf输出函数输出
return 0;
}
数据类型的封装:
C语言规定只有相同类型的指针才可以互相赋值,但是void*指针作为左值可以用于“接收”任意类型的指针。当void*作为右值赋值给其他指针时需要强制类型转换。
int *p1 = NULL;
char *p2 = (char *)malloc(sizoeof(char)*20);
C语言并没有定义void究竟是多大内存的别名,所以不存在void类型的变量。void的字面意思就是“无类型”,void*则是“无类型指针”,void*可以指向任何类型的数据。
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
void修饰函数返回值和参数,仅表示无。如果函数没有返回值,那么可以将其声明为void类型。如果函数没有参数,应该将其参数声明为void。
数据类型总结:
数据类型的本质是固定内存大小的别名:是一个模具。C语言规定,通过数据类型定义变量。
数据类型大小通过“sizeof”进行计算。
可以给已经存在的数据类型通过“typedef”起别名。
数据类型可以通过void这个万能类型进行封装。
变量
变量概念:
变量就是既能读又能写的内存对象,如果一旦进行初始化后就不能修改的对象被称为常量。
//变量定义形式:类型 标识符
int x;
int x,y,z;
变量本质:
程序通过变量来申请和命名内存空间,通过变量名访问内存空间,变量就是一段连续的内存空间的别名。
可以直接修改变量,也可以间接通过获取内存地址修改内存数据。
#include <iostream>
#include <windows.h>
int main()
{
int i = 0;
std::cout << "i = " << i << std::endl;
std::cout << "请输入修改后的i值:";
std::cin >> i;
std::cout << "修改后的i值:" << i << std::endl;
Sleep(1000);
std::cout << "接下来我们通过内存编号操作内存,修改变量。" << std::endl;
Sleep(1000);
std::cout << "变量i的内存地址为:" << &i << std::endl;
Sleep(1000);
*(&i) = 10;
std::cout << "修改后的i值:" << i << std::endl;
Sleep(1000);
return 0;
}
内存四区
内存四区的建立流程:
1,操作系统把物理硬盘代码载入到内存当中。
2,操作系统把C代码分成了四个区。
3,操作系统找到main函数入口,开始执行。
各区元素分析:
栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量的值等。
堆区(heap):一般由程序员分配释放,如果程序员不释放,程序结束后可能由操作系统回收。
全局区,静态区(static):全局变量和静态变量是存储在一起的,初始化的全局变量和静态变量在一块区域,还未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,该区域在程序结束后由操作系统释放。
常量区:字符串常量和其他常量的存储位置,程序结束后由操作系统进行释放。
程序代码区:存放函数体的二进制代码。
函数
基本运行原理:
调用main()函数,调用fa(),执行fa()代码块,调用fb(),执行fb()代码块。
#include <iostream>
int fa()
{
fb();
return 0;
}
int fb()
{
return 0;
}
int main()
{
fa();
}
内存四区模型和函数调用模型变量传递分析:
堆区与栈区和函数个数没什么关系,堆区每个程序只有一个,栈区分为进程栈和线程栈,每个进程一个进程栈,每个线程一个线程栈。
当函数嵌套调用时,实参地址传给形参后,C++编译器通过作用域管理变量的生命周期。
main函数中可以在栈区分配内存也可以在堆区分配内存,全局分配内存。所以可以被fa、fb使用。但是,如果fb在栈上分配内存,则不能被fa和main使用。fb在堆区分配的内存,可以被main和fa使用。fb中进行全局分配的内存,是可以被main和fa使用的。