C++程序阅读常见题型

1.逻辑运算符优先级

#include <iostream>
using namespace std;

int main() {
    int a = -1, b = 2, c = 3;
    int f1, f2, f3;

    // f1 = (a++ && b || (c++))
    // a++: 由于 a 是 -1 (true),执行后 a 的值变为 0,但返回值是 -1。
    // a++ && b: 由于 a++ 为 true,b 为 2 (true),因此 "a++ && b" 为 true (1)。
    // 后续的 c++ 没有执行,因为 "a++ && b" 已经为 true,整个表达式的值已经可以确定为 true。
    f1 = (a++ && b || (c++));
    cout << f1 << endl;  // 输出 f1 = 1 (true)

    // f2 = --a || b++ && c++;
    // --a: 首先将 a 减 1,a 的值变为 -1 (true),因此 --a 为 true。
    // 由于 --a 为 true,后续的 "b++ && c++" 不会执行。
    // b 和 c 的值保持不变(b = 2, c = 3)。
    f2 = --a || b++ && c++; 
    cout << f2 << endl;  // 输出 f2 = 1 (true)

    // 重置 a 的值为 0。
    a = 0;

    // f3 = a++ && b++ && c++;
    // a++: 首先将 a 的值从 0 增加到 1,但 a++ 返回的值是 0 (false)。
    // 由于 a++ 为 false,后续的 b++ 和 c++ 不会执行。
    f3 = a++ && b++ && c++;  // f3 = 0 (false)
    cout << f3 << endl;  // 输出 f3 = 0

    // 输出 a, b, c 的当前值。
    // a = 1 (因为 a++ 已执行)
    // b = 2 (没有变化,因为 b++ 没有执行)
    // c = 3 (没有变化,因为 c++ 没有执行)
    cout << a << " " << b << " " << c << endl;  // 输出 a = 1, b = 2, c = 3

    return 0;
}

在C++中,逻辑运算符的优先级如下:

  1. 逻辑非 (!) 优先级最高。
  2. 逻辑与 (&&) 的优先级高于 逻辑或 (||)

具体优先级顺序为:

  • 逻辑非 (!)
  • 逻辑与 (&&)
  • 逻辑或 (||)

因此,逻辑与的优先级高于逻辑或。例如:

bool result = true || false && false;

按照优先级顺序,等价于:

bool result = true || (false && false);

结果为 true

如果你想改变默认的优先级,可以使用括号强制指定计算顺序。

cout << !++n + 3 << endl;

操作符优先级

  1. 前置自增运算符 ++:最高优先级,首先执行。
  2. 逻辑非运算符 !:其次执行。
  3. 加法运算符 +:最后执行。

2.ASCII 隐式转换

(21年阅读题1)

#include<iostream>
using namespace std;

int main() {
    char a = 'a';  // 变量 a 被初始化为字符 'a',ASCII 值为 97。
    cout << ++a << endl;  // 前置自增,a 变为 'b'(ASCII 98),输出 'b'。
    cout << a + 1 << endl;  // a 是 'b'(ASCII 98),98+1 = 99,输出 99(整数)。
    int b = 3.14;  // 3.14 是浮点数,但被转换为 int,只保留整数部分,b = 3。
    b /= 3;  // b = 3 / 3,整数除法,结果为 1,b = 1。
    cout << b / 3 << endl;  // b 是 1,1 / 3 进行整数除法,结果为 0,输出 0。
    bool c = a && b;  // a 是 'b'(98,非零),b 是 1(非零),因此 a && b 为 true,c = true。
    cout << (c || a ? b * 3 : a % 5) << endl;  
    // c 是 true,a 也是非零(true),所以 c || a 为 true,选择 b * 3。
    // b 是 1,所以 b * 3 = 3,输出 3。
    return 0;
}

输出 c 时,虽然它是 true,但 cout 输出 bool 类型变量时,会将 true 作为 1 输出。

3.字符串 指针

#include<iostream>
using namespace std;

