C++期末复习易错点

显示问题

显示 双引号“  显示反斜杠/

cout << "\\"; // 显示反斜杠    cout << "\""; // 显示双引号

字符与数字互转

int i='1'; cout<<i;为什么输出的是49

在C++中,当你将字符字面量 '1' 赋值给一个 int 类型的变量时,实际上是将字符 '1' 对应的ASCII码值赋给了这个整数变量。ASCII码中,字符 '1' 对应的十进制数值是49。

因此,当你执行 int i='1'; 后,i 的值就是49。当你使用 cout<<i; 输出时,显示的是这个整数值 49,而不是字符 '1'。如果你想让 i 存储并输出字符 '1',你应该声明 ichar 类型:

char i = '1'; std::cout << i;

这样,输出的就是字符 '1',而不是其ASCII码值 49

类型转化

char c='A';   int i=c;
    cout<<c<<endl;//A
    cout<<i<<endl;//65

float f=1000.34f;
    int j=f;
    cout<<f;//1000.34
    cout<<j;//1000
  • 当你将 float 类型的 f 赋值给 int 类型的变量 j 时,会发生类型转换。C++中的这种隐式类型转换会直接截断浮点数的小数部分,只保留整数部分,因此 j 将得到 1000(舍弃了 .34 的小数部分)。
int l=97;
    char ch=l;
    cout<<l<<endl;//97
    cout<<ch<<endl;//a
  • 当你将整数 l 赋给 char 类型的变量 ch 时,会发生类型转换。ASCII码中,97对应的小写字母是 'a',因此字符变量 ch 将获取到字符 'a'
char x='a';
    char y='c';
    cout<<x<<endl;//a
    cout<<y<<endl;//c
    cout<<(x-y)<<endl;//-2
  • 在C++中,字符 'a' 和 'c' 实际上代表的是它们在ASCII码表中的数值(小写字母'a'的ASCII值为97,'c'的ASCII值为99)。
  • 当你进行 (x - y) 运算时,实际上是将两个字符变量视为整数(即它们对应的ASCII码值)进行减法运算:97('a')- 99('c')= -2。
  • 虽然 x 和 y 是 char 类型,但在这里作为操作数参与减法运算时会隐式转换为 int 类型,因此输出结果为 -2

stew与setprection的使用

double number = 93123.1234567; cout << setw(10) << setprecision(8) << number; 

//输出  93123.123(前有2个空格)

注:setw 用于设置输出流(如 cout)上输出数据的字段宽度,如果stew设置的数字长度超过本身长度,则按实际输出。

setprecision主要用于控制输出流(如 cout)显示浮点数时的小数位数。

double a=1345.4567;
    double b=866.887234;

    cout<<setprecision(7);    cout<<a<<endl;   cout<<b<<endl;   

         cout<<fixed<<setprecision(2);
            cout<<setw(8)<<a<<endl;
            cout<<setw(8)<<b<<endl;

输出结果

1345.457

866.887

 1345.46(前有一个空格)

  866.89(前有两个空格)

分析

  • 第一行:setprecision(7) 设置了输出浮点数时的小数位数为7,但默认情况下可能仍会采用科学计数法(取决于具体的编译器和环境),因此 a 输出的结果是四舍五入到三位小数的 1345.457

  • 第二行:同理,b 输出的结果也是四舍五入到三位小数的 866.887

  • 第四行:fixed 操纵符强制接下来的浮点数以定点小数形式输出,setprecision(2) 设置了两位小数。setw(8) 设置了字段宽度为8,但由于之前设置了 fixedsetprecision(2),所以 a 输出时会在整数部分后面填充空格以达到8个字符的总宽度,并保留两位小数,结果是 " 1345.46"(注意前面有一个空格)。

  • 第五行:同样地,b 输出的结果是 " 866.89",其中也有一个空格作为前导填充物。
     

 结果溢出问题

  int x=80000000;
    while (x>0)  {  x++;}
    cout<<"x is"<<x<<endl;//x is -2147483648

变量 x 是一个32位整型(在大多数编译器中,默认 int 类型为32位),它的取值范围是 -2^312^31-1(即 -21474836482147483647)。

