面试题总结

个人遇到的笔试面试题目,不当之处,欢迎批评指正!(本博客左侧的连接收藏里有在线编译器)

1、strcpy()的写法.
        题目:已知strcpy函数的原型是char * strcpy(char * Dest, const char * Src);
        1、不调用库函数,实现strcpy函数。
        2、解释为什么要返回char *。//返回指针是为了方便链式操纵,比如连续拷贝

char * strcpy(char * Dest, const char * Src)
{
	   if ((Dest == NULL)||(Src == NULL)) 
	        return NULL; 
	    char * DestCopy = Dest;  
	    while ((*Dest++ = *Src++) != '\0');
	    return DestCopy;
}

2、写出下面程序段输出:

#include <stdio.h>

int main() {
    char p[] = "\\\bSRE\0abc\\\b\n";
    printf("%d %d\n", strlen(p),sizeof(p));
    printf("%%s = %s", p);

    return 0;
}

3、写程序,字符串和整数的相互转换。

#include <iostream>
#include <string>
using namespace std;

int myatoi(const char *s) {//字符串转换成整数
    int i, sign, num;
    for(i = 0; isspace(s[i]); i++);//跳过字符串前面的空格
    
    if (s[i] == '-')
        sign = -1;
    else 
        sign = 1;

    if(s[i] == '-' || s[i] == '+') i++;//符号位

    for(num = 0; isdigit(s[i]); i++) {//遇到非数字字符就结束循环
        num = 10 * num + s[i] - '0';
    }
    return sign * num;
}

void reverse(char *s) {
    char *p = s;
    int len = 0;
    while(*p++ != '\0') len++;
    for(int i = 0, j = len-1; i <=j; i++, j--) {
        s[i] = s[i] ^ s[j];
        s[j] = s[i] ^ s[j];
        s[i] = s[i] ^ s[j];
    }
}

void myitoa(int num, char *s) {//整数置换成字符串
    int sign = 1;
    if(num < 0) {
        num = -num;
        sign = -1;
    }

    int i = 0;
    do{
        s[i++] = num % 10 + '0';
        num /= 10;
    }while(num > 0);

    if(sign == -1)
        s[i++] = '-';
    s[i] = '\0';

    reverse(s);

}

int main() {
    char str[] = " -1234567a8";
    int num = -1234567;

    cout << myatoi(str) << endl;
    myitoa(num, str);
    cout << str << endl;

    return 0;
}

4、写程序,统计一个字符串中单词的数量(不进行合法性检查)。

#include <iostream>
#include <string>
using namespace std;


int wordnums( char *s) {

    if(s == NULL)
        return 0;
    int num = 0;

    char *pchar = s;

    while(*pchar != '\0') {

        while(*pchar == ' ') pchar++;//去除空格

        while(*pchar != ' ' && *pchar != '\0') pchar++;
        num++;

        while(*pchar == ' ') pchar++;//去除空格
    }
    return num;
}

int main() {
    char str[] = " Hello Nice to meet you!";
    cout << wordnums(str) << endl;

    return 0;
}

5、找出1--N之间的所有素数。

//神的代码 找出MAXN中的素数
#include <iostream>
using namespace std;
const int MAXN = 65535;
bool prime[MAXN + 1];

int main(){ 
    for (int i = 0; i <= MAXN; ++i) { //对非偶数标true
        prime[i] = true;
        if (!(i & 1)) {
            prime[i] = false;
        }
    }
    prime[1] = false; //0和1非素数标fales
    prime[2] = true; //对2标true

    for (int i = 3; i * i <= MAXN; i += 2) {
        if (prime[i]) {
            for (int j = i + i; j <= MAXN; j += i) { //碰见true往后加i,标false
                 prime[j] = false;
            }
        }
    }
    return 0;
}


6、下面程序的输出是:

#include <iostream>
#include <string>
using namespace std;

void func(char str[50]) {
    printf("A %d B %d\n",sizeof(str), strlen(str));
}
int main()
{
    char stra[] = "HelloWorld";
    char *strb = stra;
    printf("C %d D %d\n", sizeof(stra), sizeof(strb++));
    func(++strb);
    printf("E %d F %d\n", strlen(stra), strlen(strb++));
    return 0;
}


7、下面程序的输出是:

