C++笔试题合集-第一阶段

2024年9月25日23:46:07 今天你努力了吗?
一、解释代码
char * const * (*next)();
(*next) next是一个指针
const 和指针之间的关系(指向常量的指针,以及指针常量)
(*next)() next是一个函数指针
char * const  是一个指针 ,常量指针
char * const *(*next)() 
next 是一个函数指针,只想一个没有参数的函数,并且该函数的返回值是一个指针,该指针指向一个类型为char的常量指针。

二、函数指针数组
解释char *(*c[10])(int **p)
char *pt[10]; pt 是数组,数组是由10个char * 指针所组成;
char (*pt)[10];pt 是指针,指向一个由20个char元素组成的数组;
c[10] c是数组,
*c[10] c 是一个指针数组
char * (*c[10])(int **p)c数组中每一个元素都是函数指针,其指向的函数的返回值为char * ,参数为一个指向指针的指针;

三、字符串常量
char *s= "AAA";
printf("%s",s);
s[0]='B';
//s = 'B';
printf("%s",s);
1.字符串常量 "AAA" 实际上是一个 const char * 类型的指针。这意味着它指向的内存是只读的,不应该被修改。
2.当你执行 s[0] = 'B'; 时,编译器通常会发出警告,提示你不应该修改字符串常量。在某些编译器中,这可能会导致编译错误。

四、访问指定内存地址
嵌入式系统经常具有要求程序员去访问某特定的内存位置,要求读取地址的里面的内容或者想该地址写入新值,特别是在嵌入式处理器开发中操作寄存器时这种用法会经常出现。例如在某工程中,要求设置一绝对内存地址为0x40040800的位置,将改地址里面的内容设置为整型值0x3456。编写代码完成这一任务。
方法一:
int * pt;
pt = (unsigned long *)0x40020800;
*pt = 0x3456;
方法二:
#define ADDR (*(volatile unsigned long *)0x40020800)
ADDR = 0x3456;

五、#define对比typedef
typeddef在C语言中频繁用以生命一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子:
#define dPS struct s *
typedef struct s * tPS;
以上两种情况的意图都是要定义dPS 和 tPS作为一个指向结构s指针。那种方法更好呢?
dPS p1;----------------->struct s * p1;
tPS p2;
dPS p1,p2;------------------>struct s *p1, p2;
p1是结构体指针,p2是结构体s的对象。
tPS p3,p4;------------------>p3,p4都是结构体指针。
所以,typedef优于#define

2024年9月26日22:20:40 今天你努力了吗?
六、函数返回局部变量地址的问题
下面代码是否有问题,如果有问题,那么那么编译运行后的结果是什么,并说明问题的原因,并修改。
#include <stdio.h>
char * get_str();
int main(void){
    char * p = get_str();
    printf("%s\n",p);
    return 0;
}
char * get_str(void){
    char str[]= {"abcd"};
    return str;
}
在 get_str() 函数中返回了一个指向局部变量 str 的指针。这意味着当 get_str() 函数执行完毕后,str 所占用的栈内存会被回收,之后对这个指针的使用将是未定义的行为,可能导致程序崩溃或产生垃圾数据。
方法一:动态分配内存
char * str = malloc(5 * sizeof(char));(包括'\0')
方法二:传递参数

七、无符号整数和有符号整数的相加
下面所示的代码运行的结果是什么?
#include <stdio.h>
int main(void){
    unsigned int a = 6;
    int b = -20;
    (a+b > 6) ? puts(" >6 ") : puts(" <= 6");
    return 0;
}
运行结果为>6。也就是说条件表达式被判断为真。
问题:自动类型转换。a+b会自动转换。b转换为无符号类型b。
数字在电脑中是以补码的形式存储的。
当你把一个有符号整数(int b)和一个无符号整数(unsigned int a)进行加法操作时,编译器会将较小的类型转换为较大的类型。在这个例子中,b 会被转换成 unsigned int 类型,这意味着 -20 会被解释为其对应的无符号整数值。
当 -20 被转换为 unsigned int 时,它实际上变成了一个非常大的正数。这是因为无符号整数的表示范围是从 0 到 UINT_MAX,而负数的二进制补码形式在转换到无符号整数时不会改变。对于 int 类型,如果 -20 的补码形式转换到 unsigned int,结果将是 UINT_MAX - 20 + 1(假设 int 和 unsigned int 的位宽相同)。
因此,(a + b) 实际上是一个很大的数(因为 -20 转换成了一个大的正值),再加上 6 后肯定大于 6。所以,表达式 (a + b > 6) 总是为真。

八、大小端模式以及代码判别
什么是大端模式,什么是小端模式,编写并测试。
大端模式:数据高位,存储在低地址中
小端模式:数据高位,存放在高地址中
#include <stdio.h>
int main(void){
    union test {
        unsigned int n;
        char arr[4];
    };
    union test t;
    t.n = 0x12345678;
    cout << "arr[0]"<< t.arr[0] << endl;    
    cout << "arr[1]"<< t.arr[1] << endl;    
    cout << "arr[2]"<< t.arr[2] << endl;    
    cout << "arr[3]"<< t.arr[3] << endl;    
    return 0;
}

