每天进步一点点,坚持带来大改变!!!
目录
前言:
指针在C语言中扮演这一个重要的角色,神秘且强大,接下来我们就来一点点揭开指针的神秘面纱。
1.指针概念的引入:
计算机在内存中存储数据,而内存又被划分为一个个的内存单元,每个内存单元占一个字节。
内存单元
每一个个内存单元都有相应的编号,而编号就是每个内单元的地址,而地址又被称为指针。
总结:指针就是地址。
2.指针变量
概念:
指针变量是用来存放地址的变量
辨析指针和指针变量:
指针就是地址,指针变量是用来存放变量的地址。
通常我们所说的指针实则是指指针变量
3.指针的类型和大小:
1.类型:
每一种数据类型都对应一种指针类型:
例:
2.指针的大小:
32位机器平台上指针大小占4个字节 x86
64位机器平台上指针大小占8个字节 x64
32位机器平台:
64位机器平台
注: sizeof操作数返回类型标准打印是用%zu打印
4.指针的意义 :
通过上面的图片看到指针的大小都一样,是否指针不同类型就没有意义了呢?
1.指针解引用的时候能访问几个字节
解释:通过上面三个图可以观察到,图2是整形指针在解引用的时候能访问四个字节,图三是字符指针在解引用的时候能访问只到访问一个字节。
总结: 不同的指针类型决定了指针在解引用的时候能访问几个字节。
2.指针在加减的时候跳过几个字节:
解释:整形指针+1,地址加4,说明跳过四个字节。字符指针+1,地址加1,说明跳过一个字节。
总结: 不同类型的指针决定了指针在加减操作的时候能够跳过几个字节。
5.野指针:
概念:指针指向的内存空间是未知的。
1.指针未初始化:
解释:整形指针未初始化,默认是随机值,当我们使用的时候造成了内存非法访问。
2.指针越界访问:
数组大小是10,而循环进行了11次,当进行到11次的时候,指针指向范围已经超越了数组的大小,这个时候指针就属于野指针。
3.指针指向的内存已经被释放掉了:
解释:定义的局部变量是在函数内定义的,当出了函数的时候,局部变量所占内存已经被释放掉了,还给操作系统,这个时候指针指向的内存在解引用的时候属于非法访问内存了,这个指针就属于野指针了。
4.如何规避野指针:
1.指针进行初始化:
当初始化指针的时候不知道赋什么值的时候,可以赋一个空指针(NULL),使用的时候会报错,避免了野指针的问题。
2.小心指针越界
3.使用之前判断指针的有效性:
int main() { int a = 10; int* p = &a; //判断指针的有效性 if (p != NULL) { *p = 100; } return 0; }
6.指针运算:
1.指针加减整数:
解释:通过指针将arr数组元素改成0—9;
2.指针—指针
解释:
总结:指针减指针得到的是中间元素的个数。
应用:计算字符的个数:
#include<stdio.h> int my_strlen(char* str) { char* p = str; while (*str != '\0') { str++; } return (str - p); } int main() { char ch[10] = "abcdef"; int len = my_strlen(ch); printf("%d\n", len); return 0; }
7.指针和数组:
数组名是首元素的地址,因此可以用指针接受数组名
int*p=arr;
总结:p+i计算的是arr下标为i的地址,因此可以通过指针来访问数组
总结:arr[i]==*(arr+i)==*(p+i)==p[i];
8.二级指针变量:
概念:
二级指针是用来存放一级指针变量的地址:
![]()
int main() { int a = 10; int* p = &a; int** pp = &p; //int* *pp //*说明pp是一个指针变量,int*说明pp指向的类型是int*的 return 0; }
访问数据:
9.指针数组:
概念:
用来存放指针的数组。
int main() { int a = 10; int b = 20; int c = 30; //parr是一个指针数组,该数组有三个元素,每个元素的类型是int* int* parr[3] = { &a,&b,&c }; return 0; }
访问数据:
用指针数组模拟实现二维数组:
#include<stdio.h> int main() { int arr1[] = { 1,2,3,4 }; int arr2[] = { 2,3,4,5 }; int arr3[] = { 3,4,5,6 }; int* parr[3] = { arr1,arr2,arr3 }; int i = 0; for (i = 0; i < 3; i++) { int j = 0; for (j = 0; j < 4; j++) { printf("%d ", parr[i][j]); } printf("\n"); } return 0; }
解释:
每一段努力的过程都是值得被尊重的,没有天生完美的人生,只有努力过越来越好的生活。