新手在C语言的学习过程中遇到的最头疼的知识点应该就是指针了,指针在C语言中有非常大的用处。下面我就带着问题来写下我对于指针的一些理解。
指针是什么?
指针本身是一个变量,它存储的是数据在内存中的地址而不是数据本身的值。它的定义如下:
int a=10,*p; p=&a int a=10; int *p=&a;
首先我们可以理解 int* 这个是要定义一个指针p,然后因为这个指针存储的是地址所以要对a取地址(&)将值赋给指针p,也就是说这个指针p指向a。
很多新手都会对这两种定义方法感到迷惑,其实他俩的意思是一样的。第一种定义方法定义了int型的变量a和指针p,然后将a的地址赋给p。第二种是在定义指针p的同时将a的地址赋给指针p。我们姑且理解为" int * "是定义指针的标志。
指针有什么用?
这样我们就可以通过*p来找到指针所指向的变量a的地址,然后对地址中的值(值是10)进行操作。
//接着上面的代码printf("%p",p) //结果是一个地址(p指向的变量a的地址)。printf("%d",*p) //结果是10,变量a的值。printf("%d",&p) //结果是一个地址(指针p的地址,因为指针也是一个变量自己也有地址的)
数组名和指针的区别?
数组名是一个地址,它可以被理解为一个常指针(它只能指向本数组首元素的地址)。而指针可以指其他的变量等等。
int str[5]={1,2,3,4,5};int *p=str;printf("%d",*p); //输出为1,数组的首元素。printf("%d",*str); //输出为1,数组的首元素。printf("%d",str[0]); //输出为1,数组的首元素。printf("%p",p); //输出为地址,数组的地址。printf("%p",str); //输出为地址,数组的地址。printf("%d",*(p+1)); //输出为2,数组的第二个元素。printf("%d",*(srt+1)); //输出为2,数组的第二个元素。
对照代码大家可以很清晰的看到数组名在对内存中存储的数据进行操作的方法和结果是一样,但是数组名存储自己数组本身的首地址。
什么是空指针,野指针?
在函数内部对指针进行赋值操作后,在函数执行完毕后,该指针就成了一个空指针(变量从栈中弹出)。但是通过动态地址分配(堆空间)的指针不会有上述问题。
free(p)后释放内存的指针为野指针。
关于const对于指针的限制问题
int a=10,b=20;int * const p=&a; //无法使p指向其他地址。p=&b; //这样的操作是不允许的。*p=20; //可以这样操作。const int * p=&a; //p可以指向其他地址。p=&b; //可以操作。*p=10; //操作不被允许。const int * const p=&a //p不能指向其他地址,也不能改变地址中的值。p=&b; //操作不被允许。*p=20; //操作不被允许。
const在int的左边那就是不能修改地址中的值,在右边就是不能指向其他地址,左右都有那就是既不能修改地址的值也不能指向其他地址。
新手常出现的问题我个人总结了上述几点,如果有错误的地方希望大家留言交流互相学习。后面会写下多维数组的存储方式和指针的问题。
下面简单介绍下c语言指针的几种用法。
1、指针指向变量:
下面有这样一个代码块:
int main(){int a=10;int b=15;test(a,b);printf("a=%d,b=%d/n",a,b);}void test(int x,int y){int tmp;tmp=x;x=y;y=tmp;}
最后输出的结果还是a=10,b=15。因为在函数调用时,实参和形参之间只是值传递。但我们使用指针结果就不一样了,如:
int main(){int a=10;int b=15;test(&a,&b);printf("a=%d,b=%d/n",a,b);return 0;}void test(int * x,int *y){int tmp;tmp=*x;*x=*y;*y=tmp;}
输出结果a=15,b=10。变量a和b的值发生了交换。这是因为我们利用指针访问变量的存储单元,间接修改变量的值。
2、指针指向数组:
定义一个数组并初始化,int array[5]={2,5,12,7,8},定义一个指针变量并把数组的地址赋给它,int *p=array,注意数组名就是数组的地址,而且数组的地址就是首元素的地址。因此我们的指针变量就指向了数组的首元素,*p=2。如果把(p+1),那么指针变量就指向了数组的下一个元素5,因此我们可以利用指针来遍历数组的各个元素:
int main(){int array[5]={2,5,12,7,8};int *p =array;for(int i=0;i<5;i++){printf("array[%d]=%d/n",i,*(p+i));}return 0;}
3、指针指向字符串:
我们都知道用数组存储字符串,如char name[20]="jack",上面已经简单讲述了指针指向数组,所以我们可以这样做,char *name="jack",指针变量指向字符串的首个字符并可以依次访问字符串的各个字符。
4,指针指向函数:
我们需要知道怎样表示一个指针指向函数,说白了就是语法要正确,下面我也取一个代码块来说明一下:
int sum(int x,int y){return x+y;}int main(){int a=5;int b=6;int (*p)(int,int);p=sum;int result=(*p)(a,b);printf("The result is %d/n",result);return 0;}
不难发现上面代码块里语句(*p)(a,b)可以用p(a,b)来代替,因为p和sum就是一样的,只是用前者可能更容易理解一点。而我们要知道怎样定义一个指针指向函数,int (*p)(int,int)这是固定写法,前面的int是指针将来指向的函数的返回值的类型,如果没有函数返回值,那就是void,后面括号里的两个int 当然就是指针将指向的函数的形参。指针指向函数用起来确实有点抽象,要想熟练运用的话就多去做一些这方面的练习吧!
5,指针指向结构体:
我们首先首先定义一个结构类型,
struct student{ char *name; int ages;};
再根据类型定义结构体变量 struct student stu={"Rose",15};定义一个指针指向结构体类型,struct student *p;把结构体变量stu的地址赋给指针变量p,p=&stu;我们可以有3种方式来访问结构体中的属性ages:
stu.ages=15;(*p).ages=15;p->ages=15;不过第三种方式在C语言中只能用来指向结构体。
综上所述,指针的基本用法就是这几种,还有些用法不常见的小编在此就一一例举了,有兴趣的话可以去翻阅相关的资料。
总结
以上就是本文关于C语言指针详解及用法示例的全部内容,希望对大家有所帮助。感谢朋友们对本站的支持!
新闻热点
疑难解答