九、显示无符号int类型的最大值和最小值
评价下面代码:
unsigned int zero = 0;
unsigned int compzero = 0xffff;
该代码默认当前系统为16位。是错误的。
unsigned int min = 0;
unsigned int max = ~0;

十、逻辑与运算符,按位与运算符
考虑下面代码,其作用是在数组中查找一个特定的元素:
i = 0;
while(i < arrsize && arr[i] != x)
    i++;
假如无意中,我们用位操作运算符&代替了上面的逻辑运算符&&,如下所示:
i = 0;
while(i < arrsize & arr[i] != x)
    i++;
则当前的语句是否还能实现上面的元素查找功能?
可以实现。
原因:
逻辑运算符两侧的运算结果都是真或假。并且数组越界后的内容是可读的。

2024年9月29日00:52:55 今天你努力了吗?
十一、printf的返回值
下面这个程序的输出结果是什么?
#include <stdio.h>
int main()
{
    int i = 43;
    printf("%d\n",printf("%d",printf("%d",i)));
    return 0;
}
输出结果:4321
原因:printf的返回值是输出打印的字符的个数。

十二、#运算符 利用宏参数创建字符串
举例说明,通过#运算符,利用宏参数创建字符串。
#include <stdio.h>
#define SQUARE(X) (printf(""#x" square is : %d\n",(x) * (x)))
int main()
{
    SQUARE(2+4);
    return 0;
}

十三、##运算符,预处理符号粘合剂
#include <stdio.h>
#define XNAME(n)  x##n
int main()
{
    int XNAME(1) = 10;
    printf("%d\n",x1);
    return 0;
}


十四、结构体中用字符数组还是字符指针
阅读下面代码,看这段代码是否有问题,如果有问题请指出问题。
#include <stdio.h>
#include <string.h>
struct std
{
    unsigned int id;
    char * name;
    unsigned int age;
}per;
int main()
{
    per.id = 0001;
    strcpy(per.name,"Micheal Jackson");
    per.age = 20;
    printf("%s\n",per.name);
    return 0;
}
问题:结构体 std 中的成员 name 是一个指向 char 类型的指针。在使用前需要正确分配内存,否则会导致未定义行为(Undefined Behavior)。
可以这样修改char name[50]; // 使用固定大小的数组来存储名字

十五、内存越界
阅读下面代码、看这段代码是否有问题,如果有请指出问题
char * p1 = "ABCABC";
char * p2 = (char *)malloc(strlen(p1));
strcpy(p2,p1);
分配给 p2 的内存没有被释放。虽然在这个简短的示例中,内存泄漏可能不会立即引起问题,但在较大的程序中,累积的内存泄漏可能会导致性能下降或其他问题。
strlen:不包含“\0”
strcpy:拷贝时,包含\0;
如果要打p2所指向的内容时,可能会造成错误。

十六、free和delete怎样处理指针。
C和C++中,free()和delete是如何操作指向动态开辟内存的指针的?
free释放指针指向的内存空间,指针本身还在。
delete也是一样。

十七、字符数组和字符指针定义字符串的区别。
字符数组是一种静态的数据结构,它在声明时就确定了大小,并且在声明时分配内存。一旦分配,就不能改变大小。字符数组非常适合用于存储已知长度的字符串。
字符指针是一个指向字符的指针,它可以指向一个字符数组、一个动态分配的字符串或者一个字符串常量。

十八、编程算法之哨兵思想
哨兵算法是一种常用的编程技术,主要用于简化循环中的边界条件处理。它通过引入一个特殊的“哨兵”元素来避免复杂的边界条件检查,从而简化代码并提高效率。

十九、一条Linux源码分析
在Linux内核代码中有如下定义:
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
请解释这条语句的含义
(TYPE *)0这部分创建了一个指向类型 TYPE 的指针,并将其设置为 0(即空指针)。
(TYPE *)0->MEMBER使用指针成员运算符 -> 访问 TYPE 类型结构体的成员 MEMBER。
&(TYPE *)0->MEMBER去春member成员的地址
(size_t) &(TYPE *)0->MEMBER最终,取地址运算符的结果被转换为 size_t 类型,得到一个表示偏移量的无符号整数。
size_t = int
总结,该宏的作用就是求出MEMBER成员变量在TYPE中的偏移量。

二十、查看如下代码,写出程序运行的结果:
#include <stdio.h>
#define offsetof(TYPE , MEMBER) (size_t) & ((TYPE *)0)->MEMBER)
typedef struct s{
     union{
         int a;
         char str[10];
     };
     struct s* next;
}S;
int main(){
    printf("%d\n",offsetof(S,next));
    return 0;
}
运行结果:10(受操作系统位数影响),也就是union所占的大小。

二一、const指针与指向const的指针
#include <stdio.h>
int main()
{
    const int i = 10;
    char arr[i] = {1,2,3,4,5,6,7,8,9,10};
    printf("i = %d\n",i);
    return 0;
}
const 修饰的变量本质上还是一个变量,并不是一个真正的常量。

