什么叫指针
指针与指针变量:一个变量的地址就称之为该变量的“指针”,而“指针变量”则是用来存放这个地址的变量。
地址:内存中存储单元的位置编号就是地址。
存储单元:大小固定,1Byte(字节)。
而在32位系统中我们最多可以有(2^32)个编号,即从0~0xffffffff
64位系统之最多有(2^64)个编号,即0~0xffffffffffffffff
如果定义如下变量与指针:
int i;
int* p=&i;
那么,p是一个int型变量,它里面存放的就是i的地址,而p则代表以p中所存储的地址作为起始地址,以p的基类型所占的字节数作为偏移量,访问此空间。
p的起始地址就是i的地址,基类型为int,所以从起始地址开始访问四个字节的存储空间,就得到了i的值。
指针变量作为函数参数
我们都知道,一个函数只能有一个返回值,那么当我们想返回多个值时就可以使用指针变量作为函数参数。
在被掉函数中,通过对形参指针的间接访问,可以改变主调函数中实参指针所指向的变量的值。
比如swap函数:
以前的做法是
void swap(int a[])
{
if(a[0]>a[1])
{
int t;
t=a[0];
a[0]=a[1];
a[1]=t;
}
}
可以通过数组来返回所要的值.
使用指针:
void swap(int* a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
通过指针就可以返回所要的值。
但要注意,不能写成这样子:
void swap(int* a,int *b)
{
int* t;
*t=*a;
*a=*b;
*b=*t;
}
上面代码中所定义的int* t;t并没有初始化,所以t中存放的就是一个随机地址,而这个地址系统中并不一定会有,所以这样运行会出错误。
数组与指针
我们都知道指针是经常会和数组放在一起使用,如定义如下指针:
int a[10];
int* p;
p=a;
这就定义了一个指向数组首元素的指针,他存放的就是数组首元素的地址,即a[0]的地址。由C语言规定 p+1就是a[1]的地址,并不是在原来的地址基础上简单的加一,而是由p+(sizeof(p的基类型))*要加的数。
一些数组与指针等价的写法:
int a[10];
int* p=a;
则a[i]==*(a+i)==p[i]==*(p+i)
对二维数组来说:
int a[3][4];
int (*p)[4];
p=a;
则a[i][j]==*(a[i]+j)==*(*(a+i)+j)==(*(a+i))[j]
int (*p)[4]是定义了一个指针变量p,该指针指向一个长度为4,元素为int的数组。
注:
数组名代表数组首元素地址
(数组名取地址)+1代表跳过整个数组
例如:
int a[3][4];
int (*p)[4],
p=a;
p是一个指针数组,p代表着a[0]的地址,而a[0]是一个包含着四个元素的数组名,
p+1==a[0]+1,即代表跳过整个a[0]数组,跳过四个int型数,即p+1跳过了16个字节。
字符串与指针
char s[]=“hello world !”;
char* p=“hello world !”;
可以写s[3]=‘a’;
不可以写p[3]=‘a’;
因为p是一个指向字符串常量的指针,常量在运行期间不能被改变,而s是一个数组,可以被改变。
如果改写为
char s[]=“hello world !”;
char* p=s;
那么两个就都可以改变,因为p变成了一个指向数组的指针。
一个可以实现链式表达式的字符串复制函数
char* strcopy(char* dest,const char* src)
{
char* temp=dest;
if(dest==NULL||src==NULL)
return ;
while(*dest++=*src++);
return temp;
}
int main()
{
char s[100];
char s1[]="tom & jerry";
char *p=NULL;
p=s1;
strcopy(s,p);
}