int main() {
    char S[] = "Mucky";  // 定义字符数组 S,内容为 "Mucky"。
    char *p = S, *q = &S[2];  // 指针 p 指向字符串 S 的首字符,指针 q 指向 S[2] 位置,即 'c'。

    cout << S << endl;  // 输出整个字符串 S,输出结果为 "Mucky"。

    cout << --*p << endl;  
    // *p 是指针 p 所指向的内容,也就是 S[0],即 'M'。
    // --*p 是先将 'M' 自减 1,'M' 的 ASCII 值是 77,减 1 后变为 76,对应的字符是 'L'。
    // 所以这行输出 'L',并且字符串 S 变为 "Lucky"(第一个字母被修改为 'L')。

    cout << S[1] << endl;  
    // S[1] 是字符 'u',所以输出 'u'。

    cout << S + 3 << endl;  
    // S + 3 是指向字符串 S 从索引 3 开始的地址。
    // S[3] 是 'k',因此会输出从 S[3] 开始的部分字符串 "ky"。

    return 0;
}

4.继承与构造函数调用顺序

#include<iostream>
using namespace std;

class A {
    public:
        // 构造函数 A 接受一个 double 类型的参数 x,默认值为 1,输出 x。
        A (double x = 1) {
            cout << x << endl;  // 输出传入的 x 值。
        }
};

class B : public A {
    public:
        // 构造函数 B 接受两个参数 x 和 y,其中 y 有默认值 1。
        // 构造函数 B 在初始化时,显式调用了基类 A 的构造函数 A(y),然后输出 x。
        B (double x, double y = 1) : A(y) {
            cout << x << endl;  // 输出传入的 x 值。
        }
};

int main() {
    // 创建对象 b1,调用 B(1)。这里 x = 1,y 使用默认值 1。
    B b1 = B(1);
    // 调用 B(1) 时,先调用 B 的构造函数,基类 A 的构造函数 A(1) 被调用并输出 1。
    // 然后继续执行 B 的构造函数,输出 x = 1。
    
    // 创建对象 b2,调用 B(3, 2)。这里 x = 3,y = 2。
    B b2 = B(3, 2);
    // 调用 B(3, 2) 时,先调用 B 的构造函数,基类 A 的构造函数 A(2) 被调用并输出 2。
    // 然后继续执行 B 的构造函数,输出 x = 3。

    return 0;
}

5.析构函数调用顺序

#include<iostream>
using namespace std;

class A{
    public:
        // 类A的构造函数
        A(int a){
            this->a = a;        // 将传入的参数a赋值给成员变量a,此时成员变量a = 2
            initaa();           // 调用initaa()方法,修改成员变量a的值
            cout << "A" << a << endl; // 注意,这里的a是构造函数的形参a,不是成员变量a
        }
        ~A(){
            cout << "~A" << endl;   // 类A的析构函数,输出“~A”
        }
        int a;  // 公有成员变量a
    private: 
        void initaa(){
            a *= 2;     // 将成员变量a的值乘以2,此时a = 4
            aa = a * a; // 计算aa为a的平方,aa = 16
        }
        int aa; // 私有成员变量aa
};

class B : public A {
    public:
        // 类B的构造函数,默认参数y=3
        B(int x, int y=3) : A(y) {
            // 基类A的构造函数已执行完毕
            cout << "B" << a << endl; // 这里的a是从A继承的成员变量a,值为4
        }
        ~B() {
            cout << "~B" << endl; // 类B的析构函数,输出“~B”
        }
};

int main(){
    // 创建B类的对象b2,传入参数x=3, y=2
    B b2 = B(3, 2);
    return 0;
}

调用函数后会析构

showX(objX) 中,objX 被按值传递,这意味着会创建一个临时副本,因此会多一次 X 类的构造函数和析构函数调用。

#include <iostream>
using namespace std;

class X {
public:
    X() { cout << "X constructor" << endl; }
    ~X() { cout << "X destructor" << endl; }
};

class Y {
public:
    Y() { cout << "Y constructor" << endl; }
    ~Y() { cout << "Y destructor" << endl; }

    void showX(X obj) {
        cout << "Inside showX" << endl;
    }
};

int main() {
    cout << "Start" << endl;
    
    Y objY;
    X objX;

    objY.showX(objX);
    
    cout << "End" << endl;

    return 0;
}

6.快速排序

#include <iostream>
using namespace std;

// 函数声明
int partition(int arr[], int low, int high);
void quickSort(int arr[], int low, int high);
void printArray(int arr[], int size);

