个人遇到的笔试面试题目,不当之处,欢迎批评指正!(本博客左侧的连接收藏里有在线编译器)
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;
}
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下程序的执行过程?
21、快速排序和堆排序
22、位域
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、程序的活动记录
另:推荐《编程之美》,笔试面试时遇到不过相近的题目。