二二、fork函数
下面这段代码int main(){fork()||fork();}共创建几个进程?
三个进程,父进程,子进程和孙子进程

二三、按指针——引用——值传递参数
下面这段代码的输出结果为:
#include <stdio.h>
void change(int *a, int &b ,int c )
{
    c = *a;
    b = 30;
    *a = 20;
}
int main()
{
    int a = 10,b = 20,c = 30;
    change(&a,b,c);
    return 0;
}
20 30 30

二四、调用几次构造函数?
若MyClass 为一个类,执行"MyClass a[4], *p[5];语句时会自动调用该类构造函数的次数是?
4次

二五、统计二进制中1的个数
求下面函数的返回值
int func(int x)
{
    int countx = 0;
    while(x)
    {
        coutx++;
        x = x&(x-1);
    }
    return countx;
}
x&(x-1)
x-1:将二进制数从右往左数,遇到的第一个1变成0,右边的所有0变成1,左边的所有数保持不报。
x&(x-1) 从右往左数,遇到的第一个1变成0,左边的数不变,右边的数全部为0;

二六、判断一个数是不是2的n次方
编写代码,判断一个数是不是2的n次方
#define ISPOWER_OF_TWO ((x&(x-1))== 0)

二七、double&operator[](int i)和double operator[](int i) const的区别
有一个名为Student的类,该类中有两个[]运算符重载函数的声明,如下所示:
double & operator[](int i);
double operator[](int i) const;
这两个运算符重载函数的定义如下所示:
double &Student::operator[](int i)
{
    return scores[i];
}
double Student::operator[](int i) const
{
    return scores[i];
}

二八、自定义字符串拷贝函数
仿照字符串库函数strcpy,自己编写一个字符串拷贝函数,不允许使用C库函数,要求两个参数,第一个参数是要拷贝的目的地址,第二个参数是拷贝字符串的来源。
char * mystrcpy(char * dest,const char * src){
    if(dest == nullptr || src == nullptr)
        return nullptr;
    if(dest == src)
        return dest;
    while(*dest++ = * src++);
}
char * mystrcpy(char * dest,const char * src){
    char * pt = dest;
    int delta = dest - src;

    if(dest == nullptr || src == nullptr)
        return nullptr;
    if(dest == src)
        return dest;
    while(*(src + delta) = *src++);
}

二九、变量置位和清零操作
给定一个整形变量a,写两端代码,第一个设置a的bit3,第二个清除a的bit3。
a = a | (1<<3)
a = a & ~(1<<3)

三十、sizeof运算符中的表达式
请说明下面代码的运算结果:
#include <stdio.h>
int main()
{
    int i;
    i = 10;
    printf("%d\n",i);
    printf("%ld\n",sizeof(i++));
    printf("%d\n",i);
    return 0;
}
10
4
10
原因:sizeof不是函数,是运算符!sizeof(i++),不会计算i++,而是直接运算sizeof(int);

三一、指针+整数
请说明下面代码的运行结果:
unsigned char *p1;
unsigned long *p2;
p1 = (unsigned char *)0x801000;
p2 = (unsigned long *)0x801000;
请问
p1 + 5 = ?
p2 + 5 = ?
指针+1 :地址+sizeof(指向数据的类型)

三二、volatile关键字
下面的函数有什么错误:
int square(volatile int *pt){
    return (*pt) * (*pt);
}
防止编译器进行优化,确保每次获取都是最新的值,则保留 volatile 是正确的做法。

三三、C++中空类占用内存的大小
定义一个空的类,里面没有任何成员变量和成员函数,对该类求sizeof,得到的结果是多少?
结果:1.编译器给空类分配了一个隐藏的字节。

三四、如果a是个数组,则a和&a之间的区别。
指出下面代码的输出,并解释为什么。
#include <stdio.h>
int main()
{
    int a[5] = {1,2,3,4,5};
    int *pt = (int *)(&a + 1 );
    printf("%d,%d\n",*(a+1),*(pt -1));
    return 0;
}
a:数组名,表示数组中第一个元素的地址
&a:整个数组在内存中的起始地址
a+1 != &a+1
输出结果:2 5

三五、不使用第三个变量的情况下交换两个变量的值
a,b;
方法一:
a = a+b;
b = a-b;
a = a-b;

三六、运算符优先级
下面程序输出结果是什么?
#include <iostream>
using namespace std;
void max_out(int val1,int val2);
int main()
{
    int i = 10,j = 20;
    cout << "The larger of " << i << "and" << j << "is";
    max_out(i,j);
    cout << endl;
    return 0;
}
void max_out(int val1,int val2)
{
    cout << (val1 >val2)? val1:val2;
}
输出结果:0;
原因(val1 > val2)判断结果为假,0;
然后被cout输出。

三七、那种指针类型占用的内存空间大?
字符指针,浮点数指针,以及函数指针这三种类型的变量,哪个占用的内存最大,为什么?
答:大小是一样大的。

三八、交换8位整数的高4位和低4位
编写一个C函数将一个8为的整数高4位和低4位互换。例如,输入0X2C则将其改为0XC2;
void convert(unsigned int *pt)
{
    unsigned int temp = *pt &0x0f;//低四位
    *pt &= oxf0;//高四位
    *pt = (temp << 4) | (*pt >>4);
}

