C语言知识总结(三)

来源:互联网 发布:java数据结构与算法 编辑:程序博客网 时间:2024/06/05 09:52

编辑中。。。未完。。。


一个由c/C++编译的程序占用的内存分为以下几个部分(内存四区

1、栈区(stack):

由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。

对于自动变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由C语言编译器实现,栈不会很大,一般都是以K为单位的

当栈空间以满,但还往栈内存压变量,这个就叫栈溢出

对于一个32位操作系统,最大管理管理4G内存,其中1G是给操作系统自己用的,剩下的3G都是给用户程序,一个用户程序理论上可以使用3G的内存空间,
2、堆区(heap):

一般由程序员分配释放,若程序员不释放,程序结束时可能由OS操作系统回 收。

注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但没有栈那样先进后出的顺序。

堆是一个大容器,它的容量要远远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成。

3、数据区:

主要包括静态全局区和常量区,如果要站在汇编角度细分的话还可以分为很多小的区。

1全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。  程序结束后有系统释放
2常量区 :常量字符串就是放在这里的。 程序结束后由系统释放

4、  代码区:

存放函数体的二进制代码。代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的。



指针:指针是一种数据类型

指针变量也是一个变量,指针存放的内容是一个地址,该地址指向一块内存空间

指针的步长,根据所指内存空间类型来定。

指针占用字节:汇编书籍对指针比较具体的解释:指针是寄存器和内存字。

寄存器在不同的操作平台上位数是不同的;内存字也是如此。

例如在8086上,内存字就是16位的,而x86系统是32位的。

对于windos的平台,32位的操作系统,寄存器和内存器是32位的。所以就是4个字节;而换到其他的平台,得根据操作平台而定的。就和整形数据在不同平台的数据范围一样。64位系统下是8个字节(64兼容32位,编译器不同会导致64位系统下生成的是32位程序【可以更换编译器】)一般Unix的指针字节数为4

还有种更加直观的解释就是:指针是以内存地址作为变量地址。


野指针解决办法:

1、定义指针时,把指针变量赋值成NULL

2、释放内存是,先判断指针变量是否为NULL

3、释放完内存后,把指针变量重新复制成NULL


一级指针易错点:

1、不断修改指针的指向,然后又free和printf(重复free或操作已经被释放的内存单元)

2、Char buf[3] = “asc” ;//越界问题

3、*p++与(*p)++.;前者是指针++,后者是数据++

一遍可能定义一个变量计数值的时候用*count++,错误用法

还有就是求字符串的时候指针指向改变,然后释放该内存的时候出错

1、  还有就是被调用函数分配临时空间,然后把该临时空间首地址返回出来出错

2、  解决的方法有多种,一般字符串指针的时候用两个指针,一个用于记录首地址

3、  为什么int a[10];中a是个常量 ,a++;//这里会报错,为什么数组首地址不能++

因为a是数组类型的内存块的首地址,这数组是个临时变量。编译器要拿着首地址a去释放内存,为了避免你把a 的指向改变所以设置为常量(数组的首地址是常量,不可改变)


指针的最大意义:指针做函数参数间接赋值是指针存在的最大意义

将函数指针做为另一个函数的参数称为回调函数


指针小结:

定义

说明

int  i

定义整形变量

int *p

定义一个指向int的指针变量

int a[10]

定义一个int数组

int *p[10]

定义一个指针数组,其中每个数组元素指向一个int型变量的地址

int (*p)[10]

定义一个数组指针,指向int [10]类型的指针变量

int func()

定义一个函数,返回值为int型

int *func()

定义一个函数,返回值为int *型

int (*p)()

定义一个指向函数的指针,函数的原型为无参数,返回值为int

int **p

定义一个指向int的指针的指针,二级指针


1)指针也是一种数据类型,指针的数据类型是指它所指向内存空间的数据类型

2)间接赋值*p是指针存在的最大意义 

3)理解指针必须和内存四区概念相结合 

4)应用指针必须和函数调用相结合(指针做函数参数)

5)指针指向谁就把谁的地址赋给指针 

6)指针指向谁就把谁的地址赋给指针,用它对付链表轻松加愉快

7)链表入门的关键是分清楚链表操作和辅助指针变量之间的逻辑关系


数组在内存的存储方式:数组在内存中就是一段连续的空间,每个元素的类型是一样的


结构体的内存对齐模式

结构体的赋值(深拷贝和浅拷贝)



文件



作为接近底层的高级语言,c语言的代码中,允许嵌入汇编语言。在某种情况下,用汇编语言替代高级语言,可以大大提高运行效率。

int main(){int a = 10;_asm   //汇编指令{        mov eax,a   //移动,将a的值赋值eaxadd eax,3   //加法,eax的值+3mov a ,eax  //寄存器的值赋值给a}printf("%d", a);return 0;}