x 的初始值为 80000000 时,循环会不断地将 x 增加1。当 x 达到最大值 2147483647 后再加1,会发生整数溢出。整数溢出会导致 x 变成最小的负整数值 -2147483648,然后循环继续检查条件,但由于 x 已经是最小的负整数,所以不再满足 x > 0 的条件,循环结束。

同名遮蔽问题

//找出和修正以下代码的错误
void p(int i)
{
int i=5;
cout<<i<<endl;
}

这段C++代码中存在一个局部变量的同名遮蔽问题。在函数内部重新定义了与参数相同的变量名 i,导致外部传入的参数未被使用。修正后的代码应为:
 

void p(int i)
{
    // 移除内部定义,直接使用函数参数
    cout << i << endl;
}

函数调用的用法

void f(double &p)
{
    p+=2;
}
int main()
{
    double x=10;
    int y=10;
    f(x);
    f(y);
    cout<<"x is"<<x<<endl;//`12
    cout<<"y is"<<y<<endl;//10
}
  1. 函数 f(double &p) 接受一个 double 类型的引用作为参数,这意味着它可以修改传入变量的值。
  2. 在 main 函数中,首先定义了一个 double 类型变量 x 并赋值为10,然后调用了 f(x)。由于 x 是 double 类型,所以可以安全地传递给函数 f,函数内部会将 x 的值增加2,因此 x 变成了12。
  3. 然后尝试调用 f(y),其中 y 是一个 int 类型变量。虽然C++允许隐式类型转换(从 int 到 double),但是在函数调用时并未进行这样的转换,因为引用必须与它所引用的对象具有相同类型。此处编译器不会自动创建一个临时 double 对象来接收 y 的值,因此这个函数调用实际上是错误的,并且在某些编译器下会导致编译错误。

所以在实际运行时,只有对 x 的操作有效,y 的值保持不变,仍为10

void f(int x){x=100;}

void f1(int &y){y=200;}

void f2(int *z){z=300}

int main()

{ int m=0;

        f(m);cout<<<m<<endl;//0

        f1(m);cout<<m<<endl;//200

        f2(&m);cout<<m<<endl;//300

}

注:f1(m) 的调用不需要在 m 前面加 *。因为 f1 函数接受一个整型引用作为参数,所以在调用时直接传入变量 m 即可。

字符比较

​
sring s1="asd",s2="456";

string s3=s1+s2;  (  s3=asd456)//ok

string str1 = "Hello"; string str2 = "World";

​str1<str2

这里是通过字典序”比较即从左到右逐个字符对比它们的 ASCII值

char t1[20]="exe",t2[20]="ttt";

char t3[20]=t1+t2;   //wrong 因为t1和t2代表的是地址

如果要连接两个数组,可以用strcat(t1,t2);

switch 语句的匹配

    char ch = 'a';
      switch (ch)
      {
        case 'a':
        case 'A':
             cout << ch << endl; break;
        case 'b':
        case 'B':
             cout << ch << endl; break;
        case 'c':
        case 'C':
             cout << ch << endl; break;
        case 'd':
        case 'D':
             cout << ch << endl;
      }

这段代码会输出 a,因为字符变量 ch 被初始化为 'a'。在 switch 语句中,它会匹配第一个 case 条件 'a',然后执行该 case 下的语句,即输出 ch 的值并换行,接着遇到 break 语句,跳出 switch 结构。

求输出什么

int i=1;
switch ( i%3 ) {
case 0: cout<<"zero";
case 1: cout<<"one";
case 2: cout<<"two";
}
  • A. zero
  • B. one
  • C. two
  • D. one two

当 i = 1 时,i % 3 的结果是 1。程序会进入 case 1 的代码块并输出 "one",但由于没有 break 语句,它将继续执行 case 2 的代码块,输出 "two"。

switch 中的defult语句

The output of the program is:

#include <iostream>
using namespace std;
void main( )
{
int a=0,i;
for(i=1;i<5;i++)
{
switch(i)
{
case 0:
case 3:a+=2;
case 1:
case 2:a+=3;
default:a+=5;
}
}
cout<<a<<endl;//31
}

 注:此题中switch语句没有break