三九、又一道和大小端模式有关的代码
阅读如下代码后,以下说法正确的是:
#include <stdio.h>
int main()
{
    char aChar;
    int aInt;
    aInt = aChar = -120;
    printf("%d\n",aInt);
    return 0;
}
结果:可能输出-120,因为不知道是大端模式还是小端模式。

四十、一级指针和二级指针
假如有如下定义:
char *str[4] = {"ABCD","EFGH","IJKL","MNOP"};
如何定义一个指针指向str?
一级指针:int *pt;
pt指针指向的地址里面存放的是int类型的数据
二级指针:int **pt;
pt指针指向的地址里面存放的是一个指向整形变量的地址。
char **pt = str;

char *pt[] = char **pt;

2024年9月30日22:36:41 今天你努力了吗?
四一、数组X复制n个字节到数组y的最简单方式
如果从数组x复制50个字节到数组y,最简单的方式是什么?
memcpy(y,x,50);

四二、将数字字符串转换为整数
为下面这个函数原型编写函数定义:
int ascii_to_integer(char *string);
这个字符串必须包含一个或多个数字,函数应该把这些数字字符转换为整数并返回这个整数,如何字符串参数包含了任何非数字字符,函数就返回0;
{
    int value = 0;
    while(*string >= '0' && *string <= '9'){
        value *= 10;
        value += *string - '0';
        string++;
    }
    if(*string != '\0')
        return 0;
}

四三、百钱买百鸡
公鸡一只5钱,母鸡一只3钱,小鸡三只1钱。一共花了100钱,问公鸡,母鸡,小鸡各多少只?
#include <stdio.h>
int main(void)
{
    int x,y,z;
    int t;
    for(t = 0;t<4;t++){
        x = 4*t;
        y = 25-7*t;
        z = 75+3*t;
        printf("cock = %d,hen = %d, chicken = %d\n",x,y,z);
    }
    return 0;
}

四四、指针取值和自增加运算符
如何理解下述表达式的含义?
*pt++,*++pt,(*pt)++,*(pt++)
整型数组 int arr[5] = {1, 2, 3, 4, 5}; 并且有一个指向数组第一个元素的指针 int *pt = &arr[0];。
*pt++
这个表达式意味着先解引用指针 pt,然后 pt 自身递增。这意味着 pt 指向的地址将会改变。
*++pt
这个表达式意味着先递增 pt,然后解引用新的 pt。
(*pt)++
这个表达式意味着先解引用 pt,然后递增解引用后的值。
*(pt++)
这个表达式等同于 *pt++,意味着先解引用 pt,然后 pt 自身递增。

四五、typede定义函数指针类型
请问如下语句是什么意思
typedef int (*funcptr)();
funcptr 函数指针类型。
typedef 关键字用于定义一个新的类型名,给已存在的数据类型起一个别名。
int (*funcptr)(); 定义了一个名为 funcptr 的类型,这个类型是指向一个返回 int 类型值的函数的指针,而且这个函数不接受任何参数。

四六、C和C++中const关键字的区别
为什么不能在初始化和数组维度中使用const值?例如:const int n = 5;
int a[n];
数组的大小必须是一个常量表达式(constant expression)。这意味着数组的尺寸必须在编译时就能确定其值。由于 const 变量在运行时才能被初始化,所以它不是常量表达式的一部分。因此,在旧版的C++中,代码是非法的.

四七、浮点数四舍五入取整
如何对一个浮点数,进行四舍五入的方式取整?
int(x+0.5);

四八、字符数组和字符指针的区别
下面这段程序的输出结果是?
char str1[]= "abc";
char str2[] = "abc";
const char str3[] = "abc";
cosnt char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout << (str1 == str2) <<endl;
cout << (str3 == str4) <<endl;
cout << (str5 == str6) <<endl;
cout << (str7 == str8) <<endl;
输出:
0
0
1
1

四九、类中共有成员函数是否一定要通过类的对象调用
否,例如构造函数可以直接调用
对于静态成员函数来说,情况有所不同。静态成员函数不属于任何一个特定的对象实例,而是属于整个类。静态成员函数不能访问类的非静态成员变量或非静态成员函数,因为它没有 this 指针。静态成员函数可以被类名直接调用,而不需要创建类的对象实例。

五十、一道函数指针题
一个函数如下所示,简单分析下这个函数并指出这个函数的功能。
void call_each(void(**a)(void),int size)
{
    int n = size;
    while(--n >= 0){
        void(*p)(void) = *a++;
        if(p)
            (*p)();
    }
}
void(**a)(void) 是一个指向函数指针数组的指针。数组中的每个元素都是一个指向不带参数的 void 类型返回值的函数的指针。
int size 是一个整型参数,表示函数指针数组的大小,即有多少个函数指针需要被调用。
void(*p)(void) = *a++;:从指针 a 指向的位置取出一个函数指针赋值给 p,然后将 a 指向下一个元素。
if (p):检查 p 是否为非空指针。如果 p 不是 nullptr(即有效的函数指针),则执行下一步。
(*p)();:调用由 p 指向的函数。

