我只是想知道我应该使用std::size_tfor循环和东西而不是int?例如:
#include <cstdint>
int main()
{
for (std::size_t i = 0; i < 10; ++i) {
// std::size_t OK here? Or should I use, say, unsigned int instead?
}
}Run Code Online (Sandbox Code Playgroud)
一般来说,何时使用的最佳做法是什么std::size_t?
// Following trick can reduce the range check by one
if ((uint) index >= (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
Run Code Online (Sandbox Code Playgroud)
显然这比(?)更有效 if (index < 0 || index >= _size)
我很好奇这个技巧背后的理由.单个分支指令真的比两个转换要贵uint吗?或者是否还有一些其他优化会使这个代码比另外的数字比较更快?
为了解决房间里的大象:是的,这是微优化,不,我不打算在我的代码中到处使用它 - 我只是好奇;)
c# performance micro-optimization numeric-conversion range-checking
这是一个相当愚蠢的问题,但为什么int常用而不是unsigned int在C或C++中为数组定义for循环时?
for(int i;i<arraySize;i++){}
for(unsigned int i;i<arraySize;i++){}
Run Code Online (Sandbox Code Playgroud)
我认识到int在进行数组索引以外的操作时使用的好处以及使用C++容器时迭代器的好处.是不是因为在循环数组时无关紧要?或者我应该一起避免它并使用不同的类型,如size_t?
我有一个关于Delphi中位移行为的问题(或者更可能是错误报告)(在Borland Delphi 7中测试过).
目标:使用任意数字向右执行"算术"按位移位.
这意味着必须扩展符号位 - 如果设置了一个数字的最高有效位,则将从左侧填充二进制数,而不是0.
因此,算术右移后的数字"-1"必须保持相同的数字(所有位= 1),但是"逻辑移位"(总是用零填充数字)必须给出最大正整数(最大正有符号整数) ,为了正确)
我只在32位系统上测试过它(Windows); 而且,我需要它以32位整数显式工作.
当源编号存储在变量中时,看起来Delphi中存在带有"shr"的内部错误.
我的示例代码:
program bug;
{$APPTYPE CONSOLE}
var
I:Integer;
C:Cardinal;
begin
I := -1; // we’ll need that later
C := $FFFFFFFF;
Run Code Online (Sandbox Code Playgroud)
(这只是开始).接下来,让我们尝试一些"shr":
Writeln('0) ', -1 shr 1 );
Writeln('1) ', $FFFFFFFF shr 1 );
Run Code Online (Sandbox Code Playgroud)
"-1"是等效于"$ FFFFFFFF"的签名.似乎"shr"行为(算术或逻辑)基于源号是签名还是不签名(整数或基数)的事实.
输出是:
0) -1
1) 2147483647
Run Code Online (Sandbox Code Playgroud)
非常正确.然后我需要尝试手动将这些数字转换为整数或基数:
Writeln('2) ', Integer(-1) shr 1 );
Writeln('3) ', Integer($FFFFFFFF) shr 1 );
Writeln('4) ', Cardinal(-1) shr 1 );
Writeln('5) ', Cardinal($FFFFFFFF) shr 1 ); …Run Code Online (Sandbox Code Playgroud) C中应该使用哪种类型来表示两个对象大小之间的差异?
像size_t未签名的那样
size_t diff = sizeof (small_struct) - sizeof (big_struct);
Run Code Online (Sandbox Code Playgroud)
显然不正确,在我看来,没有真正的签名等价物.
ptrdiff_t 听起来很诱人,但是
ptrdiff_t这样的32位平台也不会这样吗?如果是这样,两个对象的大小之间的差异只需要16位,但使用ptrdiff_t会得到一个32位宽的变量,使其不是最佳的.那么,什么是适合这种价值的便携式?
Edit:
我知道ssize_t,但它是
看看这个C代码:
int main()
{
unsigned int y = 10;
int x = -2;
if (x > y)
printf("x is greater");
else
printf("y is greater");
return 0;
}
/*Output: x is greater.*/
Run Code Online (Sandbox Code Playgroud)
我理解为什么输出是x更大,因为当计算机比较它们时,x被提升为无符号整数类型.当x被提升为无符号整数时,-2变为65534,绝对大于10.
但是为什么在C#中,等效代码会产生相反的结果呢?
public static void Main(String[] args)
{
uint y = 10;
int x = -2;
if (x > y)
{
Console.WriteLine("x is greater");
}
else
{
Console.WriteLine("y is greater");
}
}
//Output: y is greater.
Run Code Online (Sandbox Code Playgroud) 在我自己的代码中使用整数值时,我总是试着考虑签名,问自己整数应该是有符号还是无符号.
当我确定该值永远不需要为负数时,我会使用无符号整数.
我不得不说这种情况大多数时间都会发生.
在阅读其他人的代码时,我很少看到无符号整数,即使代表的值不能为负数.
所以我问自己:"这有充分的理由吗,或者人们只是使用签名整数,因为不关心»?
我在这里和其他地方搜索了这个主题,我不得不说,当它适用时,我找不到使用无符号整数的充分理由.
我遇到了这些问题:«默认int类型:签名或无符号?»和« 你应该总是使用'int'代表C中的数字,即使它们是非负数吗?»这两个都提供以下示例:
for( unsigned int i = foo.Length() - 1; i >= 0; --i ) {}
Run Code Online (Sandbox Code Playgroud)
对我来说,这只是糟糕的设计.当然,它可能会导致无限循环,无符号整数.
但是foo.Length()在循环之前是否很难检查是否为0?
所以我个人认为这不是一直使用有符号整数的好理由.
有些人也可能会说有符号整数可能很有用,即使对于非负值,通常也可以提供错误标记-1.
好吧,拥有一个特定值意味着"错误"是件好事.
但那么,UINT_MAX对于那个具体价值的东西有什么不对?
我实际上是在问这个问题,因为它可能会导致一些巨大的问题,通常是在使用第三方库时.
在这种情况下,您经常需要处理有符号和无符号值.
大多数时候,人们只是不关心签名,只是unsigned int在signed int没有检查范围的情况下将a分配给a .
我不得不说我对编译器警告标志有点偏执,所以在我的设置中,这样的隐式转换将导致编译器错误.
对于那种东西,我通常使用函数或宏来检查范围,然后使用显式转换分配,如果需要则引发错误.
这对我来说似乎合乎逻辑.
作为最后一个例子,我也是Objective-C开发人员(注意这个问题与Objective-C无关):
- ( NSInteger )tableView: ( UITableView * )tableView numberOfRowsInSection: ( NSInteger )section;
Run Code Online (Sandbox Code Playgroud)
对于那些不熟悉Objective-C的人来说,NSInteger是一个有符号整数.
对于特定部分,此方法实际上检索表视图中的行数.
结果永远不会是负值(顺便说一下,作为节号).
那么为什么要使用有符号整数呢?
我真的不明白.
这只是一个例子,但我总是看到那种东西,用C,C++或Objective-C.
所以,我只是想知道人们是否只是不关心那种问题,或者是否最终有一个 …
我很困惑size_t.我知道这是一个未签名的类型..正确吗?我的问题是,何时应该使用它.是否有理由将它与常规数组一起使用?我的意思是必须声明数组大小真的很大,如此巨大,以至于常规的无符号或有符号无法处理它.然后一个size_t人能够处理它吗?有人能举个例子吗?