例如,有如下所示的C语句序列:则结构体指针变量p1指向结构体数组元素a[2],其关系如图10.2所示。此时应该注意到被指针变量p1指向的结构体数组元素本身是不能作为整体操作的,所以*p1也不能作为整体操作。......
2023-11-20
void的字面意思是“无类型”,void*则为“无类型指针”,void类型指针(如void*p)所指向的数据类型不是确定的,即可以指向任何类型的数据。但是,这并不意味着void*可以无需强制类型转换就赋给其他类型的指针。例如,下面语句编译出错:
void*p1;
int*p2;
p2=p1;
编译时系统提示:“cannot convert from’void*’to’int*’”。
void类型指针中的数据不能访问,如果非要访问的话,可以通过强制转换将void类型指针转换为与所指向的数据类型相符的类型。
(1)任何类型的指针都可以强制转换为void类型,且不会丢失数据。
例7.6 试分析以下程序的运行结果。
(2)void类型指针可以通过强制转换为具有更小或相同存储对齐限制的指针,但数据可能失真。
所谓“相同存储对齐限制”是指void类型指针所指的数据在内存中所占的长度与显式转换后的指针所指的数据在内存中所占的长度相等(比如以上程序中的p1所指的源数据在内存中占2个字节,p2所指的数据在内存中也是占2个字节)。需要注意的是,只有上面的这种转换(前后指针所指数据类型一致的转换)才能保持数据不失真;如果类型不一致,即使具有相同存储对齐限制,也有可能失真(比如由short转向unsigned short)。(www.chuimin.cn)
例7.7 试分析以下程序的运行结果。
上述程序的输出结果就不再是-5了,因为在指针转换时,short类型的数据也经过转换变成了unsigned short类型的数据,具体的转换过程请参考数据类型转换。不过,也有数值不变的情况(如把a值变为5)。
同理,如果是将void类型转换为具有更小存储对齐限制的指针时,也可能引起数值的改变。
例7.8 试分析以下程序的运行结果。
程序运行后,p1所指向的数据不再是720,而是-48。因为a的值720在内存中的表示形式为D0 02(十六进制表示,共2块,即2个字节),其中D0的地址即a的地址0x0012ff7c,p2只保存0x0012ff7c,不知道它占有2个字节内存空间。而p1所指数据占有1个字节,因此p1只代表D0,无法代表D0 02,将D0翻译成有符号char类型,即-48(D0是补码)。当然,如果将a的值改为较小的数(-128~127)(如3),转换后的值变不会发生改变。
综合以上两种情况,其实void类型指针所指向的数据一直都在内存中存放着,并没有被改动,只是我们在引用时(从内存中提取数据的过程中)发生了提取错误。道理很简单,一个有2个字节组成的数据,而你非要提取1个字节,是有可能发生错误的(但不是一定会发生错误,当一个数据既能用1个字节表示,又能用2个字节表示时就不会产生错误)。如果我们提取正确的话,随时都可以得到正确的数据。例如,将上面的“printf(“%d\n”,*p1)”;改为“printf(“%d\n”,*(short*)p1)”;则又会输出720。
(3)如果将void类型的指针转换为具有更大存储对齐限制的指针时,则会产生无效值。
例7.9 试分析以下程序的运行结果。
有关C语言程序设计 第2版的文章
例如,有如下所示的C语句序列:则结构体指针变量p1指向结构体数组元素a[2],其关系如图10.2所示。此时应该注意到被指针变量p1指向的结构体数组元素本身是不能作为整体操作的,所以*p1也不能作为整体操作。......
2023-11-20
图8.1函数内存映射方式1.指向函数指针变量的定义C语言中可以定义指针变量来存储函数的首地址,并利用该指针变量对函数进行调用。指向函数的指针变量的真正作用是作为函数参数使用,使程序在功能的实现上具有更大的灵活性。指向函数的指针变量求最大值、最小值和两数之和。......
2023-11-20
一个指针变量用来指向一个结构体变量时,称之为结构体指针变量。结构体指针变量中的值是所指向的结构体变量的首地址。有了结构体指针变量,就能方便地访问结构体变量的各个成员。下面通过例子来说明结构体指针变量的具体说明和使用方法。图7.6程序运行结果说明:程序定义了一个结构stu,定义了stu 类型结构体变量boy1,并初始化赋值,还定义了一个指向stu 类型结构的指针变量pstu。......
2023-10-21
当指针变量指向一维数组的首元素时,称为指向了一维数组。所以,函数中一维数组形式参数可以用同类的指针形式参数替代;同理也可以用指向特定数组的指针变量来传递数组类实际参数。特别需要注意的是,函数的形式参数无论使用的是数组名形式还是指针变量形式,本质上都是一个指针变量,在被调函数中既可以将它当作数组名使用也可以将它当作指针变量使用。......
2023-11-20
当一个指针指向一个结构体变量时,称为结构体指针变量。结构体指针变量中的值是所指向的结构变量的首地址,通过结构指针即可访问该结构变量。结构体指针变量定义的一般形式为:struct结构类型名 *结构指针变量名在定义了struct student结构类型后,如要定义一个指向该结构类型的指针变量pstu,可写为:struct student*pstu;当然也可在定义struct student结构类型的同时定义pstu。与前面讨论的各类指针变量相同,结构指针变量也必须要先赋值后使用。......
2023-11-18
一般来说,对于一个n(n>1)级指针变量其内容是存放一个n-1级指针变量的地址。虽然y和z都是指针变量,但它们指向的变量是不同的,显然不能用同一层次的指针变量来表示。图8.5多级指针在存储系统中的关系在C语言中,用指针变量的级别来区分不同层次的指针变量。指向普通变量的称为一级指针变量,指向一级指针变量的称为二级指针变量,以此类推。而且,只要数据类型相同,任意级别的指针变量可以与普通变量、数组等一起定义。......
2023-11-20
从二维数组的角度看,数组名array 代表整个二维数组的首地址,也是第0 行的首地址。所以,&array[i]和array+i 等价,都是指向二维数组的第i 行。array[i]+j 指向二维数组array[i][j]。*就是数组元素 array[i][j]的值。计算 array[i][j]在数组中的相对位置为“i×m+j”,*就是数组array[i][j]的值。使用指针变量输出二维数组任一行任一列元素的值。图6.12程序运行结果说明:在主函数中定义了一个指针变量p,指向数组array 第0 行第0 列。p+是二维数组array 第i 行第j 列的地址。......
2023-10-21
相关推荐