总的来说,这个函数提供了一种机制来依次执行一组预先准备好的函数,适用于需要按顺序执行一系列操作的情况。

五一、入栈出栈的顺序
在一个栈的输入顺序为12345,下面南哥不可能是栈的输出顺序?
54132

五二、C++临时变量
假如有如下C++函数:
void bar(string &s);
为什么下面的调用是错误的?
bar("Hello World");
在C++中,函数bar(string &s);声明了一个引用类型的参数s,这意味着函数期望一个字符串变量的引用。当你尝试使用bar("Hello World");来调用这个函数时,实际上是传递了一个字符串字面值(即常量字符数组)给函数。

字符串字面值(如 "Hello World")在C++中会被转换为const char*类型,也就是指向字符数组的常量指针。然而,当你试图将其作为引用类型参数传递给函数时,编译器不允许将常量地址赋值给非常量引用。也就是说,你不能创建一个非常量引用并初始化它为常量或非常量对象的临时实例。

因此,编译器会报错,因为你在尝试将一个不可修改的字符串字面值绑定到一个可以修改的对象的引用上。

五三、任意进制的整数转换为十进制
编写一段代码,将任意一个n进制整数X转换为十进制。
#include <iostream>
#include <string>
#include <cmath>

// 函数原型声明
int n_base_to_decimal(const std::string& num, int base);

int main() {
    std::string num;
    int base;

    std::cout << "请输入n进制数: ";
    std::cin >> num;

    std::cout << "请输入基数(2-" << (int)'Z' - (int)'A' + 10 << "): ";
    std::cin >> base;

    if (base < 2 || base > 36) {
        std::cout << "基数必须在2到36之间。" << std::endl;
        return 1;
    }

    int decimalNum = n_base_to_decimal(num, base);
    std::cout << "转换后的十进制数为: " << decimalNum << std::endl;

    return 0;
}

// 将n进制数转换为十进制数
int n_base_to_decimal(const std::string& num, int base) {
    int decimalValue = 0;
    int power = 0; // 用于计算当前位的权重

    for (auto it = num.rbegin(); it != num.rend(); ++it) { // 从最低有效位开始
        int digit = isdigit(*it) ? *it - '0' : toupper(*it) - 'A' + 10;
        if (digit >= base) {
            throw std::invalid_argument("输入的数字包含不属于指定基数的数字!");
        }
        decimalValue += digit * static_cast<int>(pow(base, power));
        ++power;
    }

    return decimalValue;
}

五四、一道Lambda函数
编写一个lambda,捕获它所在的函数的int,并接受一个int参数,lambda应该返回捕获的int和int参数的和。
int a =10;
auto sum = [&](int b){cout << a+b<<endl;};
sum(20);

五五、结构体内存对齐
struct Example {
    char a;      // 1 byte
    int b;       // 4 bytes, aligned to 4 bytes
    double c;    // 8 bytes, aligned to 8 bytes
};a之后会有3个字节的填充(padding),以确保b的起始地址是4的倍数;而b之后也会有4个字节的填充,以确保c的起始地址是8的倍数。这些填充不会被使用,但它们的存在是为了满足对齐要求。

五六、结构体内存对齐
想要控制结构体的对齐方式,可以使用pragma指令来设置全局的对齐策略。
#pragma pack(push)
#pragma pack(1) // 设置对齐为1字节

struct PackedExample {
    char a;      // 无填充
    int b;       // 无填充
    double c;    // 无填充
};

#pragma pack(pop) // 恢复之前的对齐设置

五七、向前声明和不完全类型
在C++中,当一个类或结构体的完整定义不在当前作用域内可用时,我们可以通过“前向声明”来告诉编译器该类型的存在。前向声明仅提供类型名称的信息,而不包含任何成员信息,这被称为“不完全类型”。
前向声明主要用于避免头文件之间的相互依赖导致的循环包含问题,也可以用来节省编译时间,因为完整的类型定义可能相当庞大。

五八、初始化vector对象的六种方法
#include <vector>
#include <iostream>
#include <array>

int main() {
    // 1. 默认构造函数初始化
    std::vector<int> vec1; // 默认构造函数创建空vector
    
    // 2. 初始化列表构造函数
    std::vector<int> vec2 = {1, 2, 3}; // 使用初始化列表
    
    // 3. 构造函数和迭代器
    std::array<int, 3> arr = {1, 2, 3};
    std::vector<int> vec3(arr.begin(), arr.end()); // 使用迭代器范围
    
    // 4. 通过赋值操作符或成员函数
    std::vector<int> vec4;
    vec4 = {1, 2, 3}; // 使用赋值操作符
    
    std::vector<int> vec5;
    vec5.assign({1, 2, 3}.begin(), {1, 2, 3}.end()); // 使用成员函数assign()
    
    // 5. 使用std::initializer_list构造函数
    std::vector<int> vec6({1, 2, 3}); // 使用std::initializer_list
    
    // 6. 使用reserve和emplace_back
    std::vector<int> vec7;
    vec7.reserve(3); // 预留3个元素的空间
    vec7.emplace_back(1);
    vec7.emplace_back(2);
    vec7.emplace_back(3);
    return 0;
}

