std::vector<T>.size()返回的是size_t类型

一、遇到的问题

今天写程序的时候代码运行崩溃,提示format specifier doesn’t match argument type。因为我刚刚接触C++,所以在这个问题上花了不少的时间。

代码如下:

void MyApp::wrong()
{
    std::vector<int> test;
    test.push_back(1);
    test.push_back(2);
    test.push_back(3);

    wxLogDebug("length is %d", test.size());

    for (int i = 0; i < test.size(); i++)
    {
        wxLogDebug("do something");
    }
}

代码非常的简单,但是一旦编译运行,就会出断言错误提示。最终发现原来vector<T>.size()返回的不是int类型,而是size_t类型,所以在wxLogDebug()中因为存在着断言,发现类型不同就报错了。而后面for()循环里面虽然不报错,那是因为for()循环里面相当于是对int < size_t进行判断,没有断言语句所以不报错,并不是因为真的没有错误。

(int < size_t)这个判断语句虽然在多数情况下都可以正确的执行,但安全起见,还是应该重新定义,改成for (size_t i=0; i<test.size(); i++)这样比较稳妥。

再回过头看wxLogDebug()里面正确的写法,就是使用%zu代替%d,这样格式化字符串的时候接受的参数类型就是size_t了。所以最终代码正确写法如下:

void MyApp::right()
{
    std::vector<int> test;
    test.push_back(1);
    test.push_back(2);
    test.push_back(3);

    wxLogDebug("length is %zu", test.size()); // 改动1

    for (size_t i = 0; i < test.size(); i++) // 改动2
    {
        wxLogDebug("do something");
    }
}

二、size_t和int有什么不同?

上面遇到的问题并不复杂,只是因为以前没有碰到过,所以浪费了一些时间。接下来的问题更令我感兴趣:size_t和int有什么不同吗?既然说size_t是无符号、且与当前系统最大可用内存匹配数,为什么不能直接用unsigned int代替呢?

原因是为了令代码在不同的平台上移植时更加的方便。size_t的确就是unsigned int,但具体是int16、int32还是int64并不一定,在不同的处理器、不同的系统上,size_t表示的范围是不同的。

例如在32位系统上,size_t是unsigned int32,而在64位系统上它的范围则是unsigned int64。

std::vector<T>.size()返回的虽然是size_t类型,但是更多的情形下,size_t并不是为了存储索引数值、而是为了存储内存地址,这个时候内存的地址最大能寻址到多少,size_t就能够跟随到多少。

虽然我们也可以直接定一个unsigned long int,也就是“无符号int64”,这样也可以确保在不同的系统下存储的数值都不会产生溢出,但是如果是在32位系统上编译这样的程序,就会产生严重的浪费,所有用到的变量,都有至少16位是永远用不到的,这是浪费存储空间、浪费内存、且效率低下的。

因而使用size_t更加的灵活,并且免除了我们在不同系统上编译代码时要考虑分配多少位给变量,完全交由编译器在预处理阶段自行根据系统的位数、预处理好了。

以前上学的时候觉得所有的知识都挺容易理解的,现在也许是年龄大了,即便是对已经已经熟练掌握了的知识,再看的时候,都会感觉是“一头雾水”,唯有继续艰难的、一点点的重新理解,才能让自己感觉有所收获。

Related Posts

闷热的三伏天

