指针的总结
一.什么是指针(指针的定义)
从根本看,指针就是一个值为内存地址的变量(或数据类型) 。
例如 char类型变量的值为字符,int类型变量为整数。而指针变量的值为地址。
二.指针的表示方法
指针变量声明时必须指定指向变量的类型。为什么呢?
我们知道 在系统中,地址是按照字节编址。例如char类型的变量所占字节数为1,short类型变量所占字节数为2。 指针指向的是一个存储单元的地址,所以指针就需要知道指向对象占多少字节。
例:int * p; 便是定义了一个指向int 类型 的指针变量。其中 int* *为指针变量的数据类型,*p为变量的名称。
三.指针的使用
变量都需要声明与初始化,指针变量也不例外。这时就需要*与&两个运算符。
1. &运算符
***&***是取地址运算符,给出变量的地址。
int a;//声明了int类型的变量a
int* p = &a;//将a的地址赋给指针变量p
printf("%p", p);//输出a的地址 (%p为指针变量的输出格式)
2.*运算符
*是指针运算符,给出指针指向地址上储存的值。
int a=1;//声明并赋值给a
int* p = &a;//p指向a
printf("%d\n", *p);//输出p指向地址上的值
printf("%d\n", a);//输出a
可以看见 * p和a输出的值是相等的。因为p中储存的是a的地址,而我们对p使用 * 进行解引用 得到的便是a的值。
那么我们也可以推出以下两个式子
&(*p)==a;
*(&a)==p;
3.野指针
野指针指向的位置随机,不确定,没有明确限制。
int* a;
*a = 9;
printf("%d",*a);
return 0;
未初始化a就会默认为随机值,这个a便指向的一个随机的地址,那么我们对a进行解引用 程序就会报错。
如果我们不知道指针指向何处又该如何初始化呢?使用NULL。
int *a=NULL;//定义一个空指针
int b=9;初始化一个b;
a=&b;将b的地址赋值给a;
printf("%d",*a);输出
return 0;
4.空指针
在C语言中如果一个指针不指向任何一个数据我们便称其为空指针(NULL)。
int *ptr=NULL;//这便是定义了一个空指针。
我们也可以用0定义空指针 即是
int*ptr=0;//等价于上文。
不过虽然 NULL和 0具有相同的功能,但建议使用NULL 替代 0。
四.指针的运算
1.指针±整数
int ar![在这里插入图片描述](https://img-blog.csdnimg.cn/f0e22094b5ef4a689407b3db824282f1.png#pic_center)
r[10] = { 0,1,2,3,4,5,6,7,8,9 };//定义一个包含0-9的数组
int* p = &arr;//p指向数组首元素
for (int i = 0; i < 10; i++)
{
printf("%d ", *p);//输出当前p指向的值
p++;//指针指向下一个元素
}
在此代码中 我们通过对指针循环加1实现输出数组中所有元素。
但是指针p实际上并不是加的1,而是加的1个int类型的字节数。
例:
int arr[10];
int* p = &arr;
printf("%p\n", p);
p++;
printf("%p", p);
我们对p使用自增运算符 加1 然后p中地址实际上是加4(int类型的长度)。
2.指针-指针
指针可以与整数进行运算,同样也可以与指针进行运算。
指针求差:可以计算两个指针的差值。通常,求差的两个指针分别指向同一数组的不同元素,通过计算求得两个元素的距离。 但是求差的两个指针必须是指向同一数组。
int arr[10]; int* p1 = &arr[5]; int* p2 = &arr[2]; printf("%d\n", p1 - p2);
为什么结果不是12 而是3?
因为arr[5]与arr[2]中相差3个元素 所以输出为3.