C是否处理十六进制常量(例如0x23FE)和signed或unsigned int?
我很高兴auto在我的C++程序中使用变量.我知道auto使用模板规则声明的变量来推导变量类型,但我对数字类型的工作原理感到困惑.假设我有:
auto foo = 12;
Run Code Online (Sandbox Code Playgroud)
类型foo可以合理地int或甚至是unsigned char.但是假设在我的程序中稍后我会做一些数学并给foo赋值40亿.那时,我想foo成为一个类型unsigned int或者也许long.
编译器如何预测将在程序中稍后分配的值?
2个问题
首先,同时
long long int num = 1000000000000;
Run Code Online (Sandbox Code Playgroud)
工作良好
long long int num = 4014109449;
Run Code Online (Sandbox Code Playgroud)
给
warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
Run Code Online (Sandbox Code Playgroud)
这是什么意思 ?
其次
long long int num = 1000000*1000000;
Run Code Online (Sandbox Code Playgroud)
发出溢出警告
long long int num = 1000000000000;
Run Code Online (Sandbox Code Playgroud)
没问题,即使它们是一样的.我如何摆脱它?乘法给出了垃圾值
为什么这个循环(到10亿)只需要几个声音来执行...
for (i = 0; i < 1000000000; i++)
{
}
Run Code Online (Sandbox Code Playgroud)
...但这个循环(达到100亿)需要> 10分钟?
for (i = 0; i < 10000000000; i++)
{
}
Run Code Online (Sandbox Code Playgroud)
它不应该只需要30秒左右(3秒x 10)?
正如问题标题所示,将2 ^ 31分配给有符号和无符号的32位整数变量会产生意外结果.
这是C++我做的简短程序(in ),看看发生了什么:
#include <cstdio>
using namespace std;
int main()
{
unsigned long long n = 1<<31;
long long n2 = 1<<31; // this works as expected
printf("%llu\n",n);
printf("%lld\n",n2);
printf("size of ULL: %d, size of LL: %d\n", sizeof(unsigned long long), sizeof(long long) );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
MyPC / # c++ test.cpp -o test
MyPC / # ./test
18446744071562067968 <- Should be 2^31 right?
-2147483648 <- This is correct ( -2^31 because of the sign bit) …Run Code Online (Sandbox Code Playgroud) 这是交易:
当我有一个带有像这样的默认参数的函数时
int foo (int a, int*b, bool c = true);
Run Code Online (Sandbox Code Playgroud)
如果我错误地这样称呼它:
foo (1, false);
Run Code Online (Sandbox Code Playgroud)
编译器会将 false 转换为 int 指针并调用 b 指向 0 的函数。
我见过人们建议使用模板方法来防止隐式类型转换:
template <class T>
int foo<int> (int a, T* b, bool c = true);
Run Code Online (Sandbox Code Playgroud)
但这种方法太混乱并且使代码变得混乱。
有显式关键字,但它仅适用于构造函数。
我想要的是一种与显式方法类似的干净方法,这样当我声明该方法时,如下所示:
(keyword that locks in the types of parameters) int foo (int a, int*b, bool c = true);
Run Code Online (Sandbox Code Playgroud)
并这样称呼它:
foo (1, false);
Run Code Online (Sandbox Code Playgroud)
编译器会给我这个:
foo (1, false);
^
ERROR: Wrong type in function call (expected int* but got bool)
Run Code Online (Sandbox Code Playgroud)
有这样的方法吗?
我有以下示例代码:
uint64_t x, y;
x = ~(0xF<<24);
y = ~(0xFF<<24);
Run Code Online (Sandbox Code Playgroud)
结果将是:
x=0xfffffffff0ffffff
y=0xfffff
Run Code Online (Sandbox Code Playgroud)
有人可以解释这个区别吗?为什么x计算超过64位而y只计算在32位?
根据MSDN(整数类型 - VC2008):
没有后缀的十进制常量的类型是int,long int或unsigned long int.可以表示常量值的这三种类型中的第一种是分配给常量的类型.
在Visual C++ 2008上运行以下代码:
void verify_type(int a){printf("int [%i/%#x]\n", a, a);}
void verify_type(unsigned int a){printf("uint [%u/%#x]\n", a, a);}
void verify_type(long a){printf("long [%li/%#lx]\n", a, a);}
void verify_type(unsigned long a){printf("ulong [%lu/%#lx]\n", a, a);}
void verify_type(long long a){printf("long long [%lli/%#llx]\n", a, a);}
void verify_type(unsigned long long a){printf("unsigned long long [%llu/%#llx]\n", a, a);}
int _tmain(int argc, _TCHAR* argv[])
{
printf("sizeof(int) %i\n", sizeof(int));
printf("sizeof(long) %i\n", sizeof(long));
printf("sizeof(long long) %i\n\n", sizeof(long long));
verify_type(-2147483647);
verify_type(-2147483648);
getchar();
return 0; …Run Code Online (Sandbox Code Playgroud) 我有一些编写C代码的古老记忆:
long value = 0;
Run Code Online (Sandbox Code Playgroud)
在糟糕的旧Win16天,最后value只有半初始化:即低16位0,高16位是内存中该位置的随机位.因此,我有条件写:
long value = 0L;
Run Code Online (Sandbox Code Playgroud)
在C99和/或C++这个时代仍然需要这个吗?我知道ILP32指定int并且long都是32位,但是假设我们正在使用LP64,其中ints是32位,longs是64位.是否需要后缀或现代形式的C和C++是否会将文字隐式地扩展到它们被赋给的变量的长度?
无符号值怎么样?即这是必需的吗?
unsigned long value = 0UL;
Run Code Online (Sandbox Code Playgroud) 问候!我正在尝试使用C语言,直到遇到一些非常奇怪的事情.我无法向自己解释下面显示的结果.
代码:
#include <stdio.h>
int main(void)
{
int num = 4294967295U;
printf("%u\n", num);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题:
1.)如你所见,我创建了一个int可以保存-2147483648到2147483647之间的数字 .
2.)当我将值4294967295分配给此变量时,IDE在编译期间向我显示警告消息,因为变量溢出.
3.)由于好奇心,我在数字后面加了一个U(无符号),当我重新编译它时,编译器没有返回任何警告信息.
4.)我通过将U(无符号)更改为L(长)和LL(长long)进行了进一步的实验.正如预期的那样,警告消息仍然存在于这两个但不是在我将其更改为UL(无符号长整数)和ULL(无符号长多长)之后.
5.)为什么会这样?
警告信息:(对于步骤2)
warning #2073: Overflow in converting constant expression from 'long long int' to 'int'.
Run Code Online (Sandbox Code Playgroud)
警告信息:(对于步骤4 LL和L)
warning #2073: Overflow in converting constant expression from 'long long int' to 'long int'.
Run Code Online (Sandbox Code Playgroud)
最后,感谢您阅读我的问题,非常感谢您的教导和建议.