C语言指针强制类型转换

简介:

C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值。不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的一种记住这个地址的方便一点的方法。但是,不同的变量在机器中都是0-1代码,所以,我们不能简单的通过检查一个值的位来判断它的类型。

例如,定义如下:

int a;

float b;

double c;

long double d;

(假设它们所占的字节分别是48810,而且连续存储于某个地址空间,起始地址是100,则我们可以得到如下内存分布)

a变量就是由以地址100开始到103结束的4个字节内存空间内的0-1代码组成。b变量则是由以地址104开始到112结束的8个字节内存空间内的0-1代码组成。而在机器中,这些内存都是连续的0-1代码,机器并不知道100~103是整型而104~111是float型,所有这些类型都是编译器告知的。当我们用a时,由于前面把a定义为int型,则编译器知道从a的地址开始向后取4个字节再把它解释成int型。那么(float)a,就是先按照int类型取出该数值,再将该数值按照int to float的规则转换成float型。所以强制类型转换就是按照某个变量的类型取出该变量的值,再按照***to***的规则进行强制转转换。如果是(类型名)常数,则是将该常数按照常数to类型 的规则进行强制转换。

指针也是一个变量,它自己占据一个4个字节的地址空间(由于程序的寻址空间是2^32次方,即4GB,所以用4个字节表示指针就已经能指向任何程序能够寻址到的空间了,所以指针的大小为4字节),他的值是另一个东西的地址,这个东西可以是普通变量,结构体,还可以是个函数等等。由于,指针的大小是4字节,所以,我们可以将指针强制转换成int型或者其他类型。同样,我们也可以将任何一个常数转换成int型再赋值给指针。所有的指针所占的空间大小都是4字节,他们只是声明的类型不同,他们的值都是地址指向某个东西,他们对于机器来说没有本质差别,他们之间可以进行强制类型转换。
指针 to 指针的强制类型转换是指将指针所指的内容的类型由原先的类型转换为后面的类型。

int a = 1;

int *p = &a;

float *p1 = (float*)p;

pp1的值都是&a,但是*p是将&a地址中的值按照int型变量进行解释,而*p1则是将&a地址中的值按照float型变量进行解释。


鉴于指针之间这种灵活的强制类型转换的需求和出于简化代码的考虑,ANSI C引入了空指针即void*void指针又名万能指针,在现在的很多程序中,当参数不确定时就用万能指针代替,这一类的指针在线程\进程函数里特别常见。

ANSI C规定,void指针可以复制给其他任意类型的指针,其他任意类型的指针也可以复制给void指针,他们之间复制不需要强制类型转换。当然任何地址也可以复制给void型指针。我们在《网络编程》中经常会看到accept(socket, (struct sockaddr *)&saddr_c, &lenth)之类的语句在&saddr_c之前需要增加代码(struct sockaddr *)是因为当此函数被设计的时候ANSI C还没有提出void*的概念。所有的地址统一用struct sockaddr类型标识,该函数的第二个参数也是指向struct sockaddr类型的指针,此处是强制类型转换。

当然,在某些编译器中不同类型的指针也可以进行直接赋值,但一般情况下会给出类型不匹配的警告。要求程序员显示的给出指针强制类型转换可以提醒程序员小心使用指针,对于明确程序目的具有一定的好处。

1、指针类型强制转换:

int m;

int *pm = &m;

char *cp = (char *)&m;

pm指向一个整型,cp指向整型数的第一个字节


2、结构体之间的强制转换

struct str1 a;


struct str2 b;

a=(struct str1) b;                  //this is wrong

a=*((struct str1*)&b);         //this is correct



3、关于一个程序的解释


int main(void)

{

   int a[4] = {1, 2, 3, 4};

   int *ptr1=(int *)(&a+1);

   int *ptr2=(int *)((int)a+1);

   int *c = *(a + 1);

   printf("%x, %x,%x\n", ptr1[-1], *ptr2,*c);

   return 0;

}

输出分别为4 和2000000,2


式子&a+1表示的是指针加法运算,而不是普通的数值加法运算

vs2008下,其中a = 0x001bfc18
(&a + 1) = 0x001bfc28
而 a+1 = 0x001bfc1c

&a + 1 的值取决于a的类型如果a申明int a;
则&a + 1 = 0xFFFF5704  = a + 1
如果 int a(ArryLen);
则&a + 1 = 0xFFFF5700 + 4 * ArryLen <> a + 1

a 表示数组的起始地址,(int ) a 表示将a的地址转化为一个整形数,(int)a + 1 表示普通的数值加法运算,(int *)((int)a + 1)表示把(int )a + 1转化为整型指针的地址。该地址指向数组a(0)的第一个字节(从0计数),因为是int型的 所以需要四个字节的解释,所以结果是a(0)的后三个字节和a(1)的第一个字节组成的值,该值受大小端的影响。

*(a + 1)  此时的a已经是一个常指针了,这个表达式计算出a所指向元素后面的第2个元素的地址,然后对它解引用得到相应的值。这个表达式等价于

int last = a[1]


出处:http://blog.csdn.net/mhjcumt/article/details/7355127


相关文章
|
11月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
186 1
|
7月前
|
存储 人工智能 Java
一文轻松拿捏C语言的指针的基础使用
本文介绍了C语言中的指针概念,包括直接访问和间接访问内存的方式、指针变量的定义与使用、取址运算符`&`和取值运算符`*`的应用,帮助读者深入理解指针这一C语言的核心概念。君志所向,一往无前!
136 0
|
9月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
300 7
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
9月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
1080 9
|
9月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
264 7
|
10月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
834 13
|
10月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
303 11
|
10月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
10月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
10月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
592 3