当前位置:早雪网网络学院编程文档C/C++ → C语言我眼中的指针

C语言我眼中的指针

减小字体 增大字体 作者:不详  来源:supcode.com收集整理  发布时间:2005-7-22 19:41:10
方向移动了20个字节。

总结一下,一个指针ptrold加上一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类
型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值增加了n乘
sizeof(ptrold所指向的类型)个字节。就是说,ptrnew所指向的内存区将比ptrold所指向的内存区向高地
址方向移动了n乘sizeof(ptrold所指向的类型)个字节。一个指针ptrold减去一个整数n后,结果是一个新
的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相
同。ptrnew的值将比ptrold的值减少了n乘sizeof(ptrold所指向的类型)个字节,就是说,ptrnew所指向
的内存区将比ptrold所指向的内存区向低地址方向移动了n乘sizeof(ptrold所指向的类型)个字节。

 

第三章。运算符&和*

 

这里&是取地址运算符,*是...书上叫做“间接运算符”。&a的运算结果是一个指针,指针的类型是a的类
型加个*,指针所指向的类型是a的类型,指针所指向的地址嘛,那就是a的地址。*p的运算结果就五花八
门了。总之*p的结果是p所指向的东西,这个东西有这些特点:它的类型是p指向的类型,它所占用的地址
是p所指向的地址。

例五: 

int a=12; 

int b; 

int *p; 

int **ptr; 

p=&a;//&a的结果是一个指针,类型是int*,指向的类型是int,指向的地址是a的地址。

*p=24;//*p的结果,在这里它的类型是int,它所占用的地址是p所指向的地址,显然,*p就是变量a。

ptr=&p;//&p的结果是个指针,该指针的类型是p的类型加个*,在这里是int**。该指针所指向的类型是p
的类型,这里是int*。该指针所指向的地址就是指针p自己的地址。

*ptr=&b;//*ptr是个指针,&b的结果也是个指针,且这两个指针的类型和所指向的类型是一样的,所以用
&b来给*ptr赋值就是毫无问题的了。

**ptr=34;//*ptr的结果是ptr所指向的东西,在这里是一个指针,对这个指针再做一次*运算,结果就是
一个int类型的变量。

 

第四章。指针表达式。

 

一个表达式的最后结果如果是一个指针,那么这个表达式就叫指针表达式。下面是一些指针表达式的例
子: 

例六: 

int a,b; 

int array[10]; 

int *pa; 

pa=&a;//&a是一个指针表达式。 

int **ptr=&pa;//&pa也是一个指针表达式。 

*ptr=&b;//*ptr和&b都是指针表达式。 

pa=array; 

pa++;//这也是指针表达式。 

例七: 

char *arr[20]; 

char **parr=arr;//如果把arr看作指针的话,arr也是指针表达式

char *str; 

str=*parr;//*parr是指针表达式 

str=*(parr+1);//*(parr+1)是指针表达式 

str=*(parr+2);//*(parr+2)是指针表达式 

由于指针表达式的结果是一个指针,所以指针表达式也具有指针所具有的四个要素:指针的类型,指针所
指向的类型,指针指向的内存区,指针自身占据的内存。

好了,当一个指针表达式的结果指针已经明确地具有了指针自身占据的内存的话,这个指针表达式就是一
个左值,否则就不是一个左值。

在例七中,&a不是一个左值,因为它还没有占据明确的内存。*ptr是一个左值,因为*ptr这个指针已经占
据了内存,其实*ptr就是指针pa,既然pa已经在内存中有了自己的位置,那么*ptr当然也有了自己的位
置。

 

第五章。数组和指针的关系

 

如果对声明数组的语句不太明白的话,请参阅我前段时间贴出的文章<<如何理解c和c++的复杂类型声
明>>。 数组的数组名其实可以看作一个指针。看下例:

例八: 

int array[10]={0,1,2,3,4,5,6,7,8,9},value; 

... 

... 

value=array[0];//也可写成:value=*array; 

value=array[3];//也可写成:value=*(array+3); 

value=array[4];//也可写成:value=*(array+4); 

上例中,一般而言数组名array代表数组本身,类型是int [10],但如果把array看做指针的话,它指向数
组的第0个单元,类型是int *,所指向的类型是数组单元的类型即int。因此*array等于0就一点也不奇怪
了。同理,array+3是一个指向数组第3个单元的指针,所以*(array+3)等于3。其它依此类推。

例九: 

char *str[3]={ 

"Hello,this is a sample!", 

"Hi,good morning.", 

"Hello world" 

}; 

char s[80]; 

strcpy(s,str[0]);//也可写成strcpy(s,*str); 

strcpy(s,str[1]);//也可写成strcpy(s,*(str+1)); 

strcpy(s,str[2]);//也可写成strcpy(s,*(str+2)); 

上例中,str是一个三单元的数组,该数组的每个单元都是一个指针,这些指针各指向一个字符串。把指
针数组名str当作一个指针的话,它指向数组的第0号单元,它的类型是char**,它指向的类型是char *。

*str也是一个指针,它的类型是char*,它所指向的类型是char,它指向的地址是字符串"Hello,this is
a sample!"的第一个字符的地址,即'H'的地址。

str+1也是一个指针,它指向数组的第1号单元,它的类型是char**,它指向的类型是char *。

*(str+1)也是一个指针,它的类型是char*,它所指向的类型是char,它指向"Hi,good morning."的第一
个字符'H',等等。 

下面总结一下数组的数组名的问题。声明了一个数组TYPE array[n],则数组名称array就有了两重含义:
第一,它代表整个数组,它的类型是TYPE [n];第二,它是一个指针,该指针的类型是TYPE*,该指针指
向的类型是TYPE,也就是数组单元的类型,该指针指向的内存区就是数组第0号单元,该指针自己占有单
独的内存区,注意它和数组第0号单元占据的内存区是不同的。该指针的值是不能修改的,即类似array++
的表达式是错误的。 

在不同的表达式中数组名array可以扮演不同的角色。 

在表达式sizeof(array)中,数组名array代表数组本身,故这时sizeof函数测出的是整个数组的大小。

在表达式*array中,array扮演的是指针,因此这个表达式的结果就是数组第0号单元的值。sizeof
(*array)测出的是数组单元的大小。 

表达式array+n(其中n=0,1,2,....。)中,array扮演的是指针,故array+n的结果是一个指针,它的
类型是TYPE*,它指向的类型是TYPE,它指向数组第n号单元。故sizeof(array+n)测出的是指针类型的大
小。 

例十: 

int array[10]; 

int (*ptr)[10]; 

ptr=&array; 

上例中ptr是一个指针,它的类型是int (*)[10],他指向的类型是int [10],我们用整个数组的首地址来
初始化它。在语句

上一页  [1] [2] [3] [4]  下一页


Tags:语言,眼中,指针
[数据载入中...] [返回上一页] [打 印]