从零开始的c++学习 2:[基本的数据类型&算术运算]

6 minute read

Published:

记录一下c++学习的步骤 : base on Course ‘CS205 C/C++ Program Design’ in 2021 Fall at Southern University of Science and Technology. | 视频

week02

基本的数据类型: 整型, 浮点型, 布尔型, …//算术运算

  • 知识点1 : 变量一定要初始化

  • 知识点2 : int , signed 最高位是符号位, unsigned 全部位用来存数值

    • int is signed int $[-2^{31}, 2^{31}-1]$ //假设是32位
    • unsigned int : $[0, 2^{32}-1]$ //假设是32位
    • long int :更长的int
    • short int :更短的int
    • long long
  • 知识点3: c++ 的数据类型的位数并不是固定的

    •   //可以使用sizeof()查看字节数 : 操作符
        cout << "sizeof(int)=" << sizeof(int) << endl;
      
  • 知识点4:更多的整数类型

    • char : 8bit int, 需要指定是否带符号
      • signed char , unsigned char
    • size_t
  • 知识点5: 有限位数不能表达无限多的数
  • 知识点6: 浮点数(float double ..)会有精度问题.
    • 如果加上浮点数的量级相比很小的数, 该浮点数可能不会变.
    • 不用 == 判断浮点数是否相同, fabs(f1-f2)<FLT_EPSLION
  • 知识点7:
    • ±inf : infinity ( exponent= 11111111, fraction=0)
    • nan : not a number (exponent= 11111111, fraction!=0)
  • 知识点8: E notation is used if the exponent is 6 or larger or -5 or smaller.

    知识点9 控制output formats 的方式:

    1.  cout.setf() ; 
       cout.set(fmtflags,fmtflags);
              
       /*方法2*/
       #include <iostream>
       #include <iomanip>
       using namespace std;
       int main()
       {
       cout.setf(ios_base::fixed, ios_base::floatfield);
       cout << 56.8 << setw(12) << setfill('#') << 456.77 << endl; // 56.800000##456.770000
       cout << left;												
       cout << setw(12) << setprecision(2) << 123.356 << endl;     // 123.36######
       cout << setw(12) << setprecision(5) << 3897.6784385 << endl;// 3897.67844##
       cout << right;
       cout << setw(12) << setfill(' ') << 123.356 << endl;        // '   123.35600'
       cout << setw(12) << setfill(' ') << 3897.6784385 << endl;   // '  3897.67844'
       cout.unsetf(ios_base::fixed);
       cout << 56.8 << setw(12) << setfill('$') << 456.77 << endl; // 56.8$$$$$$456.77
       return 0;
       }
              
      

      setw()函数

      setw(int n) 是c++中在输出操作中使用的字段宽度设置,设置输出的域宽,n表示字段宽度。只对紧接着的输出有效,紧接着的输出结束后又变回默认的域宽。当后面紧跟着的输出字段长度小于n的时候,在该字段前面用空格补齐;当输出字段长度大于n时,全部整体输出。

      setprecision(int n)

      std::fixed 查看精细值, 如果一个数字太大,无法使用 std::setprecision(int n) 指定的有效数位数来打印,则许多系统会以科学表示法的方式打印。 std::setprecision(int n )将指定浮点数字的小数点后要显示的位数,而不是要显示的总有效数位数。

      setfill (char_type c);

      c − 流的新填充字符,

// bool.cpp
char16_t c4 = u'于'; //中文字符前要加u, 小写16位,大写U32位
cout << +c1 << ":" << +c2 << ":" << +c3 << endl;


// float.cpp
cout << std::fixed << std::setprecision(15) << f1 << endl; 
// std::fixed 查看精细值, 
//     如果一个数字太大,无法使用 std::setprecision(int n) 指定的有效数位数来打印,则许多系统会以科学表示法的方式打印。
// std::setprecision(int n )将指定浮点数字的小数点后要显示的位数,而不是要显示的总有效数位数。

Exercises

Compile and run the following source code. Is the output exactly match what you expect? If not, explain why? 编译并运行以下源代码。输出是否完全符合您的预期?如果没有,请解释为什么?

#include <iostream>
//#include <iomanip>
using std::cout;
using std::endl;

int main() {
    int num1 = 1234567890;
    int num2 = 1234567890;
    int sum = num1 + num2;
    cout << "sum = " << sum << endl;
    // 2,469,135,780 but got -1,825,831,516
    // int 32位 : [-2,147,483,648, 2,147,483,647] 溢出了

    float f1 = 1234567890.0f;
    float f2 = 1.0f;
    float fsum = f1 + f2;
    cout << "fsum = " << fsum << endl; // expect 1234567891.0 but got 1.23457e+09 
    cout << "(fsum == f1) is " << (fsum == f1) << endl; ////expect 0 but got 1 ,float 精度问题,两数的量级差太多

    float f = 0.1f;
    float sum10x = f + f + f + f + f + f + f + f + f + f;
    float mul10x = f * 10;

    cout<<"sum10x = "<< sum10x << endl;
    cout<<"mul10x = "<< mul10x << endl;
    //cout << std::fixed << std::setprecision(15) << sum10x << endl;// 1.000000119209290 还是float 精度问题
    //cout << std::fixed << std::setprecision(15) << mul10x << endl;// 1.000000000000000
    cout<<"(sum10x == 1) is "<< (sum10x == 1.0) << endl; // expect 1 but got 0, 
    cout<<"(mul10x == 1) is "<< (mul10x == 1.0) << endl;
    return 0;
}

