思索了几个C&C++实习生面试题

[TOC]

近期公司招C/C++实习生,看了一下公司面试题。觉得题目考点太偏向概念、语法题。缺少一些基本原理和实践题。 特意思索了5题。前3题关于指针/内容空间。后2题关于实践。

如有雷同,纯属巧合

题一

在C/C++中,以下代码的执行结果

char*  str = "abcd";
str[0] = '1';

答:题中str的声明类型是char,但字符串常量指向的内存空间不可写。严格来说char是个指针并不是内置字符串类型(c#/java的string )。在C++中内置字符串类型是std::string

题二

小端字节序下,printf的打印结果是

int main()
{
    short v = 0x1234;
    char* p = (char*)&v;
    printf("%x\n", *p);
    return 0;
}

答:将低位字节在低地址的称作小端字节序。题中0x12在高字节位,0x34在低字节位。打印结果是34

题三

执行以下代码打印结果是?

#include <stdio.h>
void swap(int* pLeft, int* pRight)
{
    // 交换指针
    int* tmp =pLeft;
    pLeft= pRight;    
    pRight = tmp;  
}
int main()
{
    int left = 1;
    int right = 2;
    int* pLeft = &left;
    int* pRight = &right;
    swap(ptrLeft, ptrRight);
    printf("left = %d, right = %d\n", *pLeft, *pRight);
   return 0;      
}

答:C/C++中指针类型与基本数据类型一样属于值类型,指针以值类型传递给函数,传递前后的这两个指针值没任何关系,只不过它们共同指向同一个空间(*操作符)。所以swap函数内交换指针,并不会交换指向的空间。

题四

std::cout的打印结果?

#include <iostream>
#include <vector>
/*批量删除下标元素*/
void remove(std::vector<int>& vec, int indexs[], int indexsSize)
{
    // 遍历要删除的下标
    for (inti = 0; i < indexsSize; ++i)
    {
         int realIndex = indexs[j])
         vec.erase(vec.begin() + realIndex);
     }
}
int main()
{
    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);
    
    int indexs[2] = {0, 1};
    remove(vec, indexs, 2);
    std::cout << vec[0] << std::endl;
    return 0;
}

答:遍历(读)集合时增加/删除(写)元素,操作不当对结果有很大影响。众所周知std::vector的存储结构是线性空间,删除下标0的元素,会使原来下标1的元素调整到下标0。这种素的情况下,使用倒序遍历删除元素更为安全。

题五

写出以下代码的打印结果

 //1
 vector<char> vc;
 vc.reserve(5);
 vc.resize(3);
 char* pbuf = &vc[0];
 char szT[] = "abc";
 memcpy(pbuf, &szT, sizeof(szT));
 printf("%s\n", pbuf);
 vc.push_back('d');
 vc.resize(5);
 printf("%s\n", pbuf);
 vc[4] = 'e';
 printf("%s\n", pbuf);
 vc.push_back('f');
 printf("%s\n", pbuf);
 //2
 struct stTa
 {
  char a = '1';
  char b = '2';
  char c = '3';
  char d = '4';
  char e = '5';
 };
 pbuf = &vc[0];
 printf("%s\n", pbuf);
 stTa* psta = new ((stTa*)pbuf)(stTa);
 printf("%s\n", pbuf);
 *((char*)(psta + 1)) = '6';
 printf("%s\n", pbuf);

答:考察std::vector的熟练运用和其内部线性空间的分配、释放逻辑 1. reserve(n),会将未使用的空间初始化为0。 2. resize(n),会强制将当前下标位置修改到n。 3. push_back(v),如果超出reserve(n)的大小,会重新分配空间。在例1开头记录`pbuf = &vc[0];`在执行` vc.push_back('f');`后会变成野指针。所以例2开头再重新获取。



原文:
https://lizijie.github.io/2019/11/15/%E6%80%9D%E7%B4%A2%E4%BA%86%E5%87%A0%E4%B8%AAC&C++%E5%AE%9E%E4%B9%A0%E7%94%9F%E9%9D%A2%E8%AF%95%E9%A2%98.html
作者github:
https://github.com/lizijie

PREVIOUS使用swig导出c# wraper并调用native dll
NEXT记一次修改unity3d富文本插件的设计缺陷