基本概念
对于内存而言,将内存单元的编号叫做地址,这个单元的地址即称为指针。C语言中用一个变量来存放指针,这种变量称为指针变量。指针变量的值就是某内存单元的地址或指针。
变量的指针就是变量的地址,存放变量地址的变量就是指针变量。eg:i_pointer代表指针变量,而*i_pointer是i_pointer指向的变量。
定义和使用
类型说明符 *变量名;//int *p;
一个指针变量只能指向同类型的变量
//指针的定义
int a;
int *p=&a;
int *q;
q=&a;//不用再加*;
//*q,*p都代表a的值,q、p都指向a的地址
作为函数参数
指针变量在函数调用时,将实参变量的值传递给形参变量。采取的依然是 “值传递”。
//考虑下列语句的错误
swap(int *p1,int *p2)
{
int *temp;
*temp = *p1;//错误
*p1=*p2;
*p2=*temp;//错误
}
temp作为一个指针变量,它应该存储指针变量,第一处和第二处错误都是因为,此时,temp还没有存储地址,所以取不到相应的值。
其他说明
指针运算符 * 与指针说明符 * 不是一回事。在指针变量说明中,“ * ”是类型说明,表示其后的变量是指针类型。而表达式中的“ * ”则是表示指针变量所指的变量。
int a[5],*pa;
pa=a;//可以将数组的首地址赋予指针变量
pa++;//指针指向的位置向后移动
char *pc;
pc = "C Language";//将字符串的字符数组的首地址装入指针变量
int (*pf)();//函数入口指针
pf = f;//f为函数名
两个指针变量还能进行减法运算,表示相差的地址。但是加法是不允许的,因为毫无意义。
指针变量赋0值和未赋值是不同的,未赋值时不能使用。
数组指针的运用
int a[5],*p;
p=a;//等价于p = &a[0]
此时可以*(p+i)或*(a+i)或a[i]来访问第i个元素,p[i]与*(p+i)等价。
值得注意的是,p++是合法的,a++不是合法的,因为a是数组的首地址,是一个常量(static)。
数组做参数
void main(){
int a[10];
...
f(a,10);
...
}
f(int *x,int n){}
可以形参和实参都是数组名;实参用数组,形参用指针变量;实参、形参都用指针变量;实参为指针变量,形参为数组名;
多维数组的指针和指针变量
int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
//a既是二维数组名,也代表整个二维数组的首地址,也是二维数组0行的首地址,a[i]代表第i行首地址
int (*p)[4];//指向包含4个元素的一维数组
p=a[1];
字符串指针可以写为
char *ps;
ps=“C Language”;
而对数组而言,不能写为
char st[20];
st={“C Language”};
指针型函数
类型说明符 *函数名(形参表)//返回值是指针
{
...
}
指针数组
char *name[]={"Illagal day","Monday","Tuesday","Wednesday","Thursday","Friday","Saturdy","Sunday"};
//name[0]指向Illagal day
一个例子
#include"string.h"
int main(){
void sort(char *name[],int n);
void print(char *name[],int n);
static char *name[]={ "CHINA","AMERICA","AUSTRALIA", "FRANCE","GERMAN"};
int n=5;
sort(name,n);
print(name,n);
return 0;
}
void sort(char *name[],int n){
char *pt;
int i,j,k;
for(i=0;i<n-1;i++){
k=i;
for(j=i+1;j<n;j++)
if(strcmp(name[k],name[j])>0)
k=j;
if(k!=i){
pt=name[i];
name[i]=name[k];
name[k]=pt;
}
}
}
void print(char *name[],int n){
int i;
for (i=0;i<n;i++)
printf("%s\n",name[i]);
}
指向指针的指针
char **p;
p=name[1];
main函数的参数
int main(int argc,char *argv[]){}
用于DOS命令行输入:C:>可执行文件名 参数 参数 …
argc 代表命令行参数个数(可执行文件名也是一个参数)
所以取参数一般从argv[1]开始