sizet这个类型的意义是什么?
类型名称不直观,从sizet这个名字很难理解它的用处,使用时候还要特别留意是unsigned类型,而且在数数的时候可以用int或者unsigned代替。这种类型的优势在哪里?
1。学过计算机组成原理应该不会对此有疑问。int小于等于数据线宽度,sizet大于等于地址线宽度。sizet存在的最大原因可能是因为:地址线宽度历史中经常都是大于数据线宽度的。在数据只有8位的年代,地址率先进入10位,12位,在数据16位的年代,地址也已经进入了20位,24位。目前的int普遍是32位,而sizet在主流平台中都是64位。sizet为什么存在?因为无论int还是unsigned都很可能小于sizet需要的大小,所以必须有个sizet。
补充:据说题主对t有疑惑。这个问题很简单,仅仅是因为作者选择这样的命名作为编码规范而已。类型名与变量名共享相同的命名空间,所以通常需要在命名方面刻意区分出来。在遥远的C时代,发明者很可能是想建议所有的类型名后面加t,只不过这并没有成为更普遍的编码规范罢了。而现今Java的规范倒比较容易让人接受:大写开头的是类型名,小写开头的是变量名跟函数名,虽然具体细则有不同,但原意都是一样的:变量与类型共享同一个命名空间,因而需要在命名规则上刻意区分开来。
2。之前在《内存拷贝的注意事项》一文中提到过sizet,可能许多人对这个类型不太熟悉没有用过或者根本不敢去用,最近看到一篇文章对这个类型讲的比较详细,便翻译过来让不熟悉的同学可以知道它产生的原因以及如何使用。
前言:使用sizet可能会提高代码的可移植性、有效性或者可读性,或许同时提高这三者。在标准C库中的许多函数使用的参数或者返回值都是表示的用字节表示的对象大小,比如说malloc(n)函数的参数n指明了需要申请的空间大小,还有memcpy(s1,s2,n)的最后一个参数,表明需要复制的内存大小,strlen(s)函数的返回值表明了以’’结尾的字符串的长度(不包括’’),其返回值并不是该字符串的实际长度,因为要去掉’’。或许你会认为这些参数或者返回值应该被申明为int类型(或者long或者unsigned),但是事实上并不是。C标准中将他们定义为sizet。标准中记载malloc的申明应该出现在,
定义为:voidmalloc(sizetn);memcpy和strlen的申明应该出现在中:voidmemcpy(voids1,voidconsts2,sizetn);
sizetstrlen(charconsts)sizet还经常出现在C标准库中,此外,C库中经常会使用一个相似的类型sizetype,用的可能比sizet还要多。
据我所知,大部分的C和C程序员害怕这些库使用sizet,因为他们不知道sizet代表什么或者为什么这些库需要使用它,归根结底,原因在于他们什么时候什么地方需要用到它。
可移植性问题早期的C语言(由BrianKernighan和DennisRitchie在TheCProgrammingLanguage书中所写,PrenticeHall,1978)并没有提供sizet类型,C标准委员会为了解决移植性问题将sizet引入,举例如下:让我们来写一个可移植的标准memcpy函数,我们将会看到一些不同的申明和它们在不同平台不同大小的地址空间上编译下的情况。回忆memcpy(s1,s2,n)函数,它将s2指向地址开始的n个字节拷贝到s2指向的地址,返回s1,这个函数可以拷贝任何数据类型,所以参数和返回值的类型应该为可以指向任何类型的void,同时,源地址不应该被改变,所以第二个参数s2类型应该为constvoid,这些都不是问题。真正的问题在于我们如何申明第三个参数,它代表了源对象的大小,我相信大部分程序员都会选择int:voidmemcpy(voids1,voidconsts2,intn);使用int类型在大部分情况下都是可以的,但是并不是所有情况下都可以。int是有符号的,它可以表示负数,但是,大小不可能是复数。所以我们可以使用unsignedint代替它让第三个参数表示的范围更大。在大部分机器上,unsignedint的最大值要比int的最大值大两倍,比如说再也给16位的机器上,unsignedint的最大值为65535,int的最大值为32767。尽管int类型的大小依赖于C编译器的实现,但是在给定的平台上int对象的大小和unsignedint对象的大小是一样的。
因此,使用unsignedint修饰第三个参数的代价与int是相同的:voidmemcpy(voids1,voidconsts2,unsignedintn);这样似乎没有问题了,unsignedint可以表示最大类型的对象大小了,这种情况只有在整形和指针类型具有相同大小的情况下,比如说在IP16中,整形和指针都占2个字节(16位),而在IP32上面,整形和指针都占4个字节(32位)。(参见下面C数据模型表示法)
C数据模型表示法最近,我偶然发现几篇文章,他们使用简明的标记来表述不同目标平台下c语言数据的实现。我还没有找到这个标记的来源,正式的语法,甚至连名字都没有,但他似乎很简单,即使没有正规的定义也可以很容易使用起来。这些标记的一边形式形如:InILnLLLnLLPnP。其中每个大写字母(或成对出现)代表一个C的数据类型,每一个对应的n是这个类型包含的位数。I代表int,L代表long,LL代表longlong,以及P代表指针(指向数据,而不是函数)。每个字母和数字都是可选的。例如,I16P32架构支持16位int和32位指针类型,没有指明是否支持long或者longlong。如果两个连续的类型具有相同的大小,通常省略第一个数字。例如,你可以将I16L32P32写为I16LP32,这是一个支持16位int,32位long,和32位指针的架构。标记通常把字母分类在一起,所以可以按照其对应的数字升序排列。例如,IL32LL64P32表示支持32位int,32位long,64位longlong和32位指针的架构;然而,通常写作ILP32LL64。不幸的是,这种memcpy的申明在I16LP32架构上(整形是16bit长整形和指针类型时32bits)显得不够用了,比如说摩托罗拉第一代处理器68000,在这种情况下,处理器可能拷贝的数据大于65535个字节,但是这个函数第三个参数n不能处理这么大的数据。
什么?你说很容易就可以改正?只需要把memcpy的第三个参数的类型修改一下:voidmemcpy(voids1,voidconsts2,unsignedlongn);你可以在I16LP32目标架构上使用这个函数了,它可以处理更大的数据。而且在IP16和IP32平台上效果也还行,说明它确实给出了memcpy的一种移植性较好的申明。但是,在IP16平台上相比于使用unsignedint,你使用unsignedlong可能会使你的代码运行效率大打折扣(代码量变大而且运行变慢)。在标准C中规定,长整形(无论无符号或者有符号)至少占用32位,因此在IP16平台上支持标准C的话,那么它一定是IP16L32平台。这些平台通常使用一对16位的字来实现32位的长整形。在这种情况下,移动一个长整形需要两条机器指令,每条移动一个16位的块。事实上,这个平台上的大部分的32位操作都需要至上两条指令。因此,以可移植性为名将memcpy的第三个参数申明为unsignedlong而降低某些平台的性能是我们所不希望看到的。使用sizet可以有效避免这种情况。sizet类型是一个类型定义,通常将一些无符号的整形定义为sizet,比如说unsignedint或者unsignedlong,甚至unsignedlonglong。每一个标准C实现应该选择足够大的无符号整形来代表该平台上最大可能出现的对象大小。使用sizetsizet的定义在stddef。h,stdio。h,stdlib。h,string。h,time。h和wchar。h这些标准C头文件中,也出现在相应的C头文件,等等中,你应该在你的头文件中至少包含一个这样的头文件在使用sizet之前。包含以上任何C头文件(由C或C编译的程序)表明将sizet作为全局关键字。包含以上任何C头文件(当你只能在C中做某种操作时)表明将sizet作为std命名空间的成员。根据定义,sizet是sizeof关键字(注:sizeof是关键字,并非运算符)运算结果的类型。所以,应当通过适当的方式声明n来完成赋值:nsizeof(thing);考虑到可移植性和程序效率,n应该被申明为sizet类型。类似的,下面的foo函数的参数也应当被申明为sizeof:foo(sizeof(thing));参数中带有sizet的函数通常会含有局部变量用来对数组的大小或者索引进行计算,在这种情况下,sizet是个不错的选择。适当地使用sizet还会使你的代码变得如同自带文档。当你看到一个对象声明为sizet类型,你马上就知道它代表字节大小或数组索引,而不是错误代码或者是一个普通的算术值。
3。izet和unsignedint有所不同,sizet的取值range是目标平台下最大可能的数组尺寸,一些平台下sizet的范围小于int的正数范围,又或者大于unsignedint。最典型的,在x64下,int还是4,但sizet是8。这意味着你在x64下最大可能开辟的数组尺寸是264。如果你使用int或者unsignedint,那么在x64下如果你的代码中全部使用uint作为数组的尺寸标记,那么你就会失去控制232尺寸以上的数组的机会。虽然现在在x64上开辟一个大于232大小的连续数组依然是个不大可能的事情,但是。。。。。。。。。。
640K内存对于任何人来说都足够了比尔盖茨
AMD锐龙处理器性能超intel为什么大家还是选英特尔CPU我前两年是一名业余的装机爱好者,经过这两年的经历,我是有点明白为什么很多人还是选择英特尔的。原来自己特别喜欢动手,然后通过买二手的E31230V2搭配B75主板,然后自己……
赚钱软件,是欺骗还是虚假宣传?随着互联网的飞速崛起,手机成为了人们的主体,电视电脑都很少看,它们拥有的的功能都在手机上,可以解决。曾经在电视上插播的广告,现在出现到了手机上,这样打开手机,不管在什么地……
一出手便斩获第一?五小时续航测试,iPhone13ProMa近日,小白测评发布了一份新版的五小时重度续航测试榜单。其中,iPhone13ProMax在经过一系列测试后,剩余电量还有35,不仅轻松拿下了榜单第一,而且比第二名的剩余电量足足……
重拾青春回忆OPPOReno6Pro名侦探柯南限定版开售联名,似乎已经不再是一件什么新鲜事。但这次OPPO与名侦探柯南的联名,却让我大呼一声爷青回!首先映入眼帘的便是硕大的毛利侦探事务所,作为剧中最为标志性的建筑物此次成为了这……
2亿像素144Hz刷新率,8256G卖4299,骁龙888旗目前手机市场上除了一些有名气的手机品牌外,还有一些我们不怎么熟悉的手机也步入我们的生活中。越来越多的消费者开始使用手机作为日常必备的摄影工具,出色的摄影技术也成为众多消费者选购……
数字经济之光,愈发明亮数读浙江丨数字经济之光,愈发明亮2021年的乌镇时间,如约开启。自2014年深秋起,全球互联网精英每年聚首乌镇,轻叩石板路,畅聊互联网,共襄一场世界互联网的盛会。从……
诺基亚N82022款渲染图曝光再现昔日经典,蔡司四摄堪比小单导读:诺基亚N82022款渲染图曝光:再现昔日经典,蔡司四摄堪比小单反相信大家很久都没有看到诺基亚的消息了,曾经的诺基亚还是王者,现在已经跌到了青铜,每年依然在更新迭代的……
竞争力十足,三款高颜值高性价比的旗舰手机红米K40在外观设计方面,功能K40采用了挖孔全面屏的设计,挖孔设计在屏幕顶部的中间区域,再加上极窄的黑边处理,因此整个手机正面视觉颜值相当的给力,屏占比也有十分突出的表……
如何实现两台电视机共享一个机顶盒?很多时候家庭宽带只安装一个机顶盒连接一个电视,如果家中两台电视那么需要增加一个机顶盒,并绑定相应的账号,交月租才能使用。题主在问题中询问如何实现两台电视共享一个机顶盒。根据机顶……
录音笔功能具备哪些呢?录音笔日常保养要怎么做?那么录音笔功能具备哪些呢?功能1、可以声控设计和自动录音;功能2、可以支持MP3播放;功能3、可以调频;。。。能10、可以拍摄。如果录音机的功能只是录音,MP3或者MP4……
我们对国产电动车要有自信相比传统的烧油的汽车,国产电动车确实更有可能实现弯道超车。就好比以前的手机,关键技术都被诺基亚、摩托罗拉这些国外大牌掌控。但是,到了智能手机时代,华为、OV、小米这……
有实用的软件推荐吗?一些好的软件可以很好的帮助我们提升工作效率,节约时间。今天给大家推荐八款Windows软件,每一个都是精品。一、uTools一个可以帮你提高生产率的工具uTools……