int a = 0, i;
for (i = 1; i < 5; i++)
{
    switch (i)
    {
        case 0:
        case 3: a += 2; // 这两个 case 下面没有 break,所以会继续执行下一个 case
        case 1:
        case 2: a += 3; // 同理,这两个 case 下面也没有 break,因此会继续执行
        default: a += 5; // 每次循环都会执行这一句,因为 i 的取值始终在 switch 范围内
    }
}
cout << a << endl;

第一次循环:a+=3+5

第二次循环:  a+=3+5

第三次循环:   a+=2+3+5

第四次循环:  a+=5

短路问题

短路与 (&&): 在逻辑与 (&&) 运算中,如果左侧表达式的值为 false,则右侧表达式将不再进行求值,因为无论右侧结果如何,整个逻辑表达式的结果已经是 false。例如:

bool a = false;
bool b = true;

if (a && someFunctionThatMayHaveSideEffects()) {
  // 如果 a 是 false,则这段代码永远不会被执行,
  // 因为 C++ 不会计算右侧的函数调用
}

短路或 (||): 在逻辑或 (||) 运算中,如果左侧表达式的值为 true,则右侧表达式将不再进行求值,因为无论右侧结果如何,整个逻辑表达式的结果已经是 true。例如:

bool a = true;
bool b = false;

if (a || someFunctionThatMayHaveSideEffects()) {
  // 如果 a 是 true,则这段代码将会执行,但右侧的函数调用不会被执行
}

 构造函数命名

构造函数能够被自动的命名当一个对象被创建的时候这句话对不对?

这句话是对的。在 C++ 中,构造函数是类的一个特殊成员函数,它负责初始化对象实例。当一个对象被创建时,编译器会自动调用与之对应的构造函数来完成初始化过程。

while中括号

1. (单选题)There is a program as follow:
int  k=0;

while(k=1) k++;

the number of while is______。



A. endless
B. has error
C. 2
D.
1



我的答案: A:endless;正确答案: A:endless;
int k=0;
while(k=1) k++;

while 循环中的条件表达式 k=1 是一个赋值语句,它将把 1 赋给变量 k 并返回 true(因为在 C++ 中非零值被视为真),这会导致循环进入无限循环状态。因此,这个循环会无限制地执行下去,也就是所谓的 "endless" 或者 "infinite loop"。所以,正确答案是 A: endless。

取模问题

-1取模于3结果是多少

-1 取模于 3 的结果是 2。

在数学中,取模运算(或称模运算)通常有以下两种定义方式:

  1. 非负除法的余数:对于整数 a 和非零整数 b,a 对 b 取模的结果是 a 除以 b 后的余数,且该余数是非负的。在这种定义下,-1 % 3 等于 2,因为 -1 除以 3 的商是 -1(向下取整),余数是 2。

  2. 同余定义:对于整数 a、b 和 n,如果存在某个整数 k,使得 a = kn + b,则称 a 对 n 取模等于 b。在这种定义下,-1 ≡ 2 (mod 3),因为 -1 = 3*(-1) + 2。

因此,在任何一种定义下,-1 取模于 3 的结果都是 2。

运算符的先后顺序

The output of the program is ____。
int x,y;
x=y=0;
while(x<15)
y++,x+=++y;
cout<<y<<","<<x;
//8,20

执行 x += ++y。这里 ++y 先使 y 自增为 2,然后将自增后的 y(即 2)与 x 相加,所以 x 变为 0 + 2 = 2。 

!运算符

while(!E),!E is equal to______。 //E == 0 

在 C/C++ 中,!E 表示对表达式 E 的逻辑非操作。它检查的是 E 的布尔值是否为假(false)。在 C/C++ 中,0 被视为逻辑假,非零值被视为逻辑真。

因此,while(!E) 将会循环执行直到 E 的值为非零(即 true)为止。

所以 !E 等价于 E == 0,正确答案是 A. E == 0。

析构函数

一个类中只能定义一个析构函数。

