提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
这次主要介绍指针的知识,通过演示一些简单的应用帮助大家更好的了解指针。
一、什么是指针
指针实际上就是地址,保存地址的那个变量叫做指针变量,指针变量中保存的一定是地址。
二、指针的使用
1.指针的定义
#include <stdio.h>
int main()
{
int num = 0;
int* p = #
printf("&num=%p\n",p);
return 0;
}
这个就是正常情况下的指针的定义,打印出的就是num的地址。
2.指针的类型
定义指针变量的时候需要加上指针类型,指针的类型则决定了对指针进行解引用时访问几个字节,也决定了指针加一时会跳过的字节数,说数组和指针时会看到。
上面示例中指针的类型就是int *类型,而*代表的是指针,那我如何确定指针变量的类型呢?很简单只需要将数据名去掉,剩下的就是它所对应的类型,这么说不明白?来看示例:
#include <stdio.h>
int main()
{
int num = 0;
int* p = #
int** pp = &p;
printf("&num=%p\n",p);
printf("&p=%p",pp);
return 0;
}
结果如下:

在这段代码中,p是什么类型的呢?将int* p中的p去掉,就剩下int*,那他就是int类型,将指针p的地址给了pp,将int** p中的变量名p去掉,指针变量pp的类型就是-----int**。记住上面判断指针变量类型的方法。
3.指针的空间中的大小
指针变量也是变量,既然是变量,那就会在内存中分配空间,所以指针变量的大小是多少呢?我直接说明,任何类型的的指针变量的在64位操作系统下是8个字节,在32位操作系统下,4个字节。指针的大小和类型没有关系,可以验证一下:
#include <stdio.h>
int main()
{
printf("p的大小:%ld\n",sizeof(int*));
printf("p的大小:%ld\n",sizeof(char*));
printf("p的大小:%ld\n",sizeof(float*));
printf("p的大小:%ld\n",sizeof(double*));
return 0;
}
结果如下:

可以确定不论何种类型的指针变量都是是占有8个字节的。
4.*和&的使用
*在运算的时候是乘,但在指针这里,一是用来定义指针变量的,二是用来进行解引用操作的;来看一下简单的解引用:
#include <stdio.h>
int main()
{
int num = 20;
int* p=#
printf("num的地址:%p\n",p);
printf("num的值为:%d\n",*p);
return 0;
}
可以看到所谓解引用就是将指针变量p所保存地址中的值取了出来,知道这个就可以了,接着看后面。
&,这个符号在运算时,指的时按位与 运算符(不了解的可以看一下我之前发过的c语言中的运算符),那么在这里取地址符,scanf(),初始化指针指针的时候经常用到。
5.数组和指针
在介绍数组和指针之前还有东西是需要大家知道的,看示例:
#include <stdio.h>
int main(){
int arr[8]={0,1,2,3,4,5,6,7};
int* p=arr;
printf("arr=%p\n",arr);
printf("arr+1%p\n",arr+1);
printf("&arr+1%p\n",&arr+1);
printf("sizeof(arr)=%ld\n",sizeof(arr));
return 0;
}
arr与arr+1之间相差了4个字节,arr的地址也就是arr[0]的地址,我们定义的是int类型的数组,相差4个字节就意味arr+1等价于arr[1] ,没有问题。再看&arr+1,发现打印的地址,和首地址相差了32个字节,刚好是sizeof(arr)这个数组的长度,那我们就得知&arr再进行加1会跨越一整个数组。
小结,&arr和sizeof(arr)这两种情况是代表整个数组。
现在开始看数组和指针,数组的使用离不开指针,都知道数组名就是首元素的地址,既然是地址,我们就可以将指针和数组联系起来,通常我们打印数组中的元素,是使用数组索引进行打印的,那今天看一下指针的用法:
#include <stdio.h>
int main()
{
int arr[8]={0,1,2,3,4,5,6,7};
int* p=arr;
//用数组的长度除一个元素的长度,就是数组元素的个数;
int length = sizeof(arr)/sizeof(arr[0]);
for(int i=0;i<length;i++)
{
printf("arr[%d]=%-2d",i,arr[i]);
}
putchar('\n');
for(int i=0;i<length;i++)
{
printf("arr[%d]=%-2d",i,*(p+i));
}
putchar('\n');
return 0;
}

两种打印的结果一摸一样,使用索引打印大家都会,来看一下使用指针的原理。
p存放的是数组首元素的地址,即p等价于&arr[0],p+1代表的就是&arr[0]+1, 在之前那个例子中得到的结论是&arr+1代表是地址加32,那现在是&arr[0]+1,代表的便是地址+4,对应的也就是&arr[1],所以p+1等价于&arr[1],再加上解引用,就是指向地址所对应的值了。下面是一个等式帮助理解:
会一维数组的指针,相信二维甚至多维你们也都将可以轻松拿下了。
6.野指针、void指针、NULL指针
野指针指的是指针中没有存地址的或是随机的无效的地址:
#include <stdio.h>
int main()
{
int a;//局部变量没有赋初值,值是随机的,包括指针变量。
int* p;//野指针,没有给变量存放地址,p中的地址是随机的。
}
void*是一种特殊的指针类型,可用于存放任意对象的地址。
#include <stdio.h>
int main()
{
int data = 100;
void *p = &data;
return 0;
}
但因为它没有类型,所以不能用直接用指针操作所指的对象。
NULL指针,#define NULL (void *)0 定义指针的时候,一般会把指针的值初始化为0地址,仅仅用于初始化。0地址用户没有执行权限。直接对0地址操作,系统会提示段错误。
#include <stdio.h>
int main()
{
int num = 20;
int* p = NULL;
p = #//一定在p中存一个有效地址,因为NULL,仅仅用于初始化。
}
总结
指针应用非常广泛且灵活,是c的的难点和重点,希望引起重视。
C语言指针详解
2031

被折叠的 条评论
为什么被折叠?



