关于C语言指针类型 强制转换  引用一篇文章:

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

例如,定义如下:

int a;

float b;

double c;

long double d;

(假设它们所占的字节分别是4、8、8、10,而且连续存储于某个地址空间,起始地址是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;

则p和p1的值都是&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]

在贴 下面一段代码:

#include <stdio.h>typedef struct stu1{char chs[5];
};
typedef struct stu2{char chs[4];int  n;
};int main(int argc, char const *argv[]){struct stu1 s1;struct stu2 s2;s1.chs[0] = 'a';s1.chs[1] = 'b';s1.chs[2] = 'c';s1.chs[3] = 'd';s1.chs[4] = 'e';s2 = *((struct stu2 *)&s1);printf("%c\n", s1.chs[3]);printf("%d\n", s2.n);return 0;
}

结果输出:

1 d
2 101

所有类型 都系统底层的本质都是一样的 都是内存中的 0 1组成。基本强制类型转换就是  把高出的 部分 位  截取掉。int型数值赋给char型变量时,只保留其最低8位,高位部分舍弃

在看一段代码:

 1 #include <stdio.h>2 3 4 typedef struct stu1{5     int m;6     int n;7 };8 typedef struct stu2{9     char c1;
10     char c2;
11 };
12 int main(int argc, char const *argv[]){
13     struct stu1 s1;
14     struct stu2 s2;
15     s1.m = 815;  //11 00101111
16     s1.n = 600;
17     s2 = *((struct stu2 *)&s1);
18     printf("%d, %d, \n", s2.c1, s2.c2);
19     int a = 559; //10 00101111
20     char c = (char)a;
21     printf("%d\n", c);
22     s1.m = 559;
23     s2 = *((struct stu2 *)&s1);
24     printf("%d, %d, \n", s2.c1, s2.c2);
25     return 0;
26 }

输出结果:

47, 3,
47
47, 2,

上面代码中 stu1结构体的大小为 4个字节 ,而stu2结构体的大小为 2个字节 ,所以stu1转换为stu2的时候,只保留 前面2 个字节。s1.m 为 int 类型 s2.ch1 为 char 类型,前面说过 int型数值赋给char型变量时,只保留其最低8位,高位部分舍弃

我们可以看出 815  和 559  的 后(低)八位(一个字节) 都是一样的 47。剩余一个字节(s1.m的高八位) 在赋值给 s2.ch2  815和 559的高八位  不一样 所以输出的结果也不一样。

C语言 指针之间的 强制转换 就是 其指针所指内容之间的 强制转换。一个字节  一个字节之间的转换。多出的部分截取掉。

转载于:https://www.cnblogs.com/piterzhang/p/8977091.html

C语言指针类型 强制转换相关推荐

  1. c语言 void**类型转换,void指针类型强制转换

    如何将一个void*强制转换成行指针类型? void*指针可以转换成任何类型的指针. 强制转换即可,比如 (int *)(void *)p; 假设你的数组有N行M列的int型数据. int arr[N ...

  2. 浅谈c语言指针的强制转换

    指针是c语言的灵魂,而数据的强制转换是我们在写程序的过程中经常去使用的一种手段,那么这二者结合在一起后会有什么效果呢? 直接上例子说吧 No.1 上面是一段简单的把变量打印出来的程序,显示指针指向地址 ...

  3. C语言程序——类型强制转换

    文章目录 前言 一.类型强制转换 二.程序实例 代码如下 运行结果 结果分析 总结 前言 强制类型转换的作用就是将表达式的类型转换为类型名指定的数据类型. 一.类型强制转换 表达式进行强制转换的格式为 ...

  4. c语言const类型强制转换,关于C++的强制类型转换浅析

    前言 一说起强制类型转换大家都很熟悉,相信很多学习完C++的朋友还在使用C语言的强制类型的方式 (类型)变量. C++其实也具有自己的一套强制类型转换它们分明是:static_cast  reinte ...

  5. c语言指针的强制类型转换,c语言指针的强制转换

    在c语言中经常看到以下类似的代码: int x = 1; (char*)&x; 这样的形式的代码,这个里面就涉及一个类型转换的问题. 以下是在VC6.0中调试的结果 代码: int main( ...

  6. C++中指针的强制转换

    转自:https://blog.csdn.net/u012273127/article/details/53260978 其又转自:http://blog.csdn.net/mhjcumt/artic ...

  7. c语言地址强制转为指针,C语言:指针类型强制性转换

    C语言:指针类型强制性转换 标签:C语言 指针 强制性转换 by 小威威 1.引入 我们知道,每个变量都有对应的地址,地址的距离即为地址之差.然而,地址类型不同,也就不能进行减法运算.假如,我现在要求 ...

  8. Go 学习笔记(32)— 类型系统(命名类型、未命名类型、底层类型、类型强制转换、类型别名和新声明类型)

    1. 命名类型和未命名类型 1.1 命名类型 类型可以通过标识符来表示,这种类型称为命名类型( Named Type ). Go 语言的基本类型中有 20 个预声明简单类型都是命名类型, Go 语言还 ...

  9. C++的类型强制转换,static_cast,dynamic_cast,const_cast,reinterpret_cast

    1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1type-id(expression)//转换格式2 ...

最新文章

  1. java 大数据处理一
  2. 简明python教程txt-Python新手的数据批量处理教程(TXT文件)
  3. mybatis教程--一对多查询
  4. Hdu 1283 钱币兑换问题
  5. 天谕手游与奥特曼联手,玩家看到有多么激动?
  6. html所有页面根的对象,在django中显示来自所有用户的对象,无需登录到html页面...
  7. scala学习笔记-集合操作(15)
  8. C++使用Json作为数据包装格式的通信
  9. 汉语言文学专业c学校,哪个学校汉语言文学专业最好?有哪些录取要求最低分数线是多少?...
  10. java web 教程_Java Web服务教程
  11. java枚举类型详解
  12. 中国2017 Google 开发者大会第二天简单回顾
  13. 播布客视频-Auditing笔记
  14. word插入分页符后在下一页开始出现一个回车符,这个回车符如何删掉,但不影响分页
  15. 浏览器内核 css浏览器的兼容性写法
  16. 推荐综述博客网址马克
  17. python基础数据类型
  18. 规范升级 NPM 包
  19. Exploit Development – 使用SEH绕过Security Cookie
  20. 咔咕图聊!超级酷!让QQ文字立刻变图片!

热门文章

  1. java表格模糊查询_使用java图形报表时,如何进行模糊查询
  2. 计算机视觉专硕:OCR、实习和秋招
  3. php 设置跨域axios,vue2.0中proxyTable用axios进行跨域请求的设置方法
  4. python pandas教程pdf_学习python中的pandas有没有好的教程推荐?
  5. 《MFC游戏开发》笔记七 游戏特效的实现(一):背景滚动
  6. Ubuntu gitweb 安装配置
  7. Windows 8 Directx 开发学习笔记(六)添加水模型
  8. 用唯一的颜色id编号实现OpenGL选择功能(OpenGL Selection Using Unique Color IDs )
  9. eclipse-java-2018-09-win32-x86_64配置tomcat(内含更新eclipse,如何解决添加时找不到最新tomcat版本)...
  10. 全图化引擎(AI·OS)中的编译技术