// 主函数
int main() {
    int arr[] = {12, 4, 9, 3, 15, 7, 8};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    cout << "原始数组: ";
    printArray(arr, n);
    
    quickSort(arr, 0, n - 1);
    
    cout << "排序后的数组: ";
    printArray(arr, n);
    
    return 0;
}

// 快速排序算法
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        // pi 是分区点,arr[pi] 已经排好序
        int pi = partition(arr, low, high);
        
        // 分别递归排序左右两部分
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

// 分区函数
int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // 选择最后一个元素为基准
    int i = (low - 1); // 小于 pivot 的元素的索引

    for (int j = low; j <= high - 1; j++) {
        // 如果当前元素小于或等于 pivot
        if (arr[j] <= pivot) {
            i++; // 增加小于 pivot 的元素的索引
            swap(arr[i], arr[j]);
        }
    }
    swap(arr[i + 1], arr[high]);
    return (i + 1);
}

// 打印数组函数
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
    cout << endl;
}

7.字符串计算

#include <iostream>
#include <string>

enum Month {
    JAN = 1, FEB, MAR, APR, MAY, JUN, 
    JUL, AUG, SEP, OCT, NOV, DEC
};

// 将月份的三字符缩写转换为对应的枚举值
int getMonthValue(const std::string& month) {
    if (month == "JAN") return JAN;
    if (month == "FEB") return FEB;
    if (month == "MAR") return MAR;
    if (month == "APR") return APR;
    if (month == "MAY") return MAY;
    if (month == "JUN") return JUN;
    if (month == "JUL") return JUL;
    if (month == "AUG") return AUG;
    if (month == "SEP") return SEP;
    if (month == "OCT") return OCT;
    if (month == "NOV") return NOV;
    if (month == "DEC") return DEC;
    return 0;  // 若没有匹配到,返回0
}

// 计算字符串中每个字符数字的和
int sumOfDigits(const std::string& str) {
    int sum = 0;
    for (char ch : str) {
        if (isdigit(ch)) {
            sum += ch - '0';  // 将字符转换为数字并累加
        }
    }
    return sum;
}

int main() {
    std::string input;
    
    while (true) {
        std::getline(std::cin, input);
        
        // 处理输入结束符 #
        if (input == "#") break;
        
        // 提取日期格式中的各个部分
        std::string day = input.substr(0, 2);
        std::string month = input.substr(3, 3);
        std::string year = input.substr(7, 4);
        
        // 计算各部分数字之和
        int daySum = sumOfDigits(day);
        int yearSum = sumOfDigits(year);
        int monthValue = getMonthValue(month);
        
        int totalSum = daySum + monthValue + yearSum;
        
        // 输出结果
        std::cout << totalSum << std::endl;
    }

    return 0;
}

8.switch和static_cast

#include <iostream>
#include <string>

using namespace std;

// 定义第一个函数,带有一个默认参数 "sun" 的函数
void func(string sun="***"){
    // for 循环,循环三次,打印 sun
    for(int i=0;i<3;i++){
        cout << sun;
    }
    cout << endl; // 换行
}

// 定义第二个函数,带有默认参数 'a'
void func(int n, char a='a'){
    // 打印字符 'a' 加上 n(整数偏移的 ASCII 值)
    cout << static_cast<char>(a+n) << endl;
}

int main() {
    // 定义一个字符串变量 sun
    string sun = "*b*c*d";
    
    // for 循环,i 从 5 开始,每次自增 1,直到 i 等于 n,即 10
    for(int i=5; i++<n;){ // 相当于 i = 6 开始
        cout << i << endl; // 输出当前的 i 值
        
        // 根据 i % 3 的结果选择不同的 case
        switch(i%3){
            // i%3 == 0 时
            case 0: 
                func(); // 调用 func(),输出 "*********"
                // 注意:没有 break,因此会继续执行下一个 case

            // i%3 == 1 时
            case 1: 
                cout << "case 1:"; // 输出 "case 1:"
                func(i%3); // i%3 == 1 时调用 func(1),打印 'b'
                break; // 结束 switch

            // i%3 == 2 时
            case 2: 
                cout << "case 2:"; // 输出 "case 2:"
                // 调用带有两个参数的 func 函数,n-9 == 1,sun[(i%2+1)*2-1] 对应 sun 字符串的某个字符
                func(n-9, sun[(i%2+1)*2-1]); 
                // sun[(i%2+1)*2-1] 计算解释:
                // i%2 == 0 时,(i%2+1)*2-1 == 1,输出 sun[1],即 'b'
                // i%2 == 1 时,(i%2+1)*2-1 == 3,输出 sun[3],即 'c'
                break; // 结束 switch
        }
    }
    return 0;
}

