一、指针是什么?
指针就是地址。
二、为什么会存在指针的概念?
将计算机的内存分成很多小的单元,每个单元对应一个独一无二的地址,这样一个地址表示一个空间,所以指针就是方便定位内存中某个位置。
- 一个小的内存单元多大?(一个自己字节)
- 如何编址?
约定:一个字节给一个地址
在32位机器中,假设有32根地址线,每根地址线在寻址过程中产生一个电信号(0或者1)那么32根地址线产生的地址就会有
00000000 00000000 00000000 00000000
... ... ... ...
11111111 11111111 11111111 11111111
一共有在2的32次方个地址。
每个地址表示一个字节,就可以给4G的内存进行编址。为什么4G?
1B = 8bit
1KB = 1024B = 2^10B
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
所以,2^32B = 4G
同样的方法,在64位机器中2^64地址。
【结论】在32为机器中指针变量占4个字节,64位机器中指针变量8个字节
三、指针运算
(1)指针+-整数
【结论】指针的类型决定了指针向前或向后(加或者减)走一步多大。
在二级指针以上指针加减变化都是4个字节(32位机器)
(2)指针的解引用
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> int main() { int a = 0x11223344; int *pi = &a; char *pc = (char *)&a; *pc = 0x55; //重点在调试的过程中观察内存的变化 0x11223355 *pi = 0; //同上 0 printf("%x\n%x\n", *pi, *pc); system("pause"); return 0; }
本例中需要考虑大小端问题,我的机器是小端,所以在执行*pc = 0x55之后数据的低位0x44被替换,而在执行*pi = 0;a的值发生改变。
【结论】指针的类型决定了对指针解引用时有多大的权限(能操作几个字节)
(3)指针-指针
int arr[10] = { 0 }; int *pa = &arr[3]; int *pp = &arr[7]; printf("%d\n", pp - pa); //4
int arr[10] = { 0 }; char *pa = (char *)&arr[3]; char *pp = (char *)&arr[7]; printf("%d\n", pp - pa); //16【结论】两个指针指向同一个数组或者字符串,两指针相减表示两个指针之间经历了多少个指针类型元素个数
两指针相减应用:求字符串长度
int my_strlen(char *str) { char *pc = str; while (*pc) { pc++; } return pc - str; }
四、指针比较
再利用指针对数组初始化时,
【标准规定】允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针比较。