`long long int a=50` 和 `int a =50LL` 之间的区别是什么?

huangapple go评论72阅读模式
英文:

What is the difference between `long long int a=50` and `int a =50LL`?

问题

我开始学习C++,来源于Josh Lospinoso的《C++ Crash Course》。

我无法理解“类型”。

long long int a=50int a =50LL 之间有什么区别呢?
对我来说,它们两者都看起来像是 long long int

我尝试运行了以下代码:

#include <cstdio>
int main() {
    long long int a=50;
    int b=50LL;
    printf("a is %lld and b is %lld",a,b);
}

结果是:

a is 50 and b is 18042367336513586

所以要么格式说明符有问题,要么int b=50LL有问题。

将b的格式说明符更改为%d后,我得到:

a is 50 and b is 50

这是否意味着b是默认的“int”?如果是的话,那么LL的作用是什么呢?

在查阅关于类型的信息时,我遇到了这个链接
所以我尝试运行了这个代码:

#include <iostream>
#include <typeinfo>

int main(){
    long long int a = 50;
    int b = 50LL;
    std::cout << typeid(a).name() << std::endl;
    std::cout << typeid(b).name() << std::endl;

    return 0;
}

结果是:

x
i

所以它们确实是不同的类型(?)。但是为什么呢?

英文:

I have started learning C++ from Josh Lospinoso's C++ Crash Course.

I am unable to wrap my mind around 'types'.

What is the difference between long long int a=50 and int a =50LL ?
To me, they both look like long long int

I tried to run this:

#include&lt;cstdio&gt;
int main() {
    long long int a=50;
    int b=50LL;
    printf(&quot;a is %lld and b is %lld&quot;,a,b);
}

and got :
> a is 50 and b is 18042367336513586

So there is something wrong with either the format specifier or int b=50LL

On changing the format specifier of b to %d. I get:
> a is 50 and b is 50

So does this mean that b is the default 'int' ? If yes, what is the role of LL then?

On surfing about types, I came across this.
So I tried running this:

#include &lt;iostream&gt;
#include &lt;typeinfo&gt;

int main(){
    long long int a = 50;
    int b = 50LL;
    std::cout &lt;&lt; typeid(a).name() &lt;&lt; std::endl;
    std::cout &lt;&lt; typeid(b).name() &lt;&lt; std::endl;

    return 0;
}

which gave
> x<br>
i

So they are indeed of different types (?). But Why?

答案1

得分: 6

声明了一个 `long long int` 变量,并将其初始化为 50。
声明了一个 `int` 变量,并将其初始化为 50。常量值 50 在词法上被指定为 `long long` 整数常量,用于初始化 `a`(仅仅为了初始化 `a` 而转换为 `int`,本身没有任何有用的作用)。

所以不同之处在于最终你要么得到一个名为 long long int 的变量,要么得到一个名为 int 的变量,无论哪种情况,它们都被初始化为 50。

英文:
long long int a=50;

This declares a long long int variable, and initializes it to 50.

int a =50LL;

This declares an int variable, and initializes it to 50. The constant value 50 is lexically specified as a long long integer constant, which gets converted to an int, for the purpose of initializing a (accomplishing absolutely nothing useful, by itself, whatsover).

So the difference is that you end up with either a long long int or an int variable named a. In both cases they are initialized to 50.

答案2

得分: 1

%lld 是对类型为 int 的变量 b 的错误的 转换规范。请改用 %d

  • %lld 表示以十进制格式输出类型为 long long int 的值(而不是十六进制或八进制)。
  • %d 表示以十进制格式输出类型为 int 的值(而不是十六进制或八进制)。

垃圾输出的原因是 intlong long int 的大小不同。

按照你的写法,printf 将访问存储 b 的地址,并抓取 8 个字节,这通常是 long long int 的大小。它应该只抓取 4 个字节,这通常是 int 的大小。

以下是正确的程序:

#include<cstdio>
int main() {
    long long int a = 50LL;
    int b = 50;
    printf("a is %lld and b is %d", a, b);
}

在Microsoft Visual C++上,这个无效的程序实际上在被编译器自动修复后可以正确运行。以下是它生成的警告:

1>main.cpp(5,12): warning C4477: 'printf' : format string '%lld' requires an argument of type '__int64', but variadic argument 2 has type 'int'
1>main.cpp(5,12): message : consider using '%d' in the format string
1>main.cpp(5,12): message : consider using '%I32d' in the format string

顺便说一下,用于 b 的初始化器选择不佳,但完全有效。C++ 会悄悄执行一个会丢弃高阶位的 narrowing conversion

int b = 50LL;  // 不好的形式,但合法
int b = 50;    // 更好的形式
英文:

The problem is the call to printf, not the initialization.

%lld is the wrong conversion specification for variable b, which has type int. Use %d instead.

  • %lld means output a value of type long long int in decimal format (rather than hex or octal).
  • %d means output a value of type int in decimal format (rather than hex or octal).

The garbage output is explained by the different sizes of int and long long int.

As you wrote it, printf is going to the address where b is stored, and grabbing 8 bytes, which is (usually) the size of long long int. It should be grabbing only 4 bytes, which is (usually) the size of int.

Here is the correct program:

#include&lt;cstdio&gt;
int main() {
    long long int a = 50LL;
    int b = 50;
    printf(&quot;a is %lld and b is %d&quot;, a, b);
}

On Microsoft Visual C++, the invalid program actually runs correctly after automatically being fixed by the compiler. Here are the warnings it generated:

1&gt;main.cpp(5,12): warning C4477: &#39;printf&#39; : format string &#39;%lld&#39; requires an argument of type &#39;__int64&#39;, but variadic argument 2 has type &#39;int&#39;
1&gt;main.cpp(5,12): message : consider using &#39;%d&#39; in the format string
1&gt;main.cpp(5,12): message : consider using &#39;%I32d&#39; in the format string

By the way, the initializer used for b is a poor choice, but perfectly valid. C++ silently performs a narrowing conversion that discards the high-order bits.

int b = 50LL;  // poor form, but legal
int b = 50;    // better form

huangapple
  • 本文由 发表于 2023年7月24日 20:11:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76754379.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定