记录偶遇for中std::string::size()的一次坑

今天玩力扣周赛中,遇到一个小小的坑。当然主要原因是自己掌握的知识不多,理解不够清楚。那就记录下来吧,希望以后不会再掉进去。

我们先来看一段代码,如下:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	string s = "hello";
	for(int i = 0;i < s.size();i ++){
		cout << s << endl;
	}
	return 0;
}

很简单的循环中输出语句,执行结果如下:

再看下面一段类似的代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	string s = "hello";
	for(int i = -1;i < s.size();i ++){
		cout << s[i];
	}
	return 0;
}

这段代码只是把i初始为-1,执行结果如下:

  

没有任何输出,很明显直接跳过了循环,乍一看,s.size()不是5吗,-1难道不小于5?

这里需要注意,std::size()返回无符号整型,而i是有符号整型-1,而负数在计算机中以补码形式存放,那么-1在内存中就是全1。同时,C语言中,当执行一个运算时,如果它的一个运算数是有符号的而另一个运算数是无符号的,那么C会隐含地将有符号数强制转换成无符号数。那下面就用几个例子说明,看看:

(1)、直接手动强制转换,把有符号转换成无符号

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	unsigned int a = -1;
	cout << a;
	return 0;
}

输出如下:(2^{32} - 1) 

(2)、遇到无符号和有符号同时运算,自动把有符号转换为无符号

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	unsigned int a = -1;
	int b = 1;
    cout << a + b << endl;
	bool is_small = a < b;
	cout << is_small;
	return 0;
}

输出如下:

 

唉,等下,a + b = 0? 不是a强制转换成无符号了吗,怎么a + b还是0呢, a < b也为假。其实,-1在内存中的存放是这样的:11111111 11111111 11111111 11111111(补码),那么它对应的无符号那就是2^32 - 1,肯定大于1,若再加1,就会一直进位,直到溢出,最终为0。

 

 好了,到这也就弄明白了,其实也就是一些小细节,如果我们最开始写成下面结构,就不会出现一些不必要的bug:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	string s = "hello";
    int len = s.size();
	for(int i = 0;i < len;i ++){
		cout << s << endl;
	}
	return 0;
}

由此可见,每次coding时,需要养成良好的习惯,按照一定规范编写代码,能够避免掉一些不必要的麻烦,不仅提高效率,还利于后续的维护和更新迭代。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值