大一C语言期末补天的快来看!从零开始教你学指针!

一.指针的基本构成

1.指针与地址

通常来讲,指针就是地址,地址就是指针。可以从两种角度来认识它:

1.可以把它看作是一个编号,计算机内的每一块空间都有一个地址,也就是这个编号。

2.可以抽象的把它认为是一个箭头,它代表其所指向空间的地址。

比如说:地址为0x00000012的空间,里面存放了一个整型数据1,单位为四个字节。指针指向或者说代表的就是0x00000012。

2.指针变量

a.基本形式:定义一个 *p,其中p是指针变量名,* 是解引用操作符。

*p的含义:p代表的是一个地址,通过p可以找到存储数据的空间位置,再通过* 可以取出p地址空间里面的内容。

既然提到了*,那么就不能忘了还有&(取地址操作符)。可以通过&,取出变量的地址

 那么如何定义一个指针变量呢?我们以整型指针为例,如下所示:

int a=10;
//定义一个整型a
int *pa;
//再定义一个同样为整型的指针变量
pa=&a;
//右边意为把a的地址取出,然后存进指针变量pa中
int b=*pa;
//如果我们想把a的值赋值给b,就可以通过*,对pa进行解引用操作,通过pa中存储的a的地址找到a空间存储的内容即10

注:*和&两者为互逆运算

b.指针变量类型

指针在计算机中同样以数据形式存储,指针可以存放地址信息,但同样指针自身也有地址和空间。指针类型的不同也影响了指针的运算以及在计算机中的指针的指向。有int*,char*,long*等类型,而不同类型的指针变量所占的字节大小不同,比如int*占4个字节,char*占一个字节。

c.指针变量的初始化和野指针

指针变量也需要初始化,一般来说,需要向里面输入一个地址以明确指针的指向,否则,指针所指向的位置可能会随机,这意味着一些计算机重要的空间可能被访问或修改。就算不给指针变量一个明确的地址,也要给它赋值NULL,不然这就是一个野指针

3.指针的运算

a.赋值运算:这个较为简单,上面也有所说明
b.加减运算
int*pa;
int a=*pa;
a=*(pa+1);//取a地址后一位地址的值赋给a

pa-pb=两个地址中间的元素个数
c.关系运算
pa>pb
//pa的地址大于pb的地址
pa==pb
//pa的地址等于pb的地址
pa&&pb=!NULL
//pa和pb的地址不为空

二.指针与其他C语言主体的结合

1.指针和数组

a.数组指针  (*p)[ ] 

定义(要与数组指针区分开来):一个指向数组的指针,其本质是一个指针,对象是数组,在

(*p)[ ] 中,* 先与指针变量p结合,成为一个指针,再与[ ] 结合,表明指向。

一维数组
int arr[5]={1,2,3,4,5};
//定义一个整型一维数组

int*pa=arr;
//把pa定义为一个数组指针,指向arr数组

pa=&arr[0];
//其中,指针pa指向的是一维数组首元素的地址

指针pa指向的是一维数组首元素的地址

如果想要用指针来访问整个数组的内容,就可以如下:

int arr[]={1,2,3,4,5};
int *pa=arr;
for(int i=0;i<5;i++)
{
 printf("%d ",*(pa+i));//通过多次循环就可以用指针访问到数组中的内容了
}
多维数组

这里以二维数组为例,指针pa指向的是二维数组第一行首元素的地址

int arr[2][3]={{1,2,3},{4,5,6}};
int (*pa)[3]=arr;
//二维数组的指针定义较为特殊,列不能省略

//其中pa=&arr[0][0],表示第一行首元素地址
//而(pa+1)=&arr[1][0],表示第二行首元素地址
//而(pa+1)+1=&arr[1][1],表示第二行第二个元素地址

如果要用循环和指针来访问数组的话,需要一个双重循环,跟一维数组的详细,就不多赘述了。

以上都属于数组指针的范畴,接下来介绍指针数组。

b.指针数组  *p[ ]

定义(要与数组指针区分开来):一个元素是指针的数组,其本质是一个数组,元素是指针,在

*p[ ] 中,p 先与[ ]结合,成为一个数组,再与 * 结合,表明其元素。

int a=10;
int b=5;
int* pa=&a;//int先和*结合,表明指针类型,pa为指针变量,存储从a中&的地址
int* pb=&b;
//先定义两个整型指针
int *arr[]={pa,pb};  
//再定义一个指针数组把指向a和b的指针存储起来

2.指针和字符串

这个没什么好说的,直接看例子

char* str={"i am a student"};
printf("%s",str);
//这里的str指的是str字符串的字符首地址,即'i'的地址

3.指针和函数

函数指针基本形式是:函数返回类型+ * +指针变量名+(参数1,参数2),比如 

 int* pt (int,int)

同时指针也可以作为函数的参数,比如

 int* pt (void*,void*)

而且,函数指针和数组连用可以起到提高函数利用效率的作用

int Add(int x, int y);
int Sub(int x, int y);
int Mul(int x, int y);
//先定义三个不同功能的函数
int(*pfarr[])(int, int) = {NULL,Add,Sub,MUL};//这里加NULL是为了添空,让k跟元素下标能对应上
//再定义一个函数指针数组,把定义好的函数作为*pfarr数组的元素
ret = (*pfarr[k])(a, b);
//通过改变k的值,改变指针指向,进而调用不同函数

4.多级指针

因为上面讲到指针本身也有地址,所以指针也可以被其他指针所存储。这里以二级指针为例

int a=10;
int* p=&a;
//这是一级指针
int** pp=&p;
//这是二级指针,*pp里存放了p的地址
int ret=**pp;
//这样就可读取到a的值了

多级指针可以让指针的运用更灵活,但一般到二级指针就够用了,再多可能会更复杂

5.指针和结构体

代码如下

struct stu
{
	char name[20];
	int age;
	int weight;
};//先定义一个结构体
struct stu student1 = {"gmy",18,140};
//完善结构体内容
struct stu *p = &student1;
//定义结构体指针,指向student1
printf("%s\n", p->name);//或者p.name
printf("%d\n", p->age);
printf("%d\n", p->weight);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值