C语言指针

来源:互联网 发布:软件缺陷报告模板 编辑:程序博客网 时间:2024/05/17 19:20
         指针以前学C的时候,指针基本上是没学的。现在重新学C,觉得C指针真的很强大,不愧是C语言的灵魂。当然自己知道的还是一点皮毛而已,只是冰山一角。        首先,在克明汉的的《C程序设计语言》中,指针的定义是“指针是能够存放一个地址的一组存储单元”。说白了,指针就是存储单元,单元里放的是什么呢,就是地址。    用表格的形式如下: 

(哎,没办法,不晓得用什么软件可以做出表格,真心希望有人能教教我。现在将就的用吧,图中一个大单元格中四个小格,表示四个字节。)

图中指针占一个存储单元(四个字节),指向C(若C是char类型,则占一个字节)。


指针的声明

首先指针是变量,我的理解是既然它是存储单元,里面的内容肯定是可变的,那么他就是变量了,变量在使用前是得先声明的

int *ip;/*定义一个指针ip,所指向的内容的类型是int型*/。现在问题来了,那指针ip是什么类型的呢?因为指针也是变量啊,那他是什么类型的呢?指针的类型其实就是“四字节无符号整数”。

需要注意的是:ip++,ip--并不是表示”四字节无符号整数“加或是减1,而是表示ip指向上一个或是下一个存储单元。由于指针是变量,如果ip,iq都是指针,那么语句”ip=iq;”就是将iq中的值COPY到ip中,指针ip也指向iq指向的内容。

指针与函数参数

由于C中函数调用是把参数的传递给被调用函数,所以被调用函数不能直接修改主调函数中变量的值。在下面的例子中并不能颠倒a,b 的值;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
voidswap(int px,int py)
{
inttemp;
temp=px;
px=py;
py=temp;
}
main()
{
inta,b;
a=2;
b=3;
swap(a,b);
printf("%d,%d\n",a,b);
}

运行结果为:

但是如果把函数 的参数改成指针变量的时候情况就不同了,看下面的程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
voidswap(int *px,int *py)
{
inttemp;
temp=*px;
*px=*py;
*py=temp;
}
main()
{
inta,b;
a=2;
b=3;
swap(&a,&b);
printf("%d,%d\n",a,b);
}

运行结果是:

这是因为当主调函数swap(&a,&b)调用void swap(int *px,int *py)时,void swap(int *px,int *py)函数改变了主函数main()中a,b的值。

指针与数组

在数组完成的操作都是通过数组下标来完成的,通过数组下标完成的操作都可以通过指针来完成。这是因为我们可以通过指针指向数组,然后对指针操作,从而实现对数组的操作。

由于数组名传递给函数时,实际上就是传递该数组的第一个元素的地址。

例如"int *ip;ip=&a[0];"和”int *ip=a“是等价的,当然前提是a是数组。

在函数定义中形式参数" char s[]"和"char *s"是等价的,也就是说上述程序中swap( int *px,int *py)也可以用swap( int px[],int[])替代。但是习惯上用"char *s",因为它更直观的表明该参数是一个指针。
面的例子可以 说明指针 与数组的关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
voidswap(char *px,char *py)
{
chartemp;
temp=*px;
*px=*py;
*py=temp;
}
main()
{
chara[1],b[1];
a[0]=2;
b[0]=3;
swap(&a[0],&b[0]);
printf("%d,%d\n",a[0],b[0]);
}

数组指针与指针数组

指针数组,它是数组,只是数组的每个元素是指针。如:"int *ip[]",先定义了一个数组ip[],数组的每个元素都是一个指向int类型的指针。

数组指针,它是指针,只不过该指针是指向数组元素的。如:"int (*ip)[]",先定义指针ip,指向int类型的数组。

复杂声明

个人觉得C中涉及到指针的复杂声明是不用掌握太细的,主要就是掌握各运算符的优先级。

"char **argv":离argv最近的是"*"说明变量argv是指针,指向指向char类型的指针。

"int (*daytab)[3]":由于()的作用使得daytab是指针,指向int类型的数组,数组有三个元素。

"int *daytab[3]":由于[]的优先级高于*,所以就是声明指针数组。和上面有点重复了。

"void *comp()":由于()的优先级高于*,所以comp是一个函数,函数返回的是指向viod类型的指针。

"void (*comp)()":comp是一个指针,指向viod类型的函数。

"char (*(*x())[]()";这个看起来挺麻烦的。首先由于()的优先级高于*,所以x是个函数,函数返回的是指针(可标记为指针1),指针1指向的是指针数组,数组元素是指针(可用*s[i]表示),

s[i]指针又指向返回类型为char类型的函数。

总之要搞明白复杂声明就先得识记运算符的优先级。


原创粉丝点击