析构函数是与类相关联的成员函数,因此它必须在类的定义体内进行声明和(可选地)定义。不过,C++允许成员函数的定义在类外部进行,析构函数也不例外。

// 在类定义中声明析构函数
class MyClass {
public:
    // 声明析构函数
    ~MyClass();
};

// 在类外部定义析构函数
~MyClass() {
    // 析构函数的实现代码
    // 例如:释放资源、关闭文件等
}

// 或者同时声明和定义
class MyClass {
public:
    ~MyClass() {
        // 析构函数的实现直接在这里给出
    }
};

总之,尽管定义可以在类外部,但析构函数的声明总是出现在类定义内部,并且一个类只能有一个析构函数。

析构函数在 C++ 中不接受任何参数。它是一个特殊成员函数,其主要目的是在对象生命周期结束时执行必要的清理工作,例如释放内存或关闭文件等。

内联函数

Which is true the following statements?
A. Inline functions execute lower than regular functions.
B. Inline functions and regular functions cannot perform the same function. The difference is in performance and memory use.
C. Inline functions use fewer memory than regular functions.
D. Inline functions are appropriate for very short functions.
我的答案: D:Inline functions are appropriate for very short functions.;正确答案: D:Inline functions are appropriate for very short functions.;
//D

. 内联函数(Inline Functions)是在编译时被展开替换到调用处的一种优化手段。编译器并不保证一定会执行内联优化,但通常情况下,对于那些功能简单、代码量小的函数,使用内联可以减少函数调用时的开销,提高程序执行效率。内联函数并不会比常规函数运行得“更低”(这里的 A 选项表达不准确),它们的区别主要在于性能而不是功能实现(B 选项错误)。至于内存使用方面,内联函数虽然理论上可能会增加代码空间占用,但在很多情况下由于消除了函数调用开销,整体上能够提升程序速度,尤其是在函数体较小且频繁调用的情况下(C 选项提到的“较少内存”并不是内联函数的主要特点)。因此,D 选项最符合实际情况。

类中的计算问题

struct S {int a,b,c;}; 
int main() 
{
struct S m={1,2,3},n={6,5,4};
 cout<<m.cn.c+m.bn.b<<endl;
} 

这段代码中,首先结构体S的两个实例m和n被初始化如下:

struct S m = {1, 2, 3}; // m.a = 1, m.b = 2, m.c = 3
struct S n = {6, 5, 4}; // n.a = 6, n.b = 5, n.c = 4

然后在cout语句中:

cout << m.c * n.c + m.b * n.b << endl;

它计算的是m的c成员与n的c成员相乘的结果(即 3 * 4)再加上m的b成员与n的b成员相乘的结果(即 2 * 5),所以计算结果是:

3 * 4 + 2 * 5 = 12 + 10 = 22

因此,该段代码会输出22。

静态局部变量

void func();
int n=1;
int main()
{
    static int x=5;
    int y;
    y=n;
    cout<<"main x="<<x<<",y="<<y<<",n="<<n<<endl;
    func();
    cout<<"main x="<<x<<",y="<<y<<",n"<<endl;
}
void func()
{
    static int x=4;
    int y=10;
    x+=2;n+=10;y+=n;
    cout<<"func x="<<x<<",y="<<y<<",n="<<n<<endl;

}
  1. main()函数开始时,全局变量n初始化为1,静态局部变量x初始化为5,局部变量y未初始化。

  2. 执行y = n;后,局部变量y被赋值为1(因为此时n的值为1)。

  3. 输出:cout<<"main x="<<x<<",y="<<y<<",n="<<n<<endl;结果是:

    main x=5, y=1, n=1
  4. 调用func()函数:

    • 静态局部变量func()中的x初始化为4,局部变量y初始化为10。
    • x += 2;使x变为6。
    • n += 10;由于n是全局变量,在func()中也可以访问并修改其值,所以全局变量n变为11。
    • y += n;使y变为21(因为此时n的值为11)。
    • 输出:cout<<"func x="<<x<<",y="<<y<<",n="<<n<<endl;结果是:
      func x=6, y=21, n=11
  5. func()函数执行完毕后,返回到main()函数。

  6. 输出:cout<<"main x="<<x<<",y="<<y<<",n"<<endl;结果是:

    • 因为xmain()中是一个静态局部变量,它在第一次调用main()时初始化为5,并且在函数外部改变其值不影响它。因此,x仍然是5。
    • 局部变量y没有在func()调用后重新赋值,所以它仍为1。
    • 全局变量nfunc()中被修改为11。
    main x=5, y=1, n=11

