【时时三省】(C语言基础)善于利用指针

发布于:2025-06-21 ⋅ 阅读:(20) ⋅ 点赞:(0)

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省

指针是C语言中的一个重要概念,也是C语言的一个重要特色。正确而灵活地运用它,可以使程序简洁、紧凑、高效。每一个学习和使用C语言的人,都应当深入地学习和掌握指针。可以说,不掌握指针就是没有掌握C的精华。

指针的概念比较复杂,使用也比较灵活,因此初学时常会出错,务请在学习内容时十分小心,多思考、多比较、多上机,在实践中掌握它。

指针是什么

为了说清楚什么是指针,必须先弄清楚数据在内存中是如何存储的,又是如何读取的。

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。例如,VisualC++为整型变量分配4个字节,为单精度浮点型变量分配4个字节,为字符型变量分配1个字节。内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号。

在地址所标志的内存单元中存放的数据则相当于旅馆房间中居住的旅客。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。打个比方,一个房间的门口挂了一个房间号2008,这个2008就是房间的地址,或者说,2008“指向”该房间。因此,将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元。

说明:对计算机存储单元的访问比旅馆要复杂一些,在C语言中,数据是分类型的,对不同类型的数据,在内存中分配的存储单元大小(字节数)和存储方式是不同的(如整数以补码形式存放,实数以指数形式存放)。如果只是指定了地址1010 ,希望从该单元中调出数据,这是做不到的,虽然能找到所指定的存储单元,但是,无法确定是从1个字节中取信息(字符数据),还是从2个字节取信息(短整型),抑或是从4个字节取信息(整型)。也没有说明按何种存储方式存取数据(整数和单精度实数都是4个字节,但存储方式是不同的)。因此,为了有效地存取一个数据,除了需要位置信息外,还需要有该数据的类型信息(如果没有该数据的类型信息,只有位置信息是无法对该数据进行存取的)。C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是“带类型的地址”。如& a,一般称它为“变量a的地址”,确切地说,它是“整型变量a的地址”。后面提到的“地址”,都是这个意思。

请思考:若有int型变量a和float型变量b,如果先后把它们分配在2000开始的存储单元中,& a和& b的信息完全相同吗?答案是不相同的,虽然存储单元的编号相同,但它们的数据类型不同。

请务必弄清楚存储单元的地址和存储单元的内容这两个概念的区别,假设程序已定义了3个整型变量i,j,k,在程序编译时,系统可能分配地址为2000 ~ 2003的4个字节给变量i,2004 ~ 2007的4个字节给j,2008 ~ 2011的4个字节给k(不同的编译系统在不同次的编译中,分配给变量的存储单元的地址是不相同的)。

在程序中一般是通过变量名来引用变量的值,例如:

printf (”% d\n”,i );

由于在编译时,系统已为变量i分配了按整型存储方式的4个字节,并建立了变量名和地址的对应表,因此在执行上面语句时,首先通过变量名找到相应的地址,从该4个字节中按照整型数据的存储方式读出整型变量i的值,然后按十进制整数格式输出。

注意:对变量的访问都是通过地址进行的。假如有输入语句

scanf (”% d”,& i );

在执行时,把键盘输入的值送到地址为2000开始的整型存储单元中。如果有语句

k = i + j;

则则从2000 ~ 2003字节取出i的值( 3 ),再从2004 ~ 2007字节取出j的值( 6 ),将它们相加后再将其和( 9 )送到k所占用的2008 ~ 2011字节单元中。这种直接按变量名进行的访问,称为“直接访问”方式。

还可以采用另一种称为“间接访问”的方式,即将变量i的地址存放在另一变量中,然后通过该变量来找到变量i的地址,从而访问i变量。

在C语言程序中,可以定义整型变量、浮点型(实型)变量、字符变量等,也可以定义一种特殊的变量,用它存放地址。假设定义了一个变量i _ pointer(变量名可任意取),用来存放整型变量的地址。可以通过下面语句将i的地址( 2000 )存放到i _ pointer中。

i _ pointer = & i;/ /将i的地址存放到i _ pointer中

这时,i _ pointer的值就是2000(即变量i所占用单元的起始地址)。

要存取变量i的值,既可以用直接访问的方式,也可以采用间接访问的方式:先找到存放“变量i的地址”的变量i _ pointer,从中取出i的地址( 2000 ),然后到2000字节开始的存储单元中取出i的值( 3 ),。

打个比方,为了开一个A抽屉,有两种办法,一种是将A钥匙带在身上,需要时直接找出该钥匙打开抽屉,取出所需的东西。另一种办法是:为安全起见,将该A钥匙放到另一部量B中锁起来。如果需要打开A抽屉,就需要先找出B钥匙,打开B抽展,取出A钥匙,再打开A抽屉,取出A抽屉中之物,这就是“间接访问”。

为了表示将数值3送到变量中,可以有两种表达方法:

( 1 )将3直接送到变量i所标识的单元中,例如“i = 3;”。

( 2 )将3送到变量i _ pointer所指向的单元(即变量i的存储单元),例如“* i _ pointer = 3;”,其中* i _ pointer表示i _ pointer指向的对象。指向就是通过地址来体现的。

假设i _ pointer中的值是变量i的地址( 2000 ),这样就在i pointer和变量i之间建立起一种联系,即通过i _ pointer能知道i的地址,从而找到变量i的内存单元。

由于通过地址能找到所需的变量单元,因此说,地址指向该变量单元(如同说,一个房间号“指向”某一房间一样)。将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元(如同根据地址2000就能找到变量i的存储单元一样)。

如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”。上述的ipointer就是一个指针变量。指针变量就是地址变量,用来存放地址,指针变量的值是地址(即指针)。

注意:区分“指针”和“指针变量”这两个概念。例如,可以说变量i的指针是2000,而不能说i的指针变量是2000。指针是一个地址,而指针变量是存放地址的变量。

 

 


网站公告

今日签到

点亮在社区的每一天
去签到