指针
指针与指针类型
指针
概念:在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值指向(points to)存在电脑存储器中的另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元(一个内存单元大小为一个字节)
注:
- 32位机器上,指针变量大小为4byte(4x8=32);64位机器上,指针变量大小为8byte
- 32位机器上:由于2^(32-10-10-10) = 4GB,故内存最大为4G
常量指针
表示指向常量的指针,例如
const int* ptr1 = &a;指针常量
表示指针是一个常量,指针指向不允许改变,例如
int* const ptr2 = &b;
指针类型
概念:
Q:为什么指针大小在同一个平台上大小都相同,为什么还要区分指针类型?
A:存放时,虽然各个指针类型结果一样,但是解引用后,结果不一样!例如:
char*、int*、float*等理解:
指针类型决定了指针解引用操作时,能访问的大小
注:访问大小为指向的类型的大小,下面同理
指针类型决定了指针+1、-1时,到底加减几个字节
野指针、指针运算
野指针
概念:指针指向的位置是不可知的指针为野指针
野指针形成原因
指针未初始化(没有初始化为NULL)
指针越界访问
指针指向的内存空间被释放
注:在动态内存开辟处,详细讲解堆区内存被释放的情况
如何避免野指针
- 指针初始化(初始化为空指针NULL)
- 小心指针越界
- 指针指向空间释放,及时把指针置为NULL
- 指针使用前检查有效性。即闲时置为空指针,用时判断是否为空指针
注:NULL在编译器中的定义:#define NULL((void*)0)
指针运算
指针加减整数
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = arr; for (int i = 0; i < 5; i++) { printf("%d\n", *p); p += 2; }加减后,指针指向的地址位置,移动到距离指针类型访问空间大小整数倍的地址位置
指针减指针
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("%d\n", &arr[9] - &arr[0]); // 输出结果:9指针减指针表示到起始地址中间的内存长度
注:
- 小地址-大地址结果为负数
- 两个指针必须指向同一块空间(如数组空间),才有意义
指针类型对指针减指针的影响
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; char* p1 = &arr[9]; char* p2 = arr; printf("%d\n", p1 - p2); // 输出结果:36指针的关系运算
float values[5]; float* p; for (p = values; p < &values[5];) { *p++ = 0; }注:
- &values[5]指的是数组末尾的野指针
- 标准规定:
- 允许数组元素指针与最后一个元素后的内存位置进行指针比较
- 不允许与首元素之前的内存位置进行比较
字符指针
字符指针的一般使用
char ch = 'a'; char* pch = &ch; *pch = 'b';常量字符串在字符指针中的使用
const char* pstr = "666";注:
- 本质是把常量字符串”666”的首字符地址放入到pstr中3
- 常量字符串的内容不允许被更改!(报错:写入访问权限冲突)
常量字符串的细节
char str1[] = "hello bit."; char str2[] = "hello bit."; const char* str3 = "hello bit."; const char* str4 = "hello bit."; if (str1 == str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not same\n"); if (str3 == str4) printf("str3 and str4 are same\n"); else printf("str3 and str4 are not same\n");输出结果:
str1 and str2 are not same str3 and str4 are same由此可得:
- 当用同一个常量字符串去初始化不同的数组时,会开辟出不同的内存块
- 当两个指针指向同一个常量字符串时,它们实际会指向同一个地址
注:C/C++会把常量字符串储存在单独的一个内存区域。当几个指针指向同一个常量字符串时,他们实际会指向同一个地址