综上所述,最终输出结果将是:

main x=5, y=1, n=1
func x=6, y=21, n=11
main x=5, y=1, n=11

 注:全局变量可以在函数内部被修改,并且这种修改会保留下来。在函数外部调用时,全局变量将保持最近一次修改后的值。

字符数组问题

【单选题】Given the following two arrays:
char s1[] = {'a', 'b', 'c'};
char s2[] = "abc";
Which of the following statements is correct?
A. s2 has four characters
B. s1 has four characters
C. s2 has three characters
//正确答案: A
  • 对于数组 s1[],它是一个字符数组,显式初始化了三个字符 'a', 'b', 'c',所以它有三个字符。对于数组 s2[],它是一个字符串字面量(string literal),被存储为一个包含三个字符('a', 'b', 'c')和一个空字符('\0')的字符数组。在 C++ 中,字符串字面量的末尾都会自动添加一个空字符作为结束标记。

  • 数组传递

  • (单选题)When you pass an array to a function, the function receives __________.
     A. the length of the array 
     B. a copy of the array
     C. the reference of the array
     D. a copy of the first element
    //正确答案: C:the reference of the array;
  • 实际上,C++ 中数组作为函数参数传递时,函数接收的是数组的地址(即指向数组首元素的指针)。虽然不是严格意义上的“引用”,但在效果上可以理解为接收了数组的一个引用。因此:

    一个字符储存一个字节

C++有关的英语单词

literal 字面常量   remainder 剩余的   code 编码   statement 语句   printout 打印输出

equivalent 相等的   indented 缩进排列的   even 偶数的   integer 整数    console 控制台

enter 输入   executed 执行   flowchart 流程图    sort 排序   character 字符

literal 字面量(程序中直接写明并具有固定值的量)  function 函数   digit 阿拉伯数字

letter 字母   convert 转化   declare 表明   loop 循环   variable 变量   identify 找出   table 表格

column 专栏    terminate 终止   global variables 全局变量   pass-by-value值传递 

modified 改进的   binary 二进制    decimal 十进制   hexadecimal 十六进制   declaration 声明

comparison operator 比较运算符   data filed 数据域   signature 函数签名

no-arg or no-argument无参   default 默认的   comment 注释   memory 内存   

assignment operator  赋值运算符  assignment statement 赋值语句    const keyword 关键字

constant 常量   data type 数据类型   declare variable 变量声明   expression 表达式

conditional operation 条件运算符   selection statement 分支语句   instance function 实例函数

infinite loop 无限循环   actual parameter 实参   argument 自变量   function declaration 函数声明

function overloading 函数重载   inline fuction 内联函数   local variable 局部变量   

global variable 全局变量   static local variable 静态局部变量   array 数组   index 下标

class 类   instance 实例   object 对象   state 状态  parameter list 参数列表   

return type 返回值类型   invoke 调用   reference 引用   bracket 括号   brace 大括号

parentheses 圆括号   quote 引用   positive 正数的   integer 整数   prime 质数

assign 分配   null 等于0   

补充关于类的题目

1、设计一个名为Rectangle,表示矩阵的类,类包括:

两个名为width和height的double类型的数据域,分别指明矩形的宽和高。

一个无参的构造函数,它创建一个矩形对象,width和height都是1

一个带参数的构造函数,它创建一个指定宽和高的矩形

所有数据域的访问器和更改器函数

一个名为getArea()的函数,返回矩形的面积

一个名为getPerimeter的函数,返回矩形的周长。

编写一个测试程序,它创建两个REctangle对象,将第一个矩形的宽、高设置为4,40,第二个矩形的宽、高设为3.5,35.9,并输出两个矩形对象的属性、面积和长度