五九、递归显示vector对象
#include <iostream>
#include <vector>

// 递归函数,用于显示vector中的元素
void displayVectorRecursively(const std::vector<int>& vec, size_t index = 0) {
    // 基本情况:当索引等于vector的大小时,停止递归
    if (index == vec.size()) {
        return;
    }
    
    // 显示当前索引处的元素
    std::cout << vec[index] << " ";
    
    // 递归调用,处理下一个元素
    displayVectorRecursively(vec, index + 1);
}

int main() {
    // 创建一个vector并填充一些数据
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    // 调用递归函数来显示vector的内容
    displayVectorRecursively(vec);
    
    // 换行
    std::cout << std::endl;
    
    return 0;
}

六十、内存分配
查看下面代码,是否有问题?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void GetMemory(char*p);
int main(void)
{
    char *str = NULL;
    GetMemory(str);
    strcpy(str,"hello world");
    printf("%s\n",str);
}
在main函数中,char *str = NULL;声明了一个指向char的指针,并将其初始化为NULL。
然后调用GetMemory(str);,理论上应该在这个函数中为str分配内存。然而,GetMemory函数的具体实现未给出,我们无法确定它是否正确分配了内存。
如果GetMemory没有为str分配内存,那么strcpy(str, "hello world");这一行就会尝试将字符串复制到一个未分配的内存区域,这会导致未定义行为(Undefined Behavior),可能包括程序崩溃。

六一、指针的引用
void GetMemory(char * &p);
int main(void)
{
    char * str = NULL;
    GetMemory(str);
    strcpy(str,"hello world");
    cout << str << endl;
}
void GetMemory(char * & p)
{
    p = (char *)malloc(100);
}

六二、如何在类声明中定义常量
//1
enum{size = 10};
//2
static const int size = 10;
//3
publlic:
构造函数(const int size = 10){};

六三、(int &)a的输出结果
float a = 10;
cout <<(int &) a << endl;
浮点数在内存中是如何存储的,将存储的数用用整数来表示出来。

六四、假定A是一个类,执行语句A a,b(3),*pt;
将调用几次构造函数?
2次。

六五、编写左值函数,功能任意,并用完整的代码测试这个左值函数。
左值(lvalue)指的是可以出现在赋值语句左侧的值,例如变量。左值函数通常是指函数返回一个左值引用,这样可以返回一个可修改的对象。
#include <iostream>

// 左值函数:交换两个整数变量的值
void swapValues(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10;
    int y = 20;

    std::cout << "Before swapping: x = " << x << ", y = " << y << std::endl;

    // 调用左值函数
    swapValues(x, y);

    std::cout << "After swapping: x = " << x << ", y = " << y << std::endl;

    return 0;
}

六六、cout输出字符型指针
下面代码运行结果是什么?
const char * ptr = "hello world";
cout << ptr << endl;
std::cout << ptr << std::endl; 这一行将通过 std::cout 输出指针 ptr 指向的字符串内容。
std::endl 用于输出一个换行符,并刷新输出流。

六七、野指针引发的错误
下面这段代码有什么错误?
swap(int * p1,int *p2)
{
    int *p;
    *p = *p1;
    *p1 = *p2;
    *p2 = *p;
}
void swap(int * p1, int * p2)
{
    int *p;
    *p = *p1;  // 错误:p未初始化,不能解引用
    *p1 = *p2; // 错误:此时*p已被赋予了一个未知值,p1和p2的值被破坏
    *p2 = *p;  // 错误:此时*p已被赋予了一个未知值,p2的值被破坏
}

六八、引用的数组和数组的引用
引用的数组:
这是一个数组的引用,可以用来替代原数组的名字。
语法:type (&arrayRef)[size] = array;
例如:int (&arrRef)[5] = arr;
数组的引用:
这是一个数组元素的引用,可以用来替代数组中的单个元素的名字。
语法:type& elementRef = array[index];
例如:int& ref1 = arr[0];

六九、C风格字符串的安全漏洞
void test(char *str1)
{
    char string[10];
    if(strlen(str1) <=10)
        strcpy(string,str1);
}
数组 string 的大小为 10,但是它实际上只能容纳最多 9 个字符加上一个终止符 \0。这是因为 C 字符串是以 \0 作为终止符的。
因此,strlen(str1) <= 10 的条件不足以防止缓冲区溢出。

如果 str1 的长度大于 9 但小于等于 10,那么 strcpy(string, str1) 仍然会导致缓冲区溢出,因为 str1 的最后一个字符将覆盖 string 数组的终止符位置。

七十、又一道有关sizeof的笔试题
假设在64位的操作系统下,一个int类型占用四个字节,则:
1)int arr[10] = {0,1,2,3,4,5,6,7,8,9};
int * pt = arr;
那么:
sizeof(arr)是多少?40
sizeof(pt)是多少?8
2)void func(int array[])
{
    printf("size of array = %d\n",sizeof(array));
}
8

七一、编写一段C代码,查看一个文件的大小
FILE *fp;
lont int size = 0;
fopen("1.mp4","r");
fseek(fp,0,SEEK_END);
size = ftell(fp);
fclose(fp);