#include <iostream>
#include <string>
using namespace std;

int count = 3;
int main()
{
    int i, sum, count = 2;
    for(i = 0, sum = 0; i < count; i += 2, count++) {
        static int count = 4;
        count ++;
        if(i % 2 == 0) {
            extern int count;
            count ++;
            sum += count;
        }
        sum += count;
    }
    printf("%d %d\n", count, sum);
    return 0;
}


8、读程序:

#include<iostream>
using namespace std;
 
class Base
{
public:
         Base(){ cout << "construct in Base" << endl;}
         Base (Base & b) {cout << "copy in Base" << endl;}
         ~Base(){cout << "deconstruct in Base" << endl;}
         int a;

};

class Derive: public Base
{
public:
         Derive(){cout << "construct in Derive" << endl;}
         Derive(Derive & b) {cout << "copy in Derive" << endl;}
         ~Derive(){cout << "deconstruct in Derive" << endl;}
         Derive getderive(Derive a) {return a;}
};

int main()
{
         Derive d;
         Derive a = d.getderive(d);
         return 0;
}


9、读程序:

#include<iostream>
using namespace std;
 
int main()
{
    int *p1 = new int[10];
    int *p2 = new int[10]();
    for(int i = 0; i < 10; i++) 
        cout << *(p1 + i) << " " << *(p2 + i) << endl;

    return 0;
}


10、读程序:

#include <iostream>
using namespace std;
int &f1() {
    int i = 1;
    return i;
}
int g1() {
    int j = 3;
    return j;
}
int f(int i) {
    return ++i;
}
int g(int &i) {
    return ++i;
}

int main () {
    int &ri = f1();
    int rj = g1();
    cout << ri << endl;
    cout << rj << endl;

    int a = 0;
    a += f(g(a));
    cout << a << endl;
    return 0;
}

11、如何判断当前系统是大端还是小段?

#include <stdio.h>

int main() {

    short int x;
    char x0,x1;
    x=0x1122;

    x0=((char*)&x)[0]; //低地址单元
    x1=((char*)&x)[1]; //高地址单元

    if(x0 == 0x11) printf("little-endian \n");
    else printf("big-endian \n");
    return 0;
}


12、如何判断当前编译器是C++ 还是C ?

#include <stdio.h>

int main() {

#ifdef __cplusplus
    printf("C++ compiler!\n");
#else
    printf("C compiler!\n");
#endif

    return 0;
}

13、读程序:

编译器会对const修饰的变量进行优化。

#include <iostream>
using namespace std;
int main () {
    const int a = 10;
    const int *p = &a;
    //int a = 10;
    //int *p = &a;


    *(int *) p = 100; 
    cout << p << " " << &a << endl;
    cout << a << endl;
    cout << *p << endl;

    return 0;

}

15、读程序:(虚拟继承)

#include <iostream> 

using namespace std; 

  
class Vehicle 
{ 
    public: 
        Vehicle(int weight = 0) 
        { 
            Vehicle::weight = weight; 
            cout<<"载入Vehicle类构造函数"<<endl; 
        } 
        void SetWeight(int weight) 
        { 
            cout<<"重新设置重量"<<endl; 
            Vehicle::weight = weight; 
        } 
        virtual void ShowMe() = 0; 
    protected: 
        int weight; 
}; 

class Car:virtual public Vehicle//汽车,这里是虚拟继承 
{ 
    public: 
        Car(int weight=0,int aird=0):Vehicle(weight) 
        { 
            Car::aird = aird; 
            cout<<"载入Car类构造函数"<<endl; 
        } 
        void ShowMe() 
        { 
            cout<<"我是汽车!"<<endl; 
        } 

    protected: 
        int aird; 

}; 


class Boat:virtual public Vehicle//船,这里是虚拟继承 
{ 
    public: 
        Boat(int weight=0,float tonnage=0):Vehicle(weight) 
        { 
            Boat::tonnage = tonnage; 
            cout<<"载入Boat类构造函数"<<endl; 
        } 
        void ShowMe() 
        { 
            cout<<"我是船!"<<endl; 
        } 
    protected: 
        float tonnage; 
}; 

