目录
[TOC]
指针基础
指针 即指向某数据的地址
指针是不可以int *p;
然后*p=12;
这样赋值的,正确的应该是p=12;
或是p=&i
之类(p不是int类 而是int*类,当然不能直接给它赋int的值,它是地址啊)
例:
#include <iostream>
using namespace std;
int main()
{
double i=100,j=200,k=300,d=10.9;
double *pointer1,*pointer2=&d;
pointer1=&i;
//对指针的直接引用
cout<<pointer1<<endl;//0x6ffe28
//对指针的间接引用
cout<<*pointer1<<endl;//100
cout<<pointer2<<endl; //0x6ffe20
cout<<*pointer2<<endl;//10.9
j=*pointer1;
cout<<j<<endl;//100
*pointer1=500;
cout<<pointer1<<endl;//0x6ffe28 地址不变
cout<<i<<endl;//500 随*pointer1一起改变
cout<<j<<endl;//100 pointer1指向的不是j的地址 所以当指针作为右值使用的时候就和普通赋值是一样的(把pointer1指向的值赋给j),所以此处j的值不变
return 0;
}
指针作函数参数
对于函数来说,传入普通变量接收到值,传入指针则接收到地址。为什么要传一个地址呢,因为比如一个structure,它可能很大,传入地址就可以用比较少的字节传递值给参数。传入数组时其实传入的也是指针,int a[]和int *a是一样的。
指针可以在函数中传出多个变量
例:求数组中元素的最大最小值
1.指针可以在函数中传出多个变量
#include <iostream>
using namespace std;
void minmax(int a[],int len,int *min,int *max);
//此函数无返回值,void别手贱打成int,min和max虽然是参数,起的却是带出返回值的作用
int main()
{
int a[]={1,2,3,4,5,6,7,8,9,12,13,14,16,17,21,23,55};
int min,max;
//这里的min和max也要声明过,执行了函数之后值就被改变了
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
//a后面不用加[],更不要忘了取址符,传的是指针啊
cout<<"min:"<<min<<",max:"<<max<<endl;
}
void minmax(int a[],int len,int *min,int *max)
{
*min=*max=a[0];
for(int i=1;i<len;i++)
{
if(a[i]<*min)
*min=a[i];
if(a[i]>*max)
*max=a[i];
}
}
那如何实现自己输入一个数组然后找到最大最小值呢?
稍微改一下上面的代码
#include <iostream>
using namespace std;
void minmax(int a[],int len,int *min,int *max);
int a[10000];
int main()
{
int number,i=0;
while(cin>>number)
{
a[i]=number;
i++;
}
int min,max;
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
cout<<"min:"<<min<<",max:"<<max<<endl;
}
void minmax(int a[],int len,int *min,int *max)
{
*min=*max=a[0];
for(int i=1;i<len;i++)
{
if(a[i]<*min)
*min=a[i];
if(a[i]>*max)
*max=a[i];
}
}
注:这样是错误的! 定义了全局变量a[10000]后,尽管最后没有cin10000个数据,但sizeof(a)还是10000*4,且未读入的数据为0。把sizeof(a)/sizeof(a[0])
换成i
就可以了,本来sizeof(a)/sizeof(a[0])
就是用来计算出数组内元素个数的。
把数组作参数,实际上也是指针。在**函数内部**sizeof(a)时,结果为4。
需要返回函数运算状态时
函数返回(return)运算状态(比如文件操作中一般用-1或0表示没有有效结果),而万一有效结果就是-1或者0呢所以分开返回,则函数的运算结果通过指针参数返回。在C++中这也可以通过异常机制处理。
指针与const//c99only
注意区分 int *const p
和const int *p
以及int const *p
主要由*和const的相对位置区分,所以后两者的意思是相同的
int *const p
即 指针是const,一旦得到了某个变量的地址,不能再指向其他变量。
int *const p=&i;//p是const
*p=26;//ok
p++;//error
const int *p
和int const *p
即 所指是const,表示不能通过指针去修改那个变量(并不能使那个变量成为const)
const int *p=&i;
*p=26;//error
i=26;//ok
p=&j;//ok
void f(const int *x);
int a=15;
f(&a);//这样a变成了const 就可以防止其在函数内部被修改
指针的运算
1.指针的地址线性递增,且指针可比较(比较地址)
2.无论指向什么地址,指针占用空间的大小都是一样的。
3.*(p+1)为移到下一个单元,移的距离为sizeof(类型)。例如char是1字节,int是四字节。如果p不指向连续的空间,则+1无意义。
4.两指针可以相减,这时候无论是int还是char都代表1,也就是并不用管数据类型占多少字节(或者可以理解成地址差/sizeof(类型))
5.*p++ (++优先级更高)
取出数据之后再移到下一个位置 经常用于数组的遍历
6.a为数组,则int *p=a;相当于int *p=&a[0];
7.关于0地址。内存中有0地址,但指针不应该具有0值。因此可以用0地址来表示返回的指针无效等。NULL是一个预定定义的符号,表示0地址。有些编译器不愿意你用0来表示0地址,用NULL比较保险(注意大写)