c++中float数据类型声明的混淆

Confusion about float data type declaration in C++

本文关键字:声明 数据类型 float c++      更新时间:2023-10-16

完全是新手。在我的学校作业中,我被要求写一个程序显示-

s= 1 + 1/2 + 1/3 + 1/4 .....+ 1/n

我是这么做的-

#include<iostream.h>
#include<conio.h>
void main()
{
    clrscr();
    int a;
    float s=0, n;
    cin>>a;
    for(n=1;n<=a;n++)
    {
        s+=1/n;
    }
    cout<<s;
    getch();
}

它完美地显示了它应该做的。然而,在过去,我只写过使用int数据类型的程序。根据我的理解,int数据类型不包含任何小数点,而float则包含。我对float还不太了解。那天晚上晚些时候,我在YouTube上看了一些视频,他在写完全相同的程序,但方式有点不同。这个视频是用外语写的,所以我看不懂。他所做的是将n声明为整数。

int a, n;
float s=0;

代替

int a
float s=0, n;

但是这并没有显示想要的结果。于是,他提出了两种纠正方法。他修改了for循环体-

s+=1.0f/n;

s+=1/(float)n;

在我的理解中,他在程序后面声明了'n'为浮点数据类型(我对吗?)所以,我的问题是,两者都显示相同的结果,但两者之间有任何区别吗?当我们声明'n'是浮点数时,为什么他写的是1.0f而不是n。我试过了,但它给出了错误。在第二种方法中,为什么不能写成1(float)/n而应该写成1/(float)n呢?在第一个方法中,我们添加了float后缀1。还有,1。F和1.0f?

我试着用谷歌搜索我的问题,但找不到任何答案。另外,几个小时后我想到的另一个困惑是——为什么我们甚至要声明"n"是浮点数?按照程序,和应该是实数。难道我们不应该只声明s是浮点数吗。我想得越多,脑子就越糊涂。请帮助!

谢谢。

原因是整数除法的行为不同于浮点除法。

4 / 3给出的是整数110 / 3给出的是整数3

然而,4.0f / 3给你的是1.3333..., 10.0f / 3给你的是3.3333...

所以如果你有:

float f = 4 / 3;

4 / 3将给你一个整数1,然后它将被存储到浮点数f中作为1.0f

你必须确保除数或被除数是浮点数:

float f = 4.0f / 3;
float f = 4 / 3.0f;

如果你有两个整数变量,那么你必须先将其中一个转换为浮点数:

int a = ..., b = ...;
float f = (float)a / b;
float f = a / (float)b;

第一个等价于:

float tmp = a;
float f = tmp / b;

由于n只具有整数值,因此将其定义为int是有意义的。然而,这样做意味着这不会像您期望的那样工作:

s+=1/n;

在除法操作中,两个操作数都是整数类型,因此它执行整数除法,这意味着它取结果的整数部分,并丢弃任何小数部分。所以1/2的值应该是0,因为1除以2得到0.5,丢掉分数得到0。

这与浮点除法相反,浮点除法保留小数部分。如果两个操作数都是浮点类型,C将执行浮点除法。

在上面表达式的情况下,可以通过对任意一个操作数执行类型转换来强制进行浮点除法:

s += (float)1/n

或:

s += 1/(float)n

还可以通过提供小数部分来指定常量1为浮点常量:

s += 1.0/n

或附加f后缀:

s += 1.0f/n

f后缀(以及ULLL后缀)只能应用于数值常量,而不能应用于变量。

他所做的是一种叫做cast的事情。我相信你们学校会在新的讲座中提到它。基本上,整个程序的n都被设置为整数。但是由于整型和双精度是相似的(都是数字),c/c++语言允许你使用它们,只要你告诉编译器你想用它做什么。可以通过添加括号和数据类型ie

来实现。
(float) n

他在程序后面声明'n'为浮点数据类型(我对吗?)

不,他定义了(因此也声明了)nint,然后显式地将其转换(强制转换)为float

都显示相同的结果,但两者之间有什么区别吗?

不。它们在这里是一样的。当算术运算符具有intfloat操作数时,前者隐式地转换为后者,因此结果也将是float。他只是向你展示了两种方法。当两个操作数都是整数时,您得到的结果可能是不正确的整数值,而适当的数学除法会给您一个非整数商。为了避免这种情况,通常将其中一个操作数转换为浮点数,以便实际结果更接近预期结果。

为什么他写了1.0f而不是n. for f.n.我试过了,但它给出了错误。[…还有,我和我的朋友之间有什么区别吗?F和1.0f?

这是因为语言语法是这样定义的。当你声明一个浮点字面值时,后缀是使用.f。所以5int5.0f5.ffloat;省略任何尾随的0 s都没有区别。然而,n.f是语法错误,因为n是一个标识符(变量)名称,而不是一个常量字面值。

在第二个方法中,为什么我们不能写1(float)/n而不是1/(float)n?

(float)nint变量n的有效c风格强制转换,而1(float)只是语法错误。

s+=1.0f/n;

s+=1/(float)n;

…所以,我的问题是,两者都显示相同的结果,但两者之间有任何区别吗?

是的。

在C和c++中,当计算涉及不同类型的表达式时,其中一个或多个表达式将被"提升"为具有更高精度或范围的类型。因此,如果您有一个包含signedunsigned操作数的表达式,那么signed操作数将被"提升"到unsigned。如果表达式中有floatdouble操作数,则float操作数将提升为double

请记住,两个整数操作数的除法得到的结果是整数——1/2得到的是0,而不是0.5。要获得浮点结果,至少有一个操作数必须为浮点类型。

1.0f/n的情况下,表达式1.0f的类型为float 1,因此n将从类型int"提升"为类型float

1/(float) n的情况下,表达式n被显式地转换为类型float,因此表达式1从类型int提升为float

吹毛求疵:

    除非你的编译器文档明确地列出void main()作为main函数的合法签名,否则使用int main()。来自在线c++标准:
    3.6.1主函数

    …实现不能预定义main函数。此函数不得重载。它必须有一个声明的返回类型int ,否则它的类型是实现定义的…
    其次,格式化你的代码——这让其他人更容易阅读和调试。空格和缩进是你的朋友——使用它们。


<一口> 1。不带后缀的常量表达式1.0类型为doublef后缀告诉编译器将其视为float1.0/n会导致double类型的值。