指针讲解 1
1:首先什么是指针呢?指针的形式有哪些呢?
指针其实就是地址,我们通过这个地址找到我们所需要的数据,类似于宾馆的形式,每个房间都有房号(地址),我们在入住的时候按照房号找到所指示的房间(数据),我们拿的房卡(房卡标有房号)就是指针。
指针主要的形式有 int *p=NULL(指向整形数据的指针) , char *p=NULL(指向字符型数据的指针)这两部分。
2:应用场景
1):在模块化程序的编辑中,牵扯到很多功能,比如实现数组元素的逆置,对实参进行算术运算等等,我们无法使用“传值”的形式更改数据内容,那么“传址”的形式就很重要啦
传址跟传值有什么区别?什么是传址?传址怎么改变数据的?
传址和传值的区别重要凸显在函数调用的时候,当你对子函数传递实参,通过子函数的功能想要对数据进行一系列的更改其实比较难,因为“传值”的形式其实是对数据的一份临时拷贝,当你在子函数运行时对复制体进行各种各样的操作,对原数据没有一点改变,例如
int fun(int x,int y) // 实现a ,b数值对换
{
int temp = 0;
temp = x;
x = y;
y= temp;
}
int main()
{
int a= 1,b = 2;
fun(1,2);
printf("%d %d\n",a,b);
system("pause");
return 0;
}
结果:
a=1
b=2
实际上并没有改变
传址呢,其实就是通过地址对数据进行改变,可以通俗的这样理解:在宾馆里,每个房间电话是唯一的,并存在这个房间里。前台可以通过电话对顾客进行一些列提醒引起改变,这就是传址的办法,例如下面
#include<stdio.h>
void fun(int *x,int *y)
{
int temp = 0;
temp = *x; // 这里的*x不是指针x,而是指针x所指空间的内容,“*”在这里是解引用
// 在定义指针时 int *p 这里代表是指针类型!在定义之后的*x都是指向地址的内容
*x = *y;
*y=temp;
}
int main()
{
int a=1,b=2;
int *p1=&a; // int *p1=&a;其实分为两部分,定义一个指针变量,指针指向a所在
int *p2=&b;
fun(p1,p2);
printf("%d %d",a,b);
system("pause");
return 0;
}
如果把解引用“ * ”去掉会怎么样?我们来试验一下
#include<stdio.h>
void fun(int *x,int *y)
{
int temp = 0;
temp = x;
x = y;
y=temp;
}
int main()
{
int a=1,b=2;
int *p1=&a;
int *p2=&b;
fun(p1,p2);
printf("%d %d",a,b);
system("pause");
return 0;
}
结果是:
a=2
b=1
第一个程序中 含有" * "的指针变量其实进行了解引用操作,其实际意义就是通过地址找到数据所在空间,对空间里的数据进行了操作
第二个程序中 没有解引用,在子函数功能中其实只是将变量 a b 的地址互换,在输出语句中,只是输出了a b的值
3:数组指针
int arr={0,1,2,3}
int *p=arr;
看到这个,有人会问啊,为啥没有“&arr”啊,是不是错啦?其实并没有。在我们的编程系统中默认数组名为一个指针,其地址为数组第一个元素的地址!当然你可以写成
p=&arr[0] 没有一点问题
1):数组指针可以进行+,-运算
p++ 指针变量指向下一个元素
p-- 指针变量指向上一个元素
*p++ 由于*与++的优先级一样,结合方向为自右向左等价为→ *(p++) 先*p再进行p++
*p-- 类比上面 *(p- -)先*p再进行p - -
*(- - p) 先进行--p(指针变量指向前一个元素),*p
*(++p) 类比上面
比如说 我们定义一个数组,输出所有元素
#include<stdio.h>
int main()
{
int arr[]={1,2,3,4,5};
int i=0;
for(i=0;i<5;i++)
printf("%d ",*(arr+i));
system("pause");
return 0;
}
数组名就是指针,这里 arr+i 就是指针指向数组第 i 个元素 *(arr+i )通过解引用,表达第 i 个元素的内容
2)数组指针可以带下标
如 p[i] ,其实在程序编译的时候,对下标的处理方法是转换成地址的,对p[ i ] 处理成*(p+i),注解:指针指向第i个元素,然后通过解引用,表示第i个元素的内容。
(二)多维数组请见下一章