前言
以下是从定义开始对指针的讲解,以练习为主,配有精美bushi小图片。如果你也觉得指针难难的话,就和SThree一起来学习叭~~
本人技术不高,所以讲解很是通俗易懂呢~~
如果有疑惑或者我哪里讲错了,十分欢迎各位指出!!!
一、指针的定义和使用
一句耳熟能详的话作为引入:指针就是变量的地址。如果用酒店作比,那么变量就是住客,指针就是他们每个人的房间号。
那么指针变量就是专门存放变量地址的变量啦~
如何定义呢,我们举个栗子叭***:
int a; int *point_a=&a;
* 表示后面是一个指针变量,point_a就是指针变量的名字,这句话表示point_a中存放a变量的地址,即point_a指向a (就是a的房间号嘻嘻嘻)我们可以拿着房间号(point_a),通过钥匙(*)找到对应房间里的人(*point_a=a)
*也是取内容运算符,*+指针变量名 相当于 访问(就是拿着小钥匙~)
另外,我们把直接找a叫做直接访问;通过房间号找a(*point_a)叫做间接访问;
指针变量的赋值
指针变量使用之前必须赋予具体的值。未经赋值的指针变量不能使用,而且只能赋予地址。
因为变量的地址是由编译系统分配的,我们不知道变量的具体地址,所以不可以把一个数(我们认为的一个地址)赋予指针变量,故下面的赋值是错误的:
int *p; p=1000;
正确的指针变量的赋值:
1. int a; int *p=&a;
2. int a; int *p; p=&a;
被赋值的指针变量前不能加 * ,因为p才是指针的名字,可以把 int* 理解为p的类型。
如*p=&a 也是错误的。
练习1.1:
观察结果,咱就是说,point_a和&a是一回事;*point_a和a是一回事。(后有精美bushi图解)
#include<stdio.h>
int main()
{
int a;
int *point_a=&a;
scanf("%d",point_a);
printf("a=%d\n",a);
printf("&a=%d\n",&a);
printf("point_a=%d\n",point_a);
printf("*point_a=%d\n",*point_a);
}
练习1.2:
在接下来的这个练习,我们感受一下,通过钥匙替换房间里的人。
#include<stdio.h>
int main()
{
int i=10;
int *p=&i;
printf("*p=%d\n",*p);
printf(" i=%d\n",i);
*p=20;
printf("*p=%d\n",*p);
printf(" i=%d\n\n",i);
}
练习1.3:
既然可以通过钥匙换人,那我们来试一试能不能用钥匙交换两个房间里的人.(后面还有讲解,别忘了看一看~~)
#include<stdio.h>
int main()
{
int *p1,*p2,*pp;
int a=9,b=5;
p1=&a;
p2=&b;
if(a>b)
{
pp=p1;
p1=p2;
p2=pp;
}
printf("a=%d,b=%d\n",a,b);
printf("after:\na=%d,b=%d\n",*p1,*p2);
}
可以看到,尽管我们设置的a和b值本身没有发生改变,但是指向他们的指针改变了。(又要打比方了,我真的好喜欢这个酒店的栗子)
也就是说交换他们的钥匙,再通过钥匙打开房间门就是不一样的人啦hhh(这个里面我们像从前交换数值一样引入了中间钥匙,偷天换日时留一把假钥匙防止被发现)
二、指针作为函数的参数:
从前通过调用函数,我们很难得到两个返回值(貌似是根本不可能?)不过有了指针,我们就可以为所欲为了(bushi)。
那么如果想要通过函数调用得到n个要改变的值,方法如下:
- 在main里定义n个变量,用n个指针变量分别指向他们;
- 用指针变量作为实参,把n给变量的地址传给形参;
- 通过形参指针变量,改变形参指针指向的变量,也就是改变地址上的内容
练习1.4:
我们来写一个swap函数,作用还是交换两个数,同样讲解放在后面
#include<stdio.h>
void swap(int *pointer1,int *pointer2);
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("before : a=%d b=%d\n",a,b);
swap(&a,&b);
printf("after : a=%d b=%d\n",a,b);
}
void swap(int *pointer1,int *pointer2)
{
int t;//变量t作为中转站,交换两个指针做指向的内容,所以用int t,而不是int *t。
t=*pointer1;
*pointer1=*pointer2;
*pointer2=t;
}
这个题我们就是通过形参指针变量,改变地址上的内容。
是否记得我们上一题偷天换日时引入的是一把假钥匙,而这一题我们引入了一个假人(有点害怕),因为在同一个函数里我们交换钥匙就可以,但是在函数之间传递是值传递,如果我们只在被调函数里交换,是影响不到主函数的。
但是我们通过指针变量的传递可以知道要改变的 变量的地址,所以交换指针做指向的内容,就相当于在所需变量上面做文章了。
这题的图可好看了呢,本咩咩甚是满意~
练习1.5:
交换两个数的工作就结束啦,我们大胆迈出下一步,是否可以创造一个函数,同时获得数组的最大值和最小值呢~ 有了指针,这可不是难事。
//下面的代码还写了许多其他函数,uu们可以只关注主函数和FindMM函数;
//而且这个程序的界面炒鸡友好~
#include<stdio.h>
#define N 100
void FindMM(int a[],int num,int *pMax,int *pMin);//寻找数组里的最值
void GetArray(int getn,int array[]);//获取数组
int GetNumbers();//获取输入数据的个数
void PrintArray(int n,int array[]);//打印数组
int main()
{
int n,max,min;
int num[N];
printf("This program is made for finding the max and min.\n");
n=GetNumbers();
GetArray(n,num);
PrintArray(n,num);
int *pMax=&max;
int *pMin=&min;
FindMM(num,n,pMax,pMin);
printf("the max number is %d\n\n",*pMax);
printf("the min number is %d\n\n",*pMin);
printf("byeeeeeee~~~~~~~~");
}
void FindMM(int *a,int num,int *pMax,int *pMin)
{
*pMax=a[0];
*pMin=a[0];
int i,t;
for(i=1;i<num;i++)
{
if(a[i]>*pMax)
{
*pMax=a[i];
}
if(a[i]<*pMin)
*pMin=a[i];
}
}
int GetNumbers()
{
int number;
printf("how many numbers do you want?(less than 100,please)\n");
scanf("%d",&number);
return number;
}
void GetArray(int getn,int array[])
{
int i;
printf("you want %d numbers.now,please tell me the numbers.\n",getn);
for(i=0;i<getn;i++)
{
printf("please give num[%d]=",i);
scanf("%d",&array[i]);
}
}
void PrintArray(int n,int array[])
{
int j;
for(j=0;j<n;j++)
{
printf("the %d number is %d \n",j+1,array[j]);
}
}
这个关于数组的题其实我觉得还是有很多点很难懂的,但道理是不变的,我们还是(●'◡'●)细细谈论一下。
首先获取数组(这里我调用了许多小函数,你可以忽略这一步直接初始化数组),然后我设置了变量max和min,并且设置了pMax和pMin指向他们,作为参数传递给了形参。
然后在FindMM函数里我们就知道max和min的地址了,这个时候把数组的第一个元素赋给他们(不然他们可能就是小垃圾了)。
then,比较,像往常的操作一样,不过因为我们用的是max和min的地址,所以在被调函数里就可以改变主函数的变量值了。
下一讲,我们一起来看看指针和数组还有函数三者叭,应用会更紧密~~
2021.11.23
SThree楠钰子.