每年最闷热的日子到了,这段日子称为“三伏天儿”,“伏”大概是“藏”的意思,指的是地表阴气因为骄阳而隐藏到地表以下。整个地表都被烈日烘烤得阳气十足、再无阴凉。 也有人喜欢用“桑拿天”称呼这段日子,因为城市人不再做农事、可却喜欢泡“桑拿”,因而对他们来说,“桑拿”是个更形象的词汇、是随着新生事物诞生的新词。这个词来源于芬兰,芬兰语中的浴室或浴池称为“sauna”。 说起来估计在芬兰,人们去sauna也顶多就是冲冲水、洗洗澡吧。可城里人并不满足这样简单的洗浴形式,他们找到了更有妙趣的洗浴方式——蒸汽浴,同时再配上一个芬兰词,看上去更加的高大上、又有舶来味道。 坐在高温蒸汽房间中,借着热气腾腾的水汽将皮肤慢慢沁润、烘开汗腺,好似能够洗的更彻底、更干净、更通透、更过瘾。当然结账的时候花销也会更大一些。可是对于喜欢沉浸在体验中的城市人,这笔钱花的值得。只要体验好、感觉妙,花钱就是理所应当且无需吝啬的。 但若是让你在烈日的烘烤、高温的环抱中“享受一次免费桑拿”,恐怕很少有人乐意,哪怕免费也不会有人觉得这是享受。这着实是种煎熬。浑身不住的出汗,脖子上的汗渍反复被蒸干,从汗液中析出的盐分附着在因烈日灼伤的皮肤表面,瘙痒疼痛。 千万不要用手去抓,已经灼伤的皮肤经不住这样的力道,只会越抓越痒、如果忍受不住瘙痒而尽管解痒、解气的去抓挠,皮肤会被指甲划伤、进而瘙痒转成疼痛。这样的话即便是晚上回到家中,汗水已经洗净,白天抓过的地方依然又痒又痛、甚至红肿热辣,辗转在床上难以入睡。 所以三伏天,任谁都不大想出门免费蒸场桑拿,除非迫不得已。明智的人都会躲在房间中、最好躲在空调房中,享受着清凉,如果能再吃上一口冰镇西瓜,那才叫一个享受呢。 我便闷热的房间中苦苦煎熬,我的房间中并没有空调,仅有的风扇吹出来的都是35摄氏度的热气。不敢开窗、因为窗外吹进来的只会是更高温的热浪。只有不住的喝水、再偶尔将水拍打在头发上,三不五时的看看窗外,期待着一场雨水到来。 我在这间闷热的房间中,无所事事的 “忙碌”着手中的“电脑工作”。 这句话有些矛盾是吧?既然是无所事事、为什么要说是忙碌呢?这句话还有一些空洞无物,究竟什么是“电脑工作”?能够说出这种既矛盾又空洞的话,显然是因为我想自欺欺人。我没有任何的工作,但又不想承认自己闲着,所以就不断地在电脑上写字,写这篇文字,目的是让自己看上去似乎是个“作家”,我可没偷闲,我在创作呢。

一道有趣的几何题

从网上看到的,试着做了做,没有做出来。所以记录在这里,等以后有时间了再重新尝试。 这道题我用绘图工具重新绘制了一遍题目,用的绘图工具是一个web工具,地址如下: https://www.geogebra.org

专注于斐波那契数列研究的期刊

Fibonacci Quarterly是由Fibonacci Association主办的一本期刊,专注于对斐波那契数列(Fibonacci)及相关的数学领域进行研究。它的网站是:https://www.fq.math.ca/ 在它的网站上提供了从创刊的第1卷起,至第47卷(1963年-2009年)的全部电子版期刊,从48卷之后发布的期刊虽然不再提供全文、但也仍然会提供摘要版本。 我对斐波那契数列相关的数学知识并不感兴趣、工作中也几乎没有与之相关的工作,但是因为业余生活中比较喜欢看数学方面的科普文章,所以对这个数列知道一些有趣的故事。 斐波那契数列是由1202年斐波那契收集阿拉伯和希腊的数学研究资料、编撰整理出来的《算盘书》中一个有趣的“兔子问题”引申、发展出来的。在《算盘书》中,斐波那契提出了一个“兔子问题”:假定大兔子每月生一对小兔子,而小兔子经过两个月就可以长成大兔子,那么自拥有一对大兔子开始,一年后可以繁殖多少对兔子? 上面这个兔子问题,如果绘制成表格: 从这个表格上可以看出来,无论是大兔子的数量、还是大兔子当月诞下的小兔子数量、还有每个月新长大的小兔子数量(从3月开始),都是相同的数列:1,1,2,3,5,8,13,21,34,…… 这个数列就是“斐波那契数列”,它从第三项开始,每一项都是前两项的和。如果用计算式表达,可以表示成:。 这个数列以及它的第n项的表达式,看上去都似乎平平无奇,然而如果要想将它的第n项表达式写成通项公式便不是那么简单的事情了。事实上,它的通项公式是自1202年斐波那契数列提出之后,经过了600多年、直到1843年才由法国数学家雅克·比奈(Jacques Philippe Marie Binet)归纳出来,因而这个通项公式被命名为Binet公式:。 Binet通项式有趣的地方有两个: 1、首先是一目了然的:它其中含有无理数,这实在是令人感到不可思议。一个简单的、完全由整数构成的数列,竟然需要使用无理数构造它的通项式。实际上也的确如此,如果不是引入了无理数,那么也不至于经历了600多年才被比奈归纳出来; 2、另一个有趣的事情可以看出来,当斐波那契数列趋于无限大之后,它的前后两项的比值趋于 。而这个比值恰恰是黄金分割比例0.618…… 斐波那契数列除了上面这些浅显的常识之外,还有很多重要的应用,无论是在计算机、密码学;还是在金融与经济学;又或者在物理和工程学上,都能见到它的身影。也正因为如此,回到本文开始提到的网站,才会有专门的这个专刊,定期刊发有关斐波那契数列的最新研究成果和消息。 update 2024.11.10 1、最近闲来无事阅读《数学史》,看到其中也有关于斐波那契的历史介绍。其中提到斐波那契生活的公元1200年左右恰是欧洲文明的“黑暗时期”,那时的欧洲非常荒芜、落后,并没有后来文艺复兴时期的辉煌璀璨。可以说是人类历史上的蒙昧时期; 2、前几天自己因为记不住牛顿二项式展开,所以手动推敲了一遍。其中也用到了一个数列,不过并非斐波那契数列、而是杨辉三角形。我因为以前并不知道斐波那契数列,所以误以为杨辉三角形就是斐波那契数列,今天才知道两个数量完全风马牛不相及。

