如果你觉得指针晦涩难懂,请多做一些练习,你会发现指针简单实用。
&取地址
pointer是一个值为内存地址的变量。
ptr = &pooh;//&取地址
把pooh的地址赋给ptr,也可以说prt指向pooh的地址;
//在声明指针变量前需要声明指针变量的类型。应该是与被指向数据类型一致
*取值
已知ptr = &pooh;
使用间接运算符*来获得pooh的值,也称为 解引用
val = *ptr
小结
int n = 0;
int ptr = &n;
int val=*ptr;
//等价于
val = 0;
声明指针
声明指针必须指定指针 “所指向变量类型”;
int *ptr;//星号表明此变量是一个指针类型
//
float sunmass;
float *psun=&sunmass;
*psun//获取值。
格式转换:%p
指针在函数间通信
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
void change(int *a,int *b){//int *a=&x;int *b=&y;
int temp;
temp=*a; //让值进行交换,如果单单是a的话只是地址。
*a=*b;
*b=temp;
}
int main(){
int x,y;
scanf("%d%d",&x,&y);//scanf读取一个值把值存储到n的地址
printf("beofer:%d %d\n",x,y);
change(&x,&y);//指针的声明形式是 int *ptr=&valaddress;
printf("after:%d %d\n",x,y);
return 0;
}
//&*的主要作用是操纵地址和地址上内容
指针与数组
arr==&arr[0];//数组名等价于数组首地址,记住这句话
指针+1指的是增加一个存储单元,对数组而言+1的地址为下一个元素的地址
int dates[n],*ptr;
ptr=dates;//(ptr=&dates[0];)
dates + 2 == &dates[2];//地址
*(dates + 2) == dates[2];//值(第三个元素的值)
下面将用一个实例用指针表达和数组相同的功能
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int months[12]={31,28,31,30,31,30,31,31,30,31,30,31};
for(int i=0;i<12;i++){
printf("%2d months has %2d days.\n",i+1,months[i]);
}
printf("__________pointer_______\n");
for(int i=0;i<12;i++){
printf("%2d months has %2d days.\n",i+1,*(months+i));
}
return 0;
}
/*
1 months has 31 days.
2 months has 28 days.
3 months has 31 days.
4 months has 30 days.
5 months has 31 days.
6 months has 30 days.
7 months has 31 days.
8 months has 31 days.
9 months has 30 days.
10 months has 31 days.
11 months has 30 days.
12 months has 31 days.
__________pointer_______
同上
*/
数组名[下表索引]==*(数组名+下标索引)
//数组名即数组首地址,在加上下标即是要获取元素地址,在*取值。效果等价于arr[i]
函数与数组,指针
编写一个函数,返回数组元素之和;
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int sum(int *arr,int n){//int *arr == int arr[]作用都是说明类型和数组首地址
int tot;
for(int i=0;i<n;i++)
tot+=*(arr+i);//
return tot;
}
int main(){
int n;
scanf("%d",&n);
int arr[n];
for(int i=0;i<n;i++)
scanf("%d",arr+i); //
int ans=sum(arr,n);
printf("ans=%d",ans);
return 0;
}
//函数的调用时传进去 数组名和数组大小
//函数原型力 *arr是一个指向数组的指针,可以 int arr[]代替;表示告诉函数数组的地址和类型
使用指针形参
上面的sum函数有两个参(数组地址,和数组大小)。这并不是象数组传递信息的唯一方法,下面方法用到2个指针一个指向数组开头一个指向数组结尾。请仔细理解,双指针的方法运用很广泛
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int psum(int *start,int *end){
int tot;
while(start<end){
tot+=*start;//累加值
start++;//地址++
}
return tot;
}
int main(){
int arr[10]={0,1,2,3,4,5,6,7,8,9};
int ans=psum(arr,arr+10);//在某些stl里面也是这样格式,sort,next_permutation
printf("the tot of arr is %d ",ans);
return 0;
}
//函数的调用 首地址,尾地址
/*定义时 首地址 尾地址
循环最后处理的是end指向位置的前一个,即end指向位置是数组最后一个元素的后面,start++到最后的值是end。
arr,arr+n;//!=arr[n]
start的递增是递增int的大小 比如 0:0123 1:就变成了(0+4 1+4 2+4 3+4) 4567...
循环还可以更加简洁
tot+=*(start++);//这样写代码更加简洁可读,你学c的到别告诉我你不会这样写。start=start+1看起来既不也不。
多维数组,变长数组
即数组的数组
int arr[x][y];
x个1维数组
每个元素,包含y个int的数组
arr[0]=[y个元素]
arr[1]
...
c传递多维数组是把数组名(数组首地址)传递给指针形参,要定义所有维度,除了第一维。
void f(int arr[][12],int rows){}
变长数组
void f(int rows,int cols,int arr[rows][cols]);
f(5,12,arr)
结尾
不要对为初始化的指针解引用
int *ptr=5;//foolish,指针指向不知什么地方
可以赋值为null
到这里指针的基本操作就差不多了,学习一些数据结构也能不被立刻劝退了
把这个捡起来的原因是,在学习数据结构时候遇到一些问题,才发现自己之前学的差不多都忘了,需要总结归纳一下,后续还会有结构和其他数据形式,文件输入输出,高级数据表示。
所有内容取自于c primer plus第6版加入了个人理解简化得来。
祝学业有成
2020/06/01