七二、逗号表达式
下面语句的运行结果是
int main(void)
{
    int x = 10,y = 3,z;
    printf("%d\n",z = (x%y,x/y));
    return 0;
}
 逗号表达式的一般形式:
 (表达式1,表达式2,表达式3...,表达式n) ->整个表达式的值为表达式n

 七三、输出字符指针
 下面程序输出的结果是:
 void main()
 {
     char * x = "abcd";
     x+= 2;
     cout << x;
 }
cd

七四、基类派生类构造函数和析构函数调用顺序。
构造函数的调用顺序如下:

基类构造函数:
如果派生类有基类,并且派生类的构造函数没有显式调用基类的构造函数,则默认调用基类的默认构造函数。
如果派生类的构造函数显式调用了基类的构造函数,则按照成员初始化列表中的顺序依次调用。
成员对象构造函数:
如果派生类中有成员对象,则按照成员初始化列表中的顺序依次调用成员对象的构造函数。
派生类构造函数体:
成员初始化列表中的构造完成后,进入派生类构造函数的函数体。
析构函数的调用顺序
析构函数的调用顺序则相反:

七五、浮点数与位操作
下面表达式,哪个是合法的?已知double m = 3.2;int n = 3;
!m *= n
(m+n)|n
m = 5,n = 3.1 m+n
m<<2
第三个是正确的

七六、new 运算符
假定p是具有int**类型的指针变量,则给p赋值的正确语句为:
p = new int;
p = new int[10];
p = new int *;
p = new int **;
int **p,p是指向指针的指针
第三个正确

七七、 有关构造函数的一道题
有如下程序:
class Name{
    char name[20];
    public:
    Name(){
    strcpy(name,"");
        cout << "r";
    }
    Name(const char *fname){
        strcpy(name,fname);
        sout << "r";
    }
}
int main(void)
{
    Name name[3] = {Name("rike"),Nmae("jack")};
    return 0;
}
七八、又符号数和无符号数
下面程序的输出结果是:
int main(void)
{
    char x = 0xff;
    printf("%d\n",x--);
    return 0;
}
-1;


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/440074.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL高阶2004-职员招聘人数

目录 题目 准备数据 分析数据 实现 题目 一家公司想雇佣新员工。公司的工资预算是 70000 美元。公司的招聘标准是&#xff1a; 雇佣最多的高级员工。在雇佣最多的高级员工后&#xff0c;使用剩余预算雇佣最多的初级员工。 编写一个SQL查询&#xff0c;查找根据上述标准雇…

男单新老对决:林诗栋VS马龙,巅峰之战

听闻了那场激动人心的新老对决&#xff0c;不禁让人热血沸腾。在这场乒乓球的巅峰之战中&#xff0c;林诗栋与马龙的对决无疑是一场视觉与技术的盛宴。 3:3的决胜局&#xff0c;两位选手的每一次挥拍都充满了策略与智慧&#xff0c;他们的每一次得分都让人心跳加速。 林诗栋&am…

Linux自动化构建工具Make/Makefile

make是一个命令 makefile是一个文件 touch 创建并用vim打开makefile 写入依赖对象和依赖方法 mycode是目标文件 第二行数依赖方法 以tab键开头 make makefile原理 makefile中写的是依赖关系和依赖方法 clean英语清理文件 后不用加源文件。.PHONY定义clean是伪目标。 make只…

动态SLAM总结二

文章目录 Mapping the Static Parts of Dynamic Scenes from 3D LiDAR Point Clouds Exploiting Ground Segmentation&#xff1a;&#xff08;2021&#xff09;RF-LIO&#xff1a;&#xff08;2022&#xff09;RH-Map&#xff1a;&#xff08;2023&#xff09;Mapless Online …

[C++]使用纯opencv部署yolov11-pose姿态估计onnx模型

【算法介绍】 使用纯OpenCV部署YOLOv11-Pose姿态估计ONNX模型是一项具有挑战性的任务&#xff0c;因为YOLOv11通常是用PyTorch等深度学习框架实现的&#xff0c;而OpenCV本身并不直接支持加载和运行PyTorch模型。然而&#xff0c;可以通过一些间接的方法来实现这一目标&#x…

POLYGON Nature - Low Poly 3D Art by Synty 树木植物

一个低多边形资源包,包含可以添加到现有多边形风格游戏中的树木、植物、地形、岩石、道具和特效 FX 资源。 为 POLYGON 系列提供混合样式树这一新增功能。弥合 POLYGON 与更传统的层级资源之间的差距。还提供了一组经典的 POLYGON 风格的树木和植被以满足你的需求。 该包还附带…

系统安全 - Linux /Docker 安全模型及实践

文章目录 导图Linux安全Linux 安全模型用户层权限管理的细节多用户环境中的权限管理文件权限与目录权限 最小权限原则的应用Linux 系统中的认证、授权和审计机制认证机制授权机制审计机制 小结 内网安全Docker安全1. Docker 服务隔离机制Namespace 机制Capabilities 机制CGroup…

