从一个用printf输出size_t类型数据的warning想到

最近写代码,想输出一个vecotr类型的变量容器的大小,用c++写的话很简单,比如:

vector<int> vec;

//vec.push_back() ......

cout<<"size is: "<<vec.size()<<endl;

但是今天突发奇想的用C的printf输出,有遇到比较有意思的问题了,我一开始这么写:

printf("size if %d\n", vec.size()) ; // warning vec.size() is of type size_t

于是我想到貌似这个是无符号整形,那么这么改:

printf("size if %u\n", vec.size()) ; // warning vec.size() is of type size_t

还是同样的warning, 这下奇怪了,于是查资料,发现其实size_t这个类型是一个长整形,于是改成

printf("size if %lu\n", vec.size()) ; //no warning

更多的资料显示,其实这个size_t是和编译器有关的,size_t的类型是不确定的,有可能是unsigned int 或者 unsigned long, 唯一能确定的就是这是个unsigned类型,更多可参考:http://stackoverflow.com/questions/1546789/clean-code-to-printf-size-t-in-c-or-nearest-equivalent-of-c99s-z-in-c,

从这个小问题里面我发散了三点:

(1)注意无符号数字和有符号数字的比较,比如定义 unsigned int a = 100, int b = -1, 比较 a > b 会输出false, 因为编译器会把有符号数转化成无符号数进行比较,于是b变成了比a大了。所以安全的做法是,有size_t或者size_type的地方,不要用int, 而是用size_type, 比如

for(string::size_type ix = 0; ix != s.size(); ++ix) 就比for(int i = 0; i != s.size(); ++i) 安全。

(2) 上述链接里面有提到%zu这样的formaat, 这个就和C/C++ 标准有关了,于是这次好好理解了一下各种标准 请看文章《C/C++ 标准笔记

(3) 觉得对printf的格式还是不够熟悉,于是又去整理了一下printf的格式加深记忆,请看文章《printf格式笔记

Written on January 5, 2013