1. 指針定義
2. 指針和指針類型
3.野指針
4. 指针运算
5.指针和数组
6.二级指针
7.指针数组
-
\t \r \n都是转义字符,空格就是单纯的空格,输入时可以输入空格
-
\t 的意思是 :水平制表符。将当前位置移到下一个tab位置。
-
\r 的意思是: 回车。将当前位置移到本行的开头。abcdef \r ghi 输出:ghidef回到句首会覆盖掉
-
\n 的意思是:回车换行。将当前位置移到下一行的开头。
-
\f的意思是:换页。将当前位置移到下一页的开头
1.指针定义
!!!!!!!!!!指针也可以说是开辟了一块可以存放变量地址的空间
指针是指指向一个变量的地址,当 int a = 10; a 是有 4 个字节,当&a 的时候,指向的是a 的4个字节中,第一个字节的地址。把它取出来之后要存储起来,要去定义一个指针变量 int *pa = &a (把第一个字节的地址存到整型的指针变量中)可以*pa = 20 就可以去改变a的数值了(a不是一共有4个字节吗?*pa只是存储了其中一个啊,为什么=20之后,整个4个字节的内容都变了?)
#include<stdio.h>
int main( )
{
int a = 10;
int *pa = &a;
*pa = 20;
printf("%d",a);
return 0;
}
//这个最后的结果是 20 怎么能?!!!!
不理解 不理解,不是第只是第一个字节吗?(有人说:创建空间,取地址符取的是第一个字节的地址)难道 那个10 就只是存在整型a的第一个字节里?
总结:指针就是变量,用来存放地址的变量(存放在指针中的值,都当做地址处理)
一个内存单元就是一个字节。
指针是用来存放地址的,地址是唯一标示一块地址空间的。
指针的大小:在32位平台上是4个字节,在64 位的平台上是8 个字节。一个数占4个比特位,8个比特位一个字节
2.指針和指針類型
指针类型的意义:
char 类型的只能访问一个字节 int 类型可以访问4 个字节 float类型可以访问4个字节
1 个16进制位 是4个 2进制位
int 是32个bite位 就是4 个字节,一个数占4个bite位,2 个数是一个字节
指针类型决定了,指针解引用的权限有多大
指针类型决定了,指针走一步,走多远 char * pc 和int * p 都输出时,是一样的,但是,如果
每一个输出的值都是加一的话,就不一样,因为p是int 的类型,加一 跳过4个字节,pc是char的类型,加一跳过的是1个字节
! 整型 的指针+1 会跳过一个整型
! 字符 的指针+1 会跳过一个字符类型
! 数组 的指针+1 会跳过一个数组
#include<stdio.h>
int main()
{
int arr[10]={0};
int *p=arr;
char *pc=arr;
printf("%p\n",p);//1
printf("%p\n",pc);//2
printf("%p\n",p+1);//3
printf("%p\n",pc+1);//4
return 0;
}
结果 000000000062FDE0
000000000062FDE0
000000000062FDE4
000000000062FDE1
int 和char的区别 int是一次访问4个字节,char是一次只访问一个字节
#include<stdio.h>
int main()
{
int arr[10]= {0};
int *p = arr;
int i;
for(i = 0;i < 10;i++)
{
*(p+i) = 1; //*(p+i)是数组下标为i的元素,都赋值为1
}
for(i=0;i<10;i++)
printf("%d ",arr[i]);
return 0;
}
如果把int *p = arr 换成 char *p = arr的话一共40个字节,它可能就只访问10个
*p = arr指针指向一个数组,只是等于数组的第一个元素的地址
3 野指针
指针的位置是不可知的,是随机的,不确定的,没有明显限定的
造成野指针有两种情况
1.int *p没有初始化,是一个随机值,造成了后续的*p = x变成非法访问
2. 越界访问,是多了一个数组下标,数组下标是从0 开始
int arr[10]= {0};
int *p = arr;
int i;
for(i = 0;i <= 10;i++)在 i <10之前,*p还不是野指针,一旦超出循环范围了,*就被命名为野指针
{
* p=i;
p++;
}
3.指针指向的空间释放
指针指向的空间存在时,叫指针,当空间被释放掉时,就被称为野指针
#include<stdio.h>
int *test()//进入函数内部,a 的局部变量空间创建
{
int a = 10;//向系统申请了4个字节的空间
return &a; //返回了a的地址,那么a的局部变量的4个字节的空间也就销毁了
}
int main()
{
int *p = test(); //这里最后返回了a的地址,并不是返回的向内存申请的空间
*p = 20;
return 0;
}
进入 test的函数时,是创建了a的局部空间, int a,给a定义数据类型,同时,向系统申请了4个字节的空间 但函数return时,是返回的a的地址 而不是返回的int 的数据类型,所以这个向系统申请的a的空间也就销毁了,没有办法带出函数,带出的是a的地址。所以这个*p 就变成了野指针,int *p 没有赋值的空间。
如何去避免野指针
1,指针要初始化
当不知道指针要初始化为什么地址的时候 直接初始化为空指针(NULL)?
2,小心指针越界
3,指针指向空间释放之后,及时设置空指针
4,指针使用之前,要进行有效性的检查
当指针等于NULL 时 int *p = null,是不存在的,发生不了的 null = 0,0的空间是不属于操作系统中的,没有分配给我们的,所以也发生不了,在使用指针时,要去判断,if(p!=NULL)才可以去使用它 ?