• 【C/C++笔试练习】常见进制转换、宏的定义和特点、sizeof与strlen、字符串函数、统计回文、连续最大和


    C/C++笔试练习

    1.常见进制转换

    (1)进制前缀

      有以下程序:

    #include
    #include
    using namespace std;
    
    int main()
    {
    	int m=0123, n=123;
    	printf("%o %o\n", m, n);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

      程序运行后的输出结果是()

      A 0123 0173    B 0123 173
      C 123 173     D 173 173

      

      在C++中,我们可以使用printf函数打印不同进制的数。以下是一些常用的格式控制符:

      %d:以十进制形式打印带符号整数(正数或负数)。

      %u:以十进制形式打印无符号整数。

      %o:以八进制形式打印无符号整数。

      %x:以十六进制形式打印无符号整数,小写abcdef表示。

      %X:以十六进制形式打印无符号整数,大写ABCDEF表示。


      如果要打印二进制,可以调用stdlib.h里面的itoa函数。

      注意,这里我们使用的是itoa函数将整数转换为相应的进制,并存储在字符数组中,然后通过printf打印出来。如果要直接打印不同进制的整数,可以使用printf的格式控制符。

    #include   
    #include   
    #include   
      
    int main() {  
        int a = 12;  
        printf("八进制 %o\n", a);  // 输出八进制的a  
        printf("十六进制 %x\n", a); // 输出十六进制的a,小写  
        printf("十六进制 %X\n", a); // 输出十六进制的a,大写  
        char s[40];  
        _itoa(a, s, 2); // 把a转为二进制并存入s数组  
        printf("二进制 %s\n", s); // 输出二进制形式的a  
        return 0;  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
      
      printf打印不同的进制有格式控制,我们也可以在十进制前加上不同的前缀表示不同的进制。

      十进制:通常我们直接表示即可。

      二进制:二进制是计算机内部处理数据所使用的数制。二进制的前缀是“0b”或“0B”,例如0b101代表二进制的101。

      八进制:八进制的前缀是“0”,例如014代表八进制的14。

      十六进制:十六进制的前缀是“0x”或“0X”,例如0xA代表十六进制的A。在十六进制中,数字0-9和字母A-F(或a-f)表示数值。

      
      结合上面的内容,m=0123和n=123就分别表示八进制的123和十进制的123,接下来printf打印的格式是%o,是以八进制打印,所以m为八进制直接打印即可,n为十进制,打印八进制需要加以转化,八进制的123用十进制表示就是173。

    在这里插入图片描述

       答案选:C
                

    (2)进制转换

       十进制变量 i 的值为100,那么八进制的变量i的值为()

       A 146       B 148
       C 144       D 142

      
      根据上面的内容可以知道,i 是十进制的100,打印八进制的 i 即可。

      在这个问题中,我们需要将一个十进制数转换为八进制数。具体来说,十进制数100需要转换为八进制数。

      转换的过程如下:

      首先,我们将100除以8,得到的结果是12余4。然后,我们将12继续除以8,得到的结果是1余4。最后,我们将1继续除以8,得到的结果是0余1。 此时,我们已经无法继续进行除法运算,因此,我们需要向上一位进位。

      所以,最终的结果是 1 4 4。其中,“1” 是进位得到的,“4” 是除以8得到的余数,“4” 是除以8得到的余数。

      因此,十进制变量 i 的值为100,那么八进制的变量i的值为 C 144。

    在这里插入图片描述

    在这里插入图片描述

       答案选:C
                

    2.宏的定义和特点

    (3)宏的定义

       下列关于C/C++的宏定义,不正确的是()

       A 宏定义不检查参数正确性,会有安全隐患
       B 宏定义的常量更容易理解,如果可以使用宏定义常量的话,要避免使用const常量
       C 宏的嵌套定义过多会影响程序的可读性,而且很容易出错
       D 相对于函数调用,宏定义可以提高程序的运行效率

      
       C++中的宏定义是一种预处理命令, 用于将标识符或一组代码替换为指定的字符串或代码块。宏定义通常用#define关键字来定义,后面跟着宏名和宏体。在源程序中,所有宏名出现的地方都会被宏体替换。 例如:

    #define SQUARE( x ) x * x
    
    SQUARE( 5 );
    
    • 1
    • 2
    • 3

       在程序中,预处理器就会用下面这个表达式替换上面的表达式:

    5 * 5
    
    • 1

      我们可以把宏看成是编译器直接替换,所以宏定义不会检查参数,有一定的安全隐患。使用常量const在一些情况下会更安全和易读,题中的说法过于绝对,应该根据具体的使用场景来选择是否使用宏定义或者const。

      相对于函数调用,宏定义在某些情况下可以提高程序的运行效率,原因如下:

      因为宏的替换,所以宏无需函数调用的开销、避免函数调用的内存分配。

      但是,宏定义并不是一种完全可替代函数调用的机制,它的使用存在一些缺点和局限性。例如,宏定义过多会影响程序的可读性,而且宏定义展开会导致代码膨胀,可能会增加程序的体积。同时宏定义的展开是在编译阶段进行的,所以无法进行类型检查、错误检查等操作。

       答案选:B
                

    (4)有关宏的计算

      下面程序的输出结果是()

    #include < iostream.h>
    
    #define SQR(A) A*A
    
    void main() 
    {
    	int x=6,y=3,z=2;
    	x/=SQR(y+z)/SQR(y+z);
    	cout< < x< < endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

      A 5      B 6
      C 1      D 0

      
      根据上面宏的直接替换规则,注意计算即可得到答案。

    在这里插入图片描述

    在这里插入图片描述

       答案选:D
                

    3.sizeof与strlen

    (5)sizeof和strlen的差别

      定义char dog[]="wang\0miao";那么sizeof(dog)与strlen(dog)分别是多少()

      A 10,4      B 4,4
      C 9,9     D 9,4

      
      sizeof和strlen的差别:

      (1)定义与本质:sizeof是一个运算符。通常在编译时,sizeof就完成了计算,其参数可以是数组、指针、类型、对象、函数等。而strlen是一个函数

      (2)计算方式与结果:sizeof是在编译时计算参数的空间大小,它返回的是该变量空间的大小, 无论是数组、指针、类型、对象还是函数,它都会根据其实际占用内存大小来返回。而strlen是在运行时计算字符串的长度,它返回的是该字符串的字符数,不包括结束符“\0”。

      (3)使用场景:sizeof常用于动态内存分配,如malloc或new等函数中, 用于确定需要分配的内存大小 。而strlen常用于字符串处理,如字符串拷贝、连接、比较等 操作中,用于确定字符串的长度。

      所以第一个sizeof(dog)的大小是从字符串开始到结束整个变量空间的大小,注意字符串结束表示是’\0’,为"wang\0miao",所以sizeof(dog)的大小是10。第二个strlen(dog)的大小是从字符串开始第一个到’\0’之前的字符数,为"wang",所以strlen(dog)的大小是4。

    在这里插入图片描述

       答案选:A
                

    4.字符串函数

    (6)strcpy和strcat函数

       下列程序的打印结果是()

    char p1[15] = "abcd", *p2 = "ABCD", str[50] = "xyz";
    strcpy(str + 2, strcat(p1 + 2, p2 + 1));
    printf("%s", str);
    
    • 1
    • 2
    • 3

       A xyabcAB       B abcABz
       C ABabcz        D xycdBCD

      
      strcpy用于将一个字符串复制到另一个地址空间。其定义如下:

      这个函数的作用是将源字符串(src)的内容复制到目标字符串(dest)中,并返回目标字符串的指针。复制包括源字符串中的’\0’结束符。

    char* strcpy(char* dest, const char* src);
    
    • 1

      
      strcat可以将两个字符串连接成一个字符串。其函数原型为:

      strcat函数将src所指向的字符串(包括"\0")复制到dest所指向的字符串的末尾(删除dest原来末尾的"\0"),并返回dest。

    char *strcat(char *dest, const char *src)
    • 1

      注意:dest所指内存区域不能与src所指内存区域重叠。dest必须有足够的空间来容纳src的字符串,否则可能会导致缓冲区溢出等问题。 此外,strcat函数在处理字符串时是不区分大小写的。如在C语言中,通过strcat函数连接字符串后,目标字符串(dest)将丢失原有的末尾"\0",因为它会被源字符串(src)的末尾"\0"替换掉。

      
    在这里插入图片描述

    在这里插入图片描述

       答案选:D
                

    5.编程题

    (7)统计回文

    统计回文

       解题思路:

       本题使用暴力循环即可,遍历str1,将str2 insert进入str1的每个位置,判断是否是回文,是就++count; 需要注意的是这里不能 str1.insert(i, str2),这样的话str1改变了,判断下一个位置就不对了。所以每次使用str1拷贝构造一个str,然后str.insert(i, str2),再判断。

    #include 
    using namespace std;
    
    //判断是否是回文函数
    bool IsCircleText(const string& str)
    {
        auto start=str.begin();
        auto end=str.end()-1;
        while(start<end)
        {
            if(*start!=*end)
            {
                return false;
            }
    
            ++start;
            --end;
        }
    
        return true;
    }
    
    int main() {
        string str1;
        string str2;
        getline(cin,str1);
        getline(cin,str2);
        //暴力循环
        size_t count=0;
        for(size_t i=0;i<=str1.size();++i)
        {
            string tmp=str1;
            tmp.insert(i,str2);//将str2插入到i的位置
            if(IsCircleText(tmp))//判断是否是回文
            {
                ++count;
            } 
        }
        cout<<count;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

                

    (8)连续最大和

    连续最大和

      状态方程式: max( dp[ i ] ) = getMax( max( dp[ i -1 ] ) + arr[ i ] ,arr[ i ] )

    #include 
    #include
    using namespace std;
    
    int GetMax(int a, int b) 
    {   //得到两个数的最大值
        return (a) > (b) ? (a) : (b);
    }
    
    int main() 
    {
        int size;
        cin >> size;
        vector<int> nums(size);
        for (size_t i = 0; i < size; ++i)
            cin >> nums[i];
        int Sum = nums[0]; //临时最大值
        int MAX = nums[0]; //比较之后的最大值
        for (int i = 1; i < size; i++) 
        {
            Sum = GetMax(Sum + nums[i], nums[i]); 
            //状态方程if (Sum >= MAX)
            MAX = Sum;
        }
        cout << MAX << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

                

  • 相关阅读:
    常用RFC规范汇总
    抽象代理模式2.0版本
    索引生命周期管理ILM看完不懂你锤我
    2022“杭电杯” 中国大学生算法设计超级联赛(4)1 2 题解
    计算机毕设(附源码)JAVA-SSM家庭安防系统
    【MyBatis】四、核心配置文件
    [MRCTF2020]你传你呢1
    AXI协议详解(9)-数据总线
    审计日志功能实现优化及测试记录(参照若依系统,以dolphinscheduler 2.0.5 为例,实现相关功能)
    mysql数据库重启、登录mysql数据库、通过命令执行mysql的sql脚本等命令
  • 原文地址:https://blog.csdn.net/Crocodile1006/article/details/133708749