[问题处理] : 因为空间不足, 造成了wsl2错误 任何命令都显示 input/output error

# win10 powershell (管理员模式)
# 调整硬盘空间后 # 重启大法!
wsl --shutdown

#等几秒,再启动
wsl

Lab2

1 Compile and run the following program, what is the result? You need to explain the reason to a SA to pass the test.

#include <stdio.h>

int main()
{
    signed char a = 127;    // 8bit int , 范围是 [-128, 127]  二进制码 0111 1111
    unsigned char b = 0xff; // 16进制 0xff == 1111 1111 
    unsigned char c = 0;    // unsigned char 是 8bit int ,无符号位 故 0 的二进制码 0000 0000 

    a++;                    // 8bit int , 范围是 [0, 127]  二进制码 1000 0000
                            // 计算机的本意应该是要完美利用存储空间不浪费的,但是0与所谓的(-0)重复了,
    						// 这就导致了空间的浪费,所以这里规定了1000 0000是-128
                            // 1000 0000怎么转化回去呢,因为数据是被截断的,所以一定会错误,所以这里又是一个半规定的地方,
    						// 规定1000 0000就是-128。
    b++;                    // +1 后,舍弃最高位 就是 0000 0000
    c--;                    // c-- 是int运算的结果, 再由长类型窄化为短类型,而目标类型是无符号的,赋值结束后,c 的值是 255。
    printf("a=%d\nb=%d\nc=%d\n",a,b,c); //a=-128
    									//b=0
    									//c=255
    return 0;
}

2 Write a program to calculate integer multiplication: 56789 * 23456789, and then print the result. Verify the result using a calculator. If the result is wrong, what could be the reason?How to get the correct result for this exercise?

#include <iostream>
using std::cout;
using std::endl;

int main(){
    int a = 56789;                                  // int --> long long 即可
    int b = 23456789;                       		// 同上

    int c= a * b; 									// 同上
    cout << a << " * " << b << " = " << c << endl;  // expect 1,332,087,590,521 but got 647728761
                                                    // 问题 : 整型溢出
    return 0;
}

3 Run the following source code and explain the result. You need to explain the reason to a SA to pass the test

#include <iostream>
#include <iomanip>
using namespace std;

int main() 
{
    cout << fixed;
    float f1 = 1.0f; 
    cout<<"f1 = "<< std::setprecision(15) <<f1<<endl; // f1 = 1.000000000000000
    float a = 0.1f;  
    cout<<"a = "<< std::setprecision(15) <<a<<endl;   // a = 0.100000001490116
    float f2 = a+a+a+a+a+a+a+a+a+a;
    cout<<"f2 = "<<std::setprecision(15) <<f2<<endl;  // f2 = 1.000000119209290

    if(f1 == f2)
        cout << "f1 = f2" << endl;
    else
        cout << "f1 != f2" << endl;
    return 0;
}

// 浮点数精度问题,float 由于计算机精度, 没法表示任意精确的数(有限的位不能表示无限的数)

4 Run the following source code and explain the result. Why the value of a and b are not equal? Explain the division operation with different types. You need to explain the reason to a SA to pass the test.

/*Run the following source code and explain the result. 
 *Why the value of a and b are not equal? 
 *Explain the division operation with different types.
 *You need to explain the reason to a SA to pass the test.
 */

#include <iostream>
using namespace std;

int main()
{
    int a, b;
    double c, d;
    a = 19.99 + 21.99;            //会先加法,在赋值的时候才转换格式 即19.99+21.99=41.98 转换int类型 舍弃小数部分 即 41
    b = (int)19.99 + (int)21.99;  //先(显式的)格式转换, 会把小数点后的数直接舍弃, 即 19+21=40
    c = 23 / 8;                   // 整数除法 没有小数部分
    d = 23 / 8.0;                 // 浮点数除法 有小数部分
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
    cout << "d = " << d << endl;
    cout << "0/0= " << 0/0 << endl; // Floating point exception
    return 0;
}

5 What is the output of the code as follows?

/*
 * What is the output of the code as follows?  // 30
 * What is the meaning of auto                 // placeholder, 
 * when defines a variable in C++?             // Before its first use
 * You need to explain the reason to a SA to pass the test
 */
#include <iostream>
int main(){
    auto a = 10;  // int
    a = 20.5;     // 20
    a += 10.5;    // 20+10.5 = 30.5 --> 30
    std::cout << a << std::endl;
    return 0;
}