JavaWeb - 8 - 请求响应 分层解耦

请求响应 请求&#xff08;HttpServletRequest&#xff09;&#xff1a;获取请求数据 响应&#xff08;HttpServletResponse&#xff09;&#xff1a;设置响应数据 BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程…

Oracle中MONTHS_BETWEEN()函数详解

文章目录 前言一、MONTHS_BETWEEN()的语法二、主要用途三、测试用例总结 前言 在Oracle数据库中&#xff0c;MONTHS_BETWEEN()函数可以用来计算两个日期之间的月份差。它返回一个浮点数&#xff0c;表示两个日期之间的整月数。 一、MONTHS_BETWEEN()的语法 MONTHS_BETWEEN(dat…

水下声呐数据集,带标注

水下声呐数据集&#xff0c;带标注 水下声呐数据集 数据集名称 水下声呐数据集 (Underwater Sonar Dataset) 数据集概述 本数据集是一个专门用于训练和评估水下目标检测与分类模型的数据集。数据集包含大量的水下声呐图像&#xff0c;每张图像都经过专业标注&#xff0c;标明…

vSAN05:vSAN延伸集群简介与创建、资源要求与计算、高级功能配置、维护、故障处理

目录 vSAN延伸集群延伸集群创建延伸集群的建议网络配置vSAN延伸集群的端口见证主机的资源要求vSAN延伸集群中见证节点带宽占用vSAN延伸集群的允许故障数vSAN延伸集群不同配置下的空间占用 vSAN延伸集群的HA配置vSAN延伸集群的DRS配置vSAN存储策略以及虚拟机/主机策略的互操作vS…

华为最新业绩出炉!上半年营收4175亿元,同比增长34%!

华为2024年上半年经营业绩分析:稳健发展,符合预期 [中国,深圳,2024年8月29日] 今日,华为发布了其2024年上半年的经营业绩,整体表现稳健,结果符合预期。在复杂多变的全球市场环境下,华为凭借强大的创新能力和市场洞察力,实现了销售收入和净利润的显著增长。 上半年,华…

C语言:预编译过程的剖析

目录 一.预定义符号和#define定义常量 二.#define定义宏 三.宏和函数的对比 四、#和##运算符 五、条件编译 在之前&#xff0c;我们已经介绍了.c文件在运行的过程图解&#xff0c;大的方面要经过两个方面。 一、翻译环境 1.预处理&#xff08;预编译&#xff09; 2.编译 3…

Spring Boot 整合 Keycloak

1、概览 本文将带你了解如何设置 Keycloak 服务器&#xff0c;以及如何使用 Spring Security OAuth2.0 将 Spring Boot 应用连接到 Keycloak 服务器。 2、Keycloak 是什么&#xff1f; Keycloak 是针对现代应用和服务的开源身份和访问管理解决方案。 Keycloak 提供了诸如单…

Unity MVC框架演示 1-1 理论分析

本文仅作学习笔记分享与交流&#xff0c;不做任何商业用途&#xff0c;该课程资源来源于唐老狮 1.一般的图解MVC 什么是MVC我就不说了&#xff0c;老生常谈&#xff0c;网上有大量的介绍&#xff0c;想看看这三层都起到什么职责&#xff1f;那就直接上图吧 2.我举一个栗子 我有…

人工智能新闻和发展 (24001)- By 10/4/2024

1. 谷歌增强了搜索中的人工智能&#xff0c;允许对图像进行语音提问。 Google adding AI to answer voiced questions about images | AP NewsGoogle is pumping more artificial intelligence into its search engine. New features will enable people to voice questions a…

15分钟学 Python 第39天:Python 爬虫入门(五)

Day 39&#xff1a;Python 爬虫入门数据存储概述 在进行网页爬虫时&#xff0c;抓取到的数据需要存储以供后续分析和使用。常见的存储方式包括但不限于&#xff1a; 文件存储&#xff08;如文本文件、CSV、JSON&#xff09;数据库存储&#xff08;如SQLite、MySQL、MongoDB&a…

无神论文解读之ControlNet:Adding Conditional Control to Text-to-Image Diffusion Models

一、什么是ControlNet ControlNet是一种能够控制模型生成内容的方法&#xff0c;能够对文生图等模型添加限制信息&#xff08;边缘、深度图、法向量图、姿势点图等&#xff09;&#xff0c;在当今生成比较火的时代很流行。 这种方法使得能够直接提供空间信息控制图片以更细粒…

PCL 1.8.1 + VTK 1.8.0 + QT5.14.2+ VS2017 环境搭建

先看看效果: PCL 1.8.1下载安装: Tags PointCloudLibrary/pcl GitHub 安装完成后: 如果VTK想重新编译的,可以看我的这篇博客:

Spring14——案例:利用AOP环绕通知计算业务层接口执行效率

前面介绍了这么多种通知类型&#xff0c;具体该选哪一种呢? 我们可以通过一些案例加深下对通知类型的学习。 34-案例&#xff1a;利用AOP环绕通知计算业务层接口执行效率 需求分析 这个需求也比较简单&#xff0c;前面我们在介绍AOP的时候已经演示过: 需求:任意业务层接口…