C语言中的指针为什么要区别出指向不同数据指向不完整类型的指针针

57680人阅读
C语言 学习历程(7)
C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值。不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的一种记住这个地址的方便一点的方法。但是,不同的变量在机器中都是0-1代码,所以,我们不能简单的通过检查一个值的位来判断它的类型。
例如,定义如下:
(假设它们所占的字节分别是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 *pm = &m;
char *cp = (char *)&m;
pm指向一个整型,cp指向整型数的第一个字节
2、结构体之间的强制转换
struct str1
struct str2
a=(struct str1) & & & & & & & & &//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 和
式子&a+1表示的是指针加法运算,而不是普通的数值加法运算
vs2008下,其中a = 0x001bfc18
(&a + 1) = 0x001bfc28
而 a+1 = 0x001bfc1c
&&a + 1 的值取决于a的类型如果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]
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:147998次
排名:千里之外
原创:10篇
评论:14条
(3)(2)(5)(5)(3)君,已阅读到文档的结尾了呢~~
指针是C语言中广泛使用的一种数据类型运用指针编程是C...99豆丁精品
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
【精品】指针是C语言中广泛使用的一种数据类型运用指针编程是C...99
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口指针的类型与指针所指向的类型是否一定要相同呢?_c语言吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:518,340贴子:
指针的类型与指针所指向的类型是否一定要相同呢?收藏
网上查了很多资料,越看越糊涂,哪个师傅给我讲讲啊?谢谢
c语言海同强大的师资阵容,因人制定课程内容,分阶段学习.c语言就到正规IT技术培训机构-海同科技,培训IT技术面对面教学,免费重读!
如果一定是相同的,那么void*咋办捏~
一定要相同。但void是特别的,它可以指向所有类型。
可以不相同。如;p="asd"; 字符串,常量。p=&a;变量;
我想变量和常量是两个不同的类型吧,我是这么看的。换个个例子;int a[],p=a; 整形的派生类。p=&i;整形
可以不相同,类型不同,偏移量就不同。int *a= int b[5]={1,2,3}那么a[2]是3,char *c= b;那么c[2]是0;
注意一元&运算符返回的是带类型的,以及不同的对象指针之间不能隐式转换。
要保持一致 可以有限的使用不一致的指针 但是 对情况不够了解有时候会出现破坏严格别名的情况麻烦
可以,我觉得强转换没有意义吧。像一个东西换了名字但是东西没变。。
我想类型必须从数据上进行划分是正确的,但也必须考虑到历史和实现。无符号的有符号的char *p;p = &p = &我想这明显是两个不同的类型,但是无区别对待。p =p =这两个对象相同的类型,但不被认同。我想划分类型只有一个标准,那就是“从数据属性上分类”。而 c 有多个划分标准,所以一个对象和一个值是什么?只有编译器知道。
达内c语言培训,0基础从入门到精通120天,先就业后付款,签订c语言就业协议,c语言培训优选达内,不就业免费重学,70000家名企联合招聘!
应该先考虑这个问题什么不给void型变量!
你居然指望一个weakly typed的语言来帮你保证类型安全?
顶一个——————许多年前,我有过这样一个手机,它只能存储200条短信,里面装的是满满的回忆,每当存满了,都要精挑细选的删掉一些,留住她的,当时真的好想要一个能存500条短信的手机,而如今,我有了一个可以无限量存储短信的手机,但却再也找不到那个能和我聊200条短信的人...      
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或C和C++中指针和地址的区别
C和C++中指针和地址的区别
  在C语言和C++中,指针是非常重要的一部分,程序的执行过程中可以通过指针来找到要操作的数据和可执行的函数代码。很多人就明白指针和地址是有区别的,但是很少有人能说清楚这种区别。
  指针总共可以分为两种,函数指针和数据指针。而指针和地址最大的区别就是指针是有类型的,地址是没有类型的。我们当然可以通过绝对地址的方式找到函数和数据,但是地址是没有类型的,不能对地址进行算术操作,在涉及诸如数组等操作时就不能通过地址的自增和自减来访问数组的各个变量。但是通过对指针的引用,就可以通过对指针进行一系列的加加减减操作很方便的访问数组的各个元素。
  所以,指针是由地址和类型两部分构成的,指向数据的指针不仅记录该数据的在内存中的存放的地址,还记录该数据的类型,即在内存中占用几个字节,这是地址所不具有的。指向函数的指针不仅记录函数的入口地址,也记录该函数的类型,即函数的返回值类型和该函数的参数类型。
  在C++中还有一种特殊的数据类型,那就是对象,这是一种用户自定义的数据类型。它即包含了数据,又包含了函数。但是在同一个类模板声明的对象变量各自拥有一份数据成员,却共享一份函数成员,因为对有共同类模板的对象来说,他们的数据成员可能不同,但是他们的用来处理数据的函数代码确是相同的,所以他们共享一份成员函数。而此时,对象的指针指向的各自的数据成员。
  指针的使用一定要特别小心,千万不能越界,否则会出现意想不到的结果。而且一定不要使用未初始化过的指针,这样将会访问到位置的内存,有可能会给操作系统带来毁灭性的灾难,虽然健壮的操作系统一般不会允许这么做。
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
职称考试题目
招生信息考研政治
网络安全安全设置工具使用手机安全
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&

我要回帖

更多关于 指向不完全类型的指针 的文章

 

随机推荐