【C语言篇】☞ 13. 指针、大端和小端、进程空间
指针
1. 概念
指针就是地址,指向了内存中的一个位置。
地址是内存的一个编号,内存中的一个字节就有一个编号,这个编号就是这个字节的地址。
1Bytes(字节)= 8bits(二进制)
2. 指针变量
保存指针(地址)的变量。我们经常将指针变量直接叫指针。
3. 用法
- 为什么用指针?
- 通过传地址,可以在一个函数中访问另一个函数中的变量。对其进行操作
-
可以用指针带回一个结果
指针是引用数据类型,因为本身没有保存数据,只是保存了数据的地址,间接的找到内存中的数据。
- 指针用于参数
值传递:函数的参数不是指针,调用这个函数传参数时相当于赋值。
基本数据类型作为函数的参数是值传递, 在函数中修改形参的值不会影响到外面实参的值。
地址传递:函数的参数是一个指针,调用这个函数时需要传的是地址。
数组/指针作为函数的参数是地址传递, 如果是地址传递在函数中修改形参的值会影响到外面实参的值。
4. 应用
5. 指针加减操作
- 指针加、减操作:与类型有关
- 指针支持加整数、减整数、指针的比较和相减,但运算的单位由指针的类型决定。
- int类型指针 + 1 = 地址 + 4
- char类型指针 + 1 = 地址 + 1
6. 指针与数组的区别
(1)占用内存空间
数组占用空间 = 数组元素占用的空间*长度
指针占用空间 = 在64位系统下,8个字节,固定的,与指针的类型没有关系
(2)赋值
数组名是常量,不可以修改其值;
指针是变量,可以多次赋值(对指针赋值,本质上是指针指向的改变)
数组的本质:
- 数组其实是内存中的一片空间。定义一个数组,相当于分配了一片内存空间。
- 数组名就是这片空间的首地址。数组名中的值不可改变,是个常量指针。
- int a[10];//a是常量指针,40Bytes的空间的开始位置保存在a中。
数组做为参数传递:
- 将一个数组传入函数时,传的是数组的地址,而不是数组本身。
- C语言中无法将整个数组用拷贝的方式传给函数。
- 所以,在C中,将一个数组传给一个函数时,一般需要再传一个数组长度的参数。
数组可以做函数的返回值吗?
函数是不可以返回数组类型的。一个函数的返回值类型不可能出现xx[],但可以返回指针。
大端和小端
由于计算机CPU的架构设计不同,一个整数有内存中存放的字节序列也不一样。
小端:一般的x86都是小端,一个整数的字节会倒序存放在内存中。比如int型的变量有4个字节,第4个字节会放在开始位置。
大端:正好和小端相反,一个整数的字节会顺序存放在内存中,和存放字符串是一样的。solaris基本是大端的。
整数在内存中保存时,不同的计算机(主要是CPU)会有不同的保存方式:
进程
程序: 保存在磁盘(外存)中的一个可以执行的文件。(在外存)
进程: 正在执行的程序。先从磁盘调入到内存中,再执行。(在内存)
进程空间
- 可以执行的文件叫应用程序,在磁盘上保存
- 进程是正在运行的程序,在内存中
- 每个进程在内存中占据的空间称进程空间
一个进程占用的内存空间可以分为以下区域:
一、代码区(正文段,text)
存放需要执行的代码(二进制代码和字符串常量)。最大特点是:只读。对此区域的修改直接会导致程序崩溃。
二、全局区(静态全局区)
存放全局变量和静态变量的。可读写,在程序运行期间,空间不会被释放。
BSS段:属于全局区,存放没有初始化过的全局变量。程序运行前,该区域会自动清0。
三、堆区(自由区 heap)
程序员自由分配空间和释放空间。动态分配内存空间。可读写。
说明:
- 程序员想什么时候在此区域分配空间就什么时候分配,想什么时候释放就什么时候释放。
- 该区域分配的内存空间不会自动释放,只能由程序员主动释放。
- 如果该释放的内存空间忘记释放,会导致内存泄漏
申请分配空间:malloc、remalloc、OC中(alloc、init、new)
释放空间:free、delete、OC中(release)
四、栈区(stack)
存放局部变量(自动变量),内存空间的分配和释放是自动的,不受程序员的控制。可读写。
不要访问野指针(没有赋值的指针, 我们称之为野指针)