函数的图像

试使用SageMath进行函数图像的绘制。例如:对于复变函数 上面函数,可以使用SageMath绘制出在复平面上的图像: 其中的complex_plot()和plot()相似,只是声明为在复平面上进行绘图。后面的第一个(-5,5)指实坐标范围从-5到+5,第二个(-5,5)指的是虚数坐标、也就是复平面上的纵坐标、从-5i到+5i。 绘制出来的图像比较“抽象”,大概能看出来是通过彩色的衔接来表达是否连续,但这五颜六色的色彩对我而言还是比较陌生、一时难以理解的。 生成的图像是: 上面的图象太模糊了,改变参数,调整为plot_points=500,可以得到更清晰、精致的图像:

苹果1984年时的宣传海报

这是1984年在苹果产品发布会上出现的海报,当时乔布斯就在会上立下一个志向:要令这台电脑成为继电话之后的、第二款桌面设备,为人们所熟知。今天看来,苹果当时对未来市场的眼光,无疑是十分正确的。 1984年时,不要说是互联网、就连电脑也十分的罕见,当时撩撩几家电脑生产厂商都是在销售着价格昂贵的商业计算机,个人微机的概念在当时恐怕很少有人敢想——计算机可不是一般老百姓想拥有就能够拥有的。 在当时,电话已经普及、并且真真实实的成为了人类历史上第一款“桌面电子设备”。与电话不同,当时的电脑,还是一个“高大上”的物件,很少有人能够接触到。 那时的美国大约有2.35亿人,其中能够知道并接触到电脑的人还凤毛麟角,除了商业用户和军用外,一般老百姓中只有对电子技术十分着迷的人乐忠于“捣鼓这些闪烁着灯光的电线”。 而苹果公司、乔布斯,当时便锁定了2.35亿人中的10%——也就是2500万人,他认为,这2500万的“办公室白领和大学校园中的学生”,将会是未来在电脑普及之后的主要使用人群,也就是说电脑将成为继电话之后的第二个“桌面电子设备”。并且个人微机的时代已经到来,因为苹果自己推出的电脑,就是专为这2500万人打造的。 所以基于以上的市场定位和对未来的预期,苹果推出了这款“小巧便携、可以为个人用户所用的”Macintosh(麦金塔)、也就是今天我们所熟知的“Mac电脑”。 这张海报上的宣传语“Of the 235 million people in America, only a fraction can use a computer”,是当时发布会上的一句演讲词,这句话的完整表述是: Because of the 235 million people in…

我现在拥有了2台主力电脑

1、昨天购买了一个新的鼠标,现在正在使用,已经好多年没有买过新鼠标了,所以昨天买回来之后非常高兴,几乎是晚上抱着这个鼠标睡的觉。今天到了单位,就迫不及待的试用了一下,效果非常满意; 2、另外,昨天还购买了一块500GB的固态硬盘,是SATA3接口的,放在我新收拾出来的电脑上,虽然那台电脑只有SATA2的支持,但是对我而言,也已经是巨大的性能提升了; 3、现在,我已经有了2台“生产力台式机”: 4、以上两台电脑,每台都是使用了一张1060的显卡; 5、对我日常工作而言,这两台电脑是足够用的。额外的,还将家里一台Time Machine找了出来,准备组一个小型局域网,这样就更方便两台电脑之间交换数据和备份数据了; 6、当下对我而言,最大的“隐患”,就是这台Windows电脑的硬盘已经用了很多年,我总担心它出问题,要尽快解决才好。