9.指针

int main() {
    // 初始化一个二维字符数组,包含多个字符串
    char s[][20] = {"b++", "python", "bplusplus", "basic"};
    char (*p)[20]; // 定义一个指向字符数组的指针
    
    // 输出 s[0] 的内容,即 "b++"
    cout << s[0] << endl; // 输出:b++
    
    // *(s + 1) 等价于 s[1],即 "python"
    cout << *(s + 1) << endl; // 输出:python
    
    p = s + 2; // p 指向 s[2],即 "bplusplus"
    
    // (*p)[0] 等价于 s[2][0],即 'b',通过 ++(*p)[0] 将 'b' 自增为 'c'
    cout << ++(*p)[0]; // 输出:c
    
    // *s 等价于 s[0],*s + 1 则指向 s[0] 的第二个字符,即 '+'
    cout << *s + 1 << endl; // 输出:++ (从 s[0] 的第二个字符 '+' 开始)
    
    return 0;
}

10.虚函数

#include <iostream>
using namespace std;

class A{
    public:
    virtual void func(){ cout<<"A"<<endl;}
};
class B:public A{
    public:
    void func(){ cout<<"B"<<endl;}
};
class C:public B{
    public:
    void func(){cout<<"C"<<endl;}
    private:
        int m;
};
int main() {
    A *a1 = new A();
    a1->func();//A
    A *a2 = new B();
    a2->func();//B
    A *a3 = new C();
    a3->func();//C
    C *c = new C();
    c->func();//C
    return 0;
}

11.函数递归

int fun(int m, int n)
{
    if (m == 0)
        return n + 1;
    else if (m > 0 && n == 0)
        return fun(m - 1, fun(m, n - 1));
    else if (m > 0 && n > 0)
        return fun(m - 1, fun(m - 1, n - 1));
}
int main()
{
    cout << fun(3, 4) << endl;//5
    cout << fun(2, 2) << endl;//3
    return 0;
}

12.类的对象递归调用

#include <iostream>
using namespace std;

class Counter {
public:
    Counter(int n) : num(n) { 
        cout << "Constructor called for " << num << endl; 
    }
    
    ~Counter() { 
        cout << "Destructor called for " << num << endl; 
    }

    void countDown() {
        if (num > 0) {
            Counter temp(num - 1);  // 创建一个临时对象
            temp.countDown();       // 递归调用
        }
        cout << "Counting: " << num << endl;
    }

private:
    int num;
};

int main() {
    Counter counter(3);  // 创建 Counter 对象,num 初始为 3
    counter.countDown();  // 调用递归方法
    return 0;
}

输出结果:

Constructor called for 3
Constructor called for 2
Constructor called for 1
Constructor called for 0
Counting: 0
Destructor called for 0
Counting: 1
Destructor called for 1
Counting: 2
Destructor called for 2
Counting: 3
Destructor called for 3
  • 每次递归调用都会创建一个新的 Counter 对象,并调用构造函数输出相关信息。
  • 当递归终止时(num = 0),开始回溯,在回溯的过程中依次输出 Counting: num,并销毁临时对象(调用析构函数)。

13.左移

左移一位*2 [<<]

右移一位/2 [>>]

#include <iostream>
using namespace std;

int main() {
    int x = 5, y = -3, z = 16;
    // 左移操作,将 x 左移 1 位,相当于乘以 2
    int a = x << 1;
    // 右移操作,将 y 右移 2 位,相当于除以 4(对于负数右移,符号位会保持不变)
    int b = y >> 2;
    // 将 z 左移 2 位,相当于乘以 4
    int c = z << 2;
    // 输出 a, b, c 的结果
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值