class AmphibianCar:public Car,public Boat//水陆两用汽车,多重继承的体现 
{ 
    public: 
        AmphibianCar(int weight,int aird,float tonnage) 
        :Vehicle(weight),Car(weight,aird),Boat(weight,tonnage) 
        //多重继承要注意调用基类构造函数 
        { 
            cout<<"载入AmphibianCar类构造函数"<<endl; 
        } 
        void ShowMe() 
        {
            cout<<"我是水陆两用汽车!"<<endl; 
        } 
        void ShowMembers() 
        { 
            cout<<"重量:"<<weight<<"吨,"<<"空气排量:"<<aird<<"CC,"<<"排水量:"<<tonnage<<"吨"<<endl; 
        } 
}; 

int main() 
{ 
    AmphibianCar a(4,200,1.35f); 
    a.ShowMe(); 
    a.ShowMembers(); 
    a.SetWeight(3); 
    a.ShowMembers(); 
    cout << sizeof(Vehicle ) << endl;
    cout << sizeof(Car ) << endl;
    cout << sizeof(Boat) << endl;
    cout << sizeof(AmphibianCar) << endl;
    return 0;
}


/*
我们在Car类和Boat类继承Vehicle类时,在前面加上virtual关键字就可以实现虚拟继承,使用虚拟继承后,当系统碰到多重继承的时候就会自动先加入一个Vehicle的拷贝,当再次请求一个Vehicle的拷贝的时候就会被忽略,保证继承类成员函数的唯一性。
*/

16、如何禁止在堆中创建对象?

#include <iostream>
using namespace std;

class OnlyStack
{
public:
    OnlyStack(int i_):i(i_){}
    void print() const
    {
        cout<<"member i = "<<i<<endl;
    }
private:
    void* operator new (size_t t);
    void operator delete(void* ptr);
private:
    int i;
};
int main () {
    //OnlyStack * ptr = new OnlyStack(5);
    //ptr->print();
    OnlyStack b(3);
    b.print();
    return 0;
}

17、实现memcpy,声明如下:
void *memcpy(void *dest, const void *src, size_t num)

void *memcpy(void *dest, const void *src, size_t num) {
	const char *s = (char *) src;
	char *t = (char *) dest;

	while(num--)
		*t++ = *s++;

	return dest;
}


18、读程序.

#include <stdio.h>
int func(int n)
{
    int k = 1;
    if(n > 0){
         k += func(--n);
         printf("%d ", n);
         k += func(--n);
    }
    return k;
}
int main(void)
{
    int a = 3;
    printf("%d\n",func(a));
    return 0;
}

19、linux开启过程?linux下程序的执行过程?

20、限制一个类对象只在堆上分配或者只在栈上分配

21、快速排序和堆排序

22、位域

23、如何确定程序中栈的增长方向

24、给定一个字符串,按单词将该字符串逆序,如输入"hello world",输出为"world hello"。方法:先按单词逆序,再对整个句子逆序。

//给定一个字符串,按单词将该字符串逆序,不包括标点

#include<stdio.h>

//p和q之间的逆序
void ReverseWord(char *p, char *q) {
	while(p < q) {
		*p = *p ^ *q;
		*q = *p ^ *q;
		*p = *p++ ^ *q--;
	}
}

char *ReverseSentence(char *s) {
	char *p = s;
	char *q = s;
	while(*q != '\0') {
		if(*q == ' ') {//查到一个单词
			ReverseWord(p,q-1);
			q++; //指向下一个单词道字符
			p = q;
		}
		else
			q++;
	}
	ReverseWord(p, q-1);//逆序最后一个单词
	ReverseWord(s, q-1);//整个句子逆序

	return s;
}

int main( ) {

	char s[] = "I am glad to see you";

	printf("%s\n", s);
	ReverseSentence(s);
	printf("%s\n", s);

	return 0;
}

25、内存的分配方式有哪几种?

    静态存储区分配:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,如全局变量、static变量;
    在栈上创建:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但容量有限。
    从堆上分配:变称为动态内存分配。使用malloc/net申请,用free/delete释放。动态内存的生存期由程序员决定,使用灵活,但容易出现内存泄漏。频繁地分配和释放不同大小的堆空间将会产生堆内碎片。

26、程序的活动记录


另:推荐《编程之美》,笔试面试时遇到不过相近的题目。

你可能感兴趣的:(面试题总结)