目录
指针是什么
指针变量的大小
指针和指针类型
指针类型的意义
野指针
指针运算
指针+-整数
指针-指针
指针的关系运算
指针和数组
二级指针
二级指针定义
指针数组
指针数组的定义
指针是什么
如下图所示(右侧编号为内存地址):
int a = 10;//a占四个字节
int* pa = &a;//拿到的是a的四个字节中第一个字节的地址
//将a的地址存放在pa变量中,pa是一个指针变量
指针变量的大小
指针和指针类型
指针类型的意义
1.指针类型决定了:指针解引用的权限有多大(如下例)
int a = 0x11223344;
int* pa = &a;
*pa = 0;
上述代码中,原先a地址的值在内存中显示为:
执行后面两句代码后,内存中四个字节的值被改变了:
而在下述定义char指针类型的代码中:
只改变了一个字节的地址
2.指针类型决定了:指针每走一步的步长(如下例)
int arr[10] = {0};
int* pa = arr;
char* pc = arr;
printf("%p\n",pa);
printf("%p\n", pa+1);
printf("%p\n", pc);
printf("%p\n", pc+1);
同样加一,但是int类型和char类型指针的步长不同
野指针
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的) ,造成原因为:
1.指针未初始化
int* p;//p是一个局部的指针变量,未初始化默认为随机值
*p = 20;//非法访问内存
2.指针越界访问
int arr[10] = { 0 };//数组大小为10
int* p = arr;
int i = 0;
for (i = 0; i <= 10; i++) {//循环11次
*p = i;
p++; //第11次越界,产生非法访问
}
3.指针指向的空间释放
int* test() {
int a = 10;
return &a;
}
int main() {
int* p = test();//局部变量a申请的内存空间已经销毁
*p = 10; //此时指针p再把10存入a的内存空间中,为非法访问内存
return 0;
}
如何规避野指针:
1.指针初始化(不知初始化为何地址时,初始化为NULL)
2.小心越界指针
3.指针指向空间释放即放置NULL
4.指针使用之前检查有效性(if p!= NULL)
指针运算
指针+-整数
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr;
int* pend = arr + 9;
while (p<=pend) //指针的关系运算(地址大小在比较)
{
printf("%d\n", *p);//依次打印1 2 3 4 5 6 7 8 9 10
p++; //指针+-整数
}
指针-指针
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", &arr[9] - &arr[0]);//结果为9
//指针减去指针得到的是两个指针之间元素的个数
指针的关系运算
#define N_VALUES 5
float values[N_VALUES];
float* vp;
for (vp = &values[N_VALUES]; vp >&values[0];) {//关系运算
*--vp = 0;//数组所有元素置为0
}
上方这段代码与下方图片中的代码执行结果是相同的:
但是,下方这段代码是存在一些问题的:
指针和数组
数组名是数组首元素的地址:
int arr[10] = { 0 };
printf("%p\n", arr);//数组名是数组首元素的地址
printf("%p\n", &arr[0]);
//打印结果都为00EFF920
通过指针访问数组:
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (int i = 0; i < 10; i++) {
printf("%d", *(p + i) = i);
//成功打印数组各元素
}
二级指针
二级指针定义
int a = 10;
int* pa = &a;//pa是指针变量,一级指针
//ppa是一个二级指针变量
int** ppa = &pa;//pa也是个变量,&pa取出pa在内存中起始地址
//a的值为10,地址为0x0012ff40
//pa的值为0x0012ff40,地址为0x0012ff48
//pa的值为0x0012ff48,地址为0x0012ff52
如何通过上述代码通过ppa找到a?
*ppa == pa
*pa == a
* *ppa == a
存在三级、四级等指针,但一般很少使用
指针数组
指针数组的定义
//指针数组 - 数组
int arr[10];//整型数组 - 存放整型量
char ch[5];//字符数组 - 存放的是字符
//指针数组 - 存放指针的数组
int* parr[5];
char* parr[5];
以上为C语言中指针初阶知识的相关内容,感谢您花费宝贵的时间阅读本文章!
之后博主会撰写关于指针高阶相关内容的博客。