Advertisement

花了两天时间好好研究了一下size_t究竟是个什么东西

阅读量:

嗨,你好啊,初次见面,下面这些学习资料送给你,要一个关注不过分吧~ ,还想学什么留言或者悄悄跟我私信,咱们细细道来

百本图灵计算机经典系列书籍全送了👇祝你学途永无止境,历经千帆,归来年薪百万!
链接:https://pan.baidu.com/s/1mDGCIgH1s7dSD1uZ6Pml1Q
提取码:hvr0

b站爬取的学习资源整理送了👇祝你成功!
链接:https://pan.baidu.com/s/184suePB-CJEbpAVWqpWIrg
提取码:0emq

数学建模资料,包含数学建模入门与进阶,数学建模经典算法,近10年优秀得奖论文,祝您旗开得胜!
链接:https://pan.baidu.com/s/1HZlnNDeYgu5-EZOxgrzECQ
提取码:svyg


先说结论:

size _t 为了增强程序的可移植性而出现。使用size_t可以提高代码的可移植性、有效性或者可读性,或者同时提高这三者。


size _t是什么,来自哪里

大部分的C和C++程序员都不曾甚至害怕使用size_t,因为他们不知道size_t代表什么或者为什么这些库需要使用它,
归根结底
原因在于他们不知道它是什么
不知道什么时候什么地方需要用到它。

实际上,
size_t的出现远比我们想象中要频繁:
1、malloc(n) 函数的参数n指明了需要申请的空间大小;
2、memcpy(s1, s2, n)的最后一个参数,表明需要复制的内存大小;
3、strlen(s)函数的返回值;
在C标准中将他们都被定义成size_t:

复制代码
    void *malloc(size_t n);//malloc函数定义
    void *memcpy(void *s1, void const *s2, size_t n);//memcpy函数定义
    size_t strlen(char const *s);//strlen函数定义

C++库中经常会使用一个和size _t 相似的类型size_type,用的可能比size_t用的还要多。

经测试发现,在32位系统中size_t是4字节的,在64位系统中,size_t是8字节的,这样利用该类型可以增加程序移植性。在不同系统中不同的大小,这也正是size_t的秘密所在。

size_t定义在/usr/include/linux/types.h

复制代码
    typedef _kernel_size_t size_t;

而__kernel_size_t 定义在 /usr/include/asm/posix_types.h 安装的是内核的源码

复制代码
    asm-i386/posix_types.h
    		typedef unsigned int __kernel_size_t;
    asm-1a64/posix_types.h
    		typedef unsigned long kernel_size_t;

它是一种“整型”类型,里面保存的是一个整数,就像int, long那样。这种整数用来记录一个大小(size)。size_t 的全称应该是size type,就是说“一种用来记录大小的数据类型”。通常我们用sizeof(XXX)操作,这个操作所得到的结果就是size_t类型。

_t的意思就是type。关于为什么要加_t。一个类型后面加了_t说明了这是一个POSIXGNU保留类型,防止命名空间污染(namespace pollution)。以防止标准库里新加了的类型和用户已经定义的类型重名。这样只要用户定义类型的时候不加_t就不会冲突。


为什么需要size_t

size_t不就是unsigned int 类型嘛,直接用unsigned int 不好吗?

首先声明size_t的功能:保证在程序运行中可以表示所有内存地址

size_t根据具体机器的体系结构,会有不同的值。
比如,32位系统,内存最大是2 32 bytes=4G。那么size_t就需要至少4个字节(32bits)来表示所有地址。

unsigned int不是也是4个字节吗?
有些系统是。

unsigned int大小是固定的,而size_t大小取决于计算机体系结构

为了保证在一些有着特殊体系结构的机器上正确运行,使用unsigned int来表示内存数据块大小可能是一个不好的主意。

1、比如,一个机器支持16bit的unsigned int,但他是一个32位系统,使用unsigned int代替size_t显然并不是一个好主意。

2、假如出现一个特别特别大的数组,unsigned int可能将无法表示出这个数组所有的元素。

那么,是否可以使用unsigned long来代替呢?毕竟,long一定需要至少32bits,long也是固定的,那么,对于那些只有16位的平台,这些平台往往使用两个16bits的字来对应一个long,在对long进行操作时,一定需要至少两条操作指令,这大大降低了程序的执行效率。而在这个系统中,并不需要32bits的地址,因为他只有16位。

要为了兼容而舍弃性能吗?显然有更好的解决方案 :那就是根据地址总线个数来决定一个类型的大小,既不会无法表示一些数据,又不会使一些机器效率折损。这个类型就是size_t

size_t的存在使得程序有更好的可移植性,显而易见,程序员不需要为了一个新机器而在unsigned intunsigned char等等类型之间改来改去。


size_t的使用

正如上述,size_t可以表示内存中的所有数据,因为它刚好能够表示内存中所有的地址。

根据定义,size_tsizeof关键字(注:sizeof是关键字,并非运算符)运算结果的类型。所以,应当通过适当的方式声明n来完成赋值:

复制代码
    size_t n = sizeof(int)

考虑到可移植性和程序效率,n应该被申明为size_t类型。类似的,下面的foo函数的参数也应当被申明为sizeof

复制代码
    foo(sizeof(thing));

正因为size_t是一种用来记录大小的数据类型,所以参数中带有size_t的函数通常会含有局部变量用来对数组的大小或者索引进行计算。

适当地使用size_t还会使你的代码变得如同自带文档。当你看到一个对象声明为size_t类型,你马上就知道它代表字节大小或数组索引,而不是错误代码或者是一个普通的算术值。

size_t在标准C头文件<stddef.h>, <stdio.h>, <stdlib.h>, <string.h>, <time.h><wchar.h>这些中定义,也出现在相应的C++头文件,所以在你使用size_t之前你的头文件中至少包含一个这样的头文件。

注:
包含以上任何C头文件(由C或C++编译的程序)表明将size_t作为全局关键字
包含以上任何C++头文件(当你只能在C++中做某种操作时)表明将size_t作为std命名空间的成员

参考资料:
https://www.cnblogs.com/li-hao/archive/2013/02/27/2935100.html
https://www.cnblogs.com/litifeng/p/7464307.html


百本图灵计算机经典系列书籍全送了👇祝你学途永无止境,历经千帆,归来年薪百万
链接:https://pan.baidu.com/s/1mDGCIgH1s7dSD1uZ6Pml1Q
提取码:hvr0

全部评论 (0)

还没有任何评论哟~