#include <iostream>

class Rectangle {
private:
    double width;
    double height;

public:
    // 无参构造函数,默认宽和高为1
    Rectangle() : width(1), height(1) {}

    // 带参数构造函数
    Rectangle(double w, double h) : width(w), height(h) {}

    // 访问器(getter)函数
    double getWidth() const { return width; }
    double getHeight() const { return height; }

    // 更改器(setter)函数
    void setWidth(double newWidth) { width = newWidth; }
    void setHeight(double newHeight) { height = newHeight; }

    // 计算并返回面积的函数
    double getArea() const { return width * height; }

    // 计算并返回周长的函数
    double getPerimeter() const { return 2 * (width + height); }
};

int main() {
    // 创建两个Rectangle对象
    Rectangle rect1;
    rect1.setWidth(4);
    rect1.setHeight(40);

    Rectangle rect2(3.5, 35.9);

    // 输出两个矩形对象的属性、面积和周长
    cout << "Rectangle 1: Width=" << rect1.getWidth() 
              << ", Height=" << rect1.getHeight()
              << ", Area=" << rect1.getArea() 
              << ", Perimeter=" << rect1.getPerimeter() << endl;

    cout << "Rectangle 2: Width=" << rect2.getWidth() 
              << ", Height=" << rect2.getHeight()
              << ", Area=" << rect2.getArea() 
              << ", Perimeter=" << rect2.getPerimeter() << endl;

    return 0;
}

运行这段程序后,将会输出:

Rectangle 1: Width=4, Height=40, Area=160, Perimeter=88
Rectangle 2: Width=3.5, Height=35.9, Area=125.65, Perimeter=78.

2、设计一个名为Fan,表示一个风扇,类包括: 一个名为speed的int 类数据域,表示风扇的转速,其取值有三种,1,2或3。一个名为on的bool型数据域,表示风扇是否开启。 一个名为radius的double 型数据域,表示风扇半径。 一个无参的构造函数,创建一个缺省的风扇,其数据域speed为1,on为false,radius为5。 所有数据域的访问器和更改器函数。

换出类的UML 图,实现类。编写一个测试程序,它创建两个Fan对象,将第一个对象的转速,半径分别设置为3,10,并将它打开,第二个对象的转速,半径分别设为2,5,并将它关闭,调用访问器输出风扇属性

class Fan {
private:
    int speed;
    bool on;
    double radius;

public:
    // 无参构造函数,创建一个默认风扇
    Fan() : speed(1), on(false), radius(5.0) {}

    // 带参数构造函数
    Fan(int s, double r) : speed(s), on(false), radius(r) {}

    // 访问器(getter)函数
    int getSpeed() const { return speed; }
    bool isOn() const { return on; }
    double getRadius() const { return radius; }

    // 更改器(setter)函数
    void setSpeed(int newSpeed) {
        if (newSpeed == 1 || newSpeed == 2 || newSpeed == 3) {
            speed = newSpeed;
        } else {
            cerr << "Invalid speed! Speed should be 1, 2 or 3." << endl;
        }
    }
    
    void setOn(bool status) { on = status; }
    void setRadius(double newRadius) { radius = newRadius; }

};

int main() {
    // 创建两个Fan对象
    Fan fan1;
    fan1.setSpeed(3);
    fan1.setRadius(10.0);
    fan1.setOn(true);

    Fan fan2(2, 5.0);
    fan2.setOn(false);

    // 输出两个风扇对象的属性
    cout << "Fan 1: Speed=" << fan1.getSpeed() 
              << ", On=" << (fan1.isOn() ? "true" : "false") 
              << ", Radius=" << fan1.getRadius() << endl;

    cout << "Fan 2: Speed=" << fan2.getSpeed() 
              << ", On=" << (fan2.isOn() ? "true" : "false") 
              << ", Radius=" << fan2.getRadius() << endl;

    return 0;
}

运行这段程序后,将会输出:

Fan 1: Speed=3, On=true, Radius=10
Fan 2: Speed=2, On=false, Radius=5
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘~风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值