11.26.2016
封装:
将函数单独写入一个*.c文件,可以将main.c与*.c一起编译,同样可以直接调用函数,可以提高代码的复用性
变量和常量:
变量:
特点:
数据类型:说明变量占据的空间大小 e.g. int型
作用域:变量的有效范围e.g. 局部变量只在函数内生效
变量的储存区域:变量在内存中的存储方式。不同的存储方式,影响变量在内
存中的生命周期
计算机三大部件:
CPU:
内存:保存动态数据,断电失去所有信息,类似于CPU内的高速缓冲存储器用于解决CPU与硬盘速度不同的矛盾
硬盘:静态保存数据…….
程序保存在硬盘,进程保存在内存,
内存大提高速度的原因:因为内存是稀缺资源且是共享的,CPU在内存中寻找数据
时耗时更长
C语言打印出的变量地址不是真实的物理地址,而是操作系统抽象出来的空间地址,类似于页表的作用抽象出来的地址相当于物理地址进行页内偏移
进程处于就绪态时保存在“进程虚拟地址空间”,操作系统给每个进程4G虚拟空间(最大占用资源值),真实分配内存时是2M内存,虚拟地址对物理地址不断映射,进程需要更多资源时继续以2M内存为单位增长,由MMU(内存管理器)实现映射
操作系统如何给内存划分区域
1.把最高地址的1G给内核(内核空间)
2.剩下3G给用户(用户空间)
用户空间:
1.栈空间:局部变量,函数形参,自动变量
2.堆空间:malloc ralloc calloc这些函数分配的空间
特点:1)先进后出
2)系统管理内存空间的分配(例如主函数返回一个局部数组,可能数组正在被释放时主函数打印局部数组,所以可能部分乱码)
3.数据区:
特点:1.先进先出
2.用户管理
划分:
1)bss段:未初始化的全局变量
2)or段:(only read)保存常量
3)静态数据区:static修饰的变量,初始化的全局变量
4代码段:代码内容
分配空间的方式:栈空间,堆空间,数据区三个区域分配
数据区与栈空间的区别
1. char *ptr=”hello world” 为常量字符串,保存在数据区or段,不可修改,
用指针修改时报错
char ptr[100]=”hello world” 为局部数组,保存在栈,可修改
2. int num; 保存在栈空间,打印num直接返回一个随机值(未初始化)
static int num: 保存在数据区,打印返回0(未初始化)
局部变量与全局变量的区别(2):
1.数据的存储位置:局部为栈空间,全局为数据区
2.声明周期:局部为所在函数,全局为整个程序
3.初始化:局部随机返回一个垃圾值,全局初始化为0(未初始化时)
4.全局与局部重名时,优先使用局部
段错误调试
gcc –g编译一下,启用GDB run命令运行一下,会提示段错误的位置
声明和定义的区别
定义:1.需要分配内存空间
2.只能定义一次 e.g. int num;
声明:1.不分配内存空间,告知编译器这个变量已经开辟内存,提高编译速度
2.可以声明多次
变量的声明分类:1.定义性声明:需要开辟内存 int num;声明时建立存储空间
2.引用性声明:不需要开辟内存 externa int num;num在别的文件已经建立存储空间
格式控制输入输出:
scanf(”%d,%d”,&a,&b) scanf每次遇到空格或回车结束一次录入
%称为占位符,表示这里将被其他数据取代
没有取地址符&出现段错误的原因:只有变量名无法获得唯一的地址,因为存在变量重名(地址具有唯一性)
长整型:ld
double:lf
获得地址:p
案例:当前面为scanf为整型,下一个scanf为字符时,后面的scanf会获得\n,因为输入第一
个scanf时会输入回车,会被下一个scanf读取到
解决方法:1.二者之间加一个getchar()函数(只能读取一个字符,用来把\n读取走)(遇到两个scanf,下一个直接自动输入时就用getchar()放两者之间)
2.scanf(“ %c”,&ch); 加一个空格
3.scanf(“%*c%c”,&ch); 加%*c
gets()函数警告的原因,它没有缓冲,也就是没有上限,容易造成数据溢出
例如char src[10];
gets(src)可以输入任意长度,回车后报错