C/C++程序员面试秘籍

1、函数返回的参数引用

#include "stdafx.h"
#include 
#include 
using namespace std;
float f;
const float pi=3.14f;
float f1(float r)
{
	f=r*r*pi;
	return f;
}
float& f2(float r)
{
	f=r*r*pi;
	return f;
}
int main()
{
	float f1(float=5);//相当于是函数执行了一遍,没有返回值,但是为什么形参可以这样写呢,还要加上float
	float& f2(float=5);
	float a=f1();//为什么不用参数也可以匹配到
	//float& b=f1();
	float c=f2();
	float& d=f2();
	d+=1.0f;
	cout<

这里不明白其用法,需要好好看下书。

 2、指针与数组

int *a=new int[5]();//数组指针
int *c[5];//指针数组,一般作为函数指针
int (*b)[10]
以及二维动态数组的创建又忘了

3、华为题1

计算最大数字连串的问题

#include "stdafx.h"
#include   
#include
using namespace std;
unsigned int Continumax(char** pOutputstr,  char* intputstr);
unsigned int Continumax(char** pOutputstr,  char* intputstr)
{
	char *pstart=NULL,*tempstart=NULL;//最好声明的时候初始化
	int count=0,tempcount=0;

	while((*intputstr))
	{
		if(isdigit(*intputstr))
		{
			tempcount++;
			if(tempcount==1)
				tempstart=intputstr;

		}
		else
		{
			if(tempcount)
			{
				if(tempcount>=count)
				{
					pstart=tempstart;
					count=tempcount;
				}
				tempcount=0;

			}
		}
		intputstr++;
	}

	if(tempcount>=count)
	{
		pstart=tempstart;
		count=tempcount;
	}
	*pOutputstr=new char[count+1];//若不返回空串,那么会出问题
	if(count)
	memcpy(*pOutputstr,pstart,count);
	(*pOutputstr)[count]='\0';//这个地方尤其要注意,有两个问题,一个是count置0,一个是*pOutputstr
	return count;
}

4、判断IP地址是否正确

#include "stdafx.h"
#include   
#include
#include
using namespace std;
bool isIPAddressValid(const char* pszIPAddr);
bool isIPAddressValid(const char* pszIPAddr)
{	
	string IPAddr=pszIPAddr;
	cout<0)
			ip[i]=IPAddr.substr(pos1,(pos2-pos1));
		else
			return false;
		pos1=pos2+1;
	}
	pos1=IPAddr.find_last_of(".");

	if(pos1!=pos2)
		return false;
	else
		ip[3]=IPAddr.substr(pos1+1,IPAddr.length()-pos1);
	
//判断空格
	if(ip[0][ip[0].length()-1]==' ')
		return false;

	if(ip[1][ip[1].length()-1]==' '||ip[1][0]==' ')
		return false;

	if(ip[2][ip[2].length()-1]==' '||ip[2][0]==' ')
		return false;

	if(ip[3][0]==' ')//是字符而不是字符串
		return false;
//0
for(int i=0;i<4;i++)
{	
	for(int j=0;j

4、找出最大连着数字的长度
// test1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include   
#include
#include
using namespace std;
void arrange(string &input);
void arrange(string &input)
{
	int a=input.length();
	if(input.length()!=7)
	{
		cout<<"eoor input"<input[max])
					max=j;
			}
			char temp=input[i];
			input[i]=input[max];
			input[max]=temp;
		}
	}
}

int main()
{ 
	//char* intputstr = "abcd12345ed125ss123456789" ;
//	char* inputstr=NULL;//CEAedca
	string inputstr;
	getline(cin,inputstr);
	arrange(inputstr);
	cout<


9、统计单词出现的频率

 
#include
#include
#include
#include
using namespace std;
int main()
{ 
 string a;
 vector v;
 map word_map;
 getline(cin,a);
 for(int i=0;i'A'&&a[i]<'Z')
   a[i]=a[i]+('a'-'A');
 }
 //cout<max)
 {
  max=(*iter).second;
  maxstr=(*iter).first;
 }
 }
 int sec=0;
 string secstr;
  for(auto iter=word_map.begin();iter!=word_map.end();iter++)
 {
  if((*iter).second>sec &&(*iter).first!=maxstr)
  { 
   sec=(*iter).second;
   secstr=(*iter).first;
   }
 }
 //比较并记录
  /*
 int *sa=new int[v.size()]();
 int *sf=new int[v.size()]();
 for(int j=0;jsa[max])
   max=m;
   }
   if(j==0)
   {
     first=max;
     sa[max]=0;
   } 
   else
    second=max; 
 }
 cout<

总结:

(1)strng 是没有结束符的,而对于char是有结束符的

(2)一定要注意遍历的时候的溢出问题,是这个题最纠结我的地方。i没有溢出,反而是子地方溢出了

(3)以后提交的时候一定要用vs软件来开发,用.net竟然出一些这样的问题。不解释了。

(4)只用string,一定要熟记string的一些函数,如substr compare length find

(5)这里我后来不用容器来存储,我用了一个map来统计,真的非常方便,以后要经常使用它。

10、奇数偶数交叉排序,输入10个数

#include
#include
using namespace std;


int main()
{ 
	int a[20]={0};
	int od[20]={0};
	int js[20]={0};
	for(int i=0;i<10;i++)
	{
		cin>>a[i];
	}
	for(int i=0;i<9;i++)
	{
		int min=i;
		for(int j=i+1;j<10;j++)
		{
			if(a[j]

11、字符串提取数字

#include "stdafx.h"
#include   
#include
#include
using namespace std;


int main()
{ 
	string a;
	getline(cin,a);
	int *s=new int[a.length()];
	int i=0,j=0;
	int pos1=0,pos2=0;
	while(i0)
		{
		string temp=a.substr(pos1,pos2-pos1);
		s[j++]= atoi(temp.c_str());
		pos1=pos2+1;
		i=pos2;
		}
		i++;

	}
	string temp=a.substr(pos1,a.length()-pos1);//提取最后一个
	s[j]= atoi(temp.c_str());
	for(int m=0;m<=j;m++)
		cout<

方法二:

	int a[5];
	for(int i=0;i<5;i++)
	{		
		scanf("%d,",&a[i]);		
	}

思想:

(1)有时候换一种思想会轻松很多

12、动态二维数组

int main()
{ 

 int **arc;
 arc=new int*[10];
 for(int i=0;i<10;i++)
 {
	 arc[i]=new int[10];
 }

 arc[0][1]=1;
 cout<

第二章

1、sizeof的问题

#include
using namespace std;

class A
{
public:
	int num;
	char c1;
	char c2;
};	
class B
{
public:
	char c1;
	int num;
	char c2;
};	

int main()
{
	cout<

输出:8 12

 


第七章

1、多重继承与虚拟继承

#include
using namespace std;

class A
{
public:
	A():num(0){}
	A(int n):num(n){}
	int num;
};	
class B: public A
{
public:
	B(int n):A(n){}
};
class C: public A
{
public:
	C(int n):A(n){}
};
class D:public B,public C
{
public:
	D(int n):B(n),C(n+1){}
};
int main()
{
	D d(1);
	cout<

输出:12

(1)多重继承会产生二义性,因此需要d.B::num这样来操作

(2)可以用虚拟继承来解决问题,但是那样只会调用基类的默认构造函数,也就是说在所有构造之前,先调用基类的默认构造函数如下:

#include
using namespace std;

class A
{
public:
	A():num(0){}
	A(int n):num(n){}
	int num;
};	
class B: virtual public A
{
public:
	B(int n):A(n){}
};
class C: virtual public A
{
public:
	C(int n):A(n){}
};
class D:public B,public C
{
public:
	D(int n):B(n),C(n+1){}
};
int main()
{
	D d(1);
	cout<

输出:00

1、static关键字的作用?

现分析,全局静态变量、局部静态变量、静态函数的作用。

(1)无论是静态变量还是静态函数都只能在当前模块中使用。

(2)全局静态变量相当于本地的全局变量。

(3)局部静态变量即定义在函数中,当函数调用完毕之后,依然存在,且保存上次运行的值。但是别的函数不能调用它。

(4)静态函数和全局函数的区别就是在内存中只有一份,普通函数在每次被调用中维持一份复制品。

相关代码如下:

a.cpp

#include 
using namespace std;
#pragma once
int a=1;
static int b=1;
static void StaticPrint()
{
	cout<<"static print function"<
main.cpp

#include 
using namespace std;
extern void Print();
extern void StaticPrint();
extern int a;
extern int b;
int main()
{
	Print();
	//StaticPrint();//错,静态函数只能在定义模块中使用
	cout<
输出结果为:

 print function2
1
 print function3
请按任意键继续. . .

显然,第二次调用时,局部静态变量值增加。

(5)在类中static关键字的作用

a、不受private的影响,不能在类内初始化。在类外初始化方式为 int A::a=1;

b、类的非静态成员不能在静态成员函数中使用。


2、erase与algorithm中的remove有什么区别?

(1)remove是删除所有指定的元素,但是后面的元素会用原来最后的元素填充。容量不变。
(2)真正迭代器位置的删除,后面的元素会自动前移,容量改变。
#include 
#include 
#include
using namespace std;
void print(int a)
{
	cout< v(a,a+4);
	remove(v.begin(),v.end(),1);//删除所有为1的元素,但是后面的元素会用原来最后的元素填充。容量不变。
	for_each(v.begin(),v.end(),print);//记住for_each的用法
	cout<

3、反向迭代器的用法

int main()
{
	int a[4]={0,1,2,3};
	vector v(a,a+4);
	auto iter=++(++v.begin());//指向2,小心++前和++后	
	vector::reverse_iterator iter1(iter);//指向1
	vector::reverse_iterator iter2(iter1);//还是指向1,同类迭代器不变。
	vector::reverse_iterator iter3(iter);//不同迭代器,所以指向iter前一个,为1
	auto iter4(iter3);//此处默认为反向迭代器,正向迭代器是不支持这种构造函数的。所以一样。
	iter4--;
	iter3--;//后移一个,指向2
	cout<<*iter<<" "<<*iter1<<" "<<*iter2<<" "<<*iter3<<" "<<*iter4<
输出:
2 1 1 2 2
请按任意键继续. . .

基于反向迭代器这样的性质,那么:
注释掉和没有注释掉的同样输出3210
int a[4]={0,1,2,3};
	vector v(a,a+4);
	vector::reverse_iterator riter(v.end());
	vector::reverse_iterator eiter(v.begin());//不能用=赋值,只能这样构造

	/*for(auto iter=v.rbegin();iter!=v.rend();iter++)//这里auto是相当于反向迭代器,如果写成一般迭代器编译会出错
		cout<<*iter;
	cout<


4、函数对象适配器binder1st 和binder2nd.
作用:通过固定其中一个参数,将二元函数转化一元函数,和函数对象一样,同样需要重载()操作符。
用法为:
binder1st> binder(plus(),5);//这里直接调用构造函数
cout<
这里根据书上写一个函数适配器的类
template 
class my_binder1st
{
public:
	my_binder1st(){};
	my_binder1st(Operation op,Param para)
	{
		my_binder=op;
		first=para;
	}
	my_binder1st(my_binder1st &binder)
	{
		my_binder=binder.my_binder;
		first=binder.first;
	}
	Param operator ()(Param second);//重载()操作符
	my_binder1st &operator =(my_binder1st &binder);
	bool operator >(my_binder1st &binder);
	friend Param operator +(my_binder1st &binder1,my_binder1st &binder2);
	//my_binder1st mybinder(Operation,Param);
private:
	Operation my_binder;
	Param	first;
};
template 
my_binder1st mybinder(Operation op,Param para)
{
	return my_binder1st(op,para);
}
template 
Param my_binder1st::operator ()(Param second)
{
	return my_binder(first,second);
}
template 
Param my_binder1st::my(Param a)
{
	return a;
}
template 
my_binder1st &my_binder1st::operator =(my_binder1st &binder)
{
	my_binder=binder.my_binder;
	first=binder.first;
	return *this;
}
template 
bool my_binder1st::operator >(my_binder1st &binder)
{
	//my_binder1st temp;
	//temp.my_binder=binder1.my_binder;
	//temp.first=binder1.first+binder2.first;

	return binder.first>first?0:1;
}
template 
Param operator+(my_binder1st binder1,my_binder1st binder2)
 {
	my_binder1st temp;
	temp.my_binder=binder1.my_binder;
	temp.first=binder1.first+binder2.first;
	return binder1.first+binder2.first;
 }
int main()
{  
	
	my_binder1st,int> binder1=mybinder(plus(),10); //这个mybinder函数为什么不用声明就可以直接定义??
	my_binder1st,int> binder2=mybinder(plus(),15); 
	//my_binder1st,int> binder3=binder1binder2;
	if(binder1>binder2)cout<<"biger"<> binder(plus(),5);//直接调用构造函数非常方便
	cout<
注意几点:
(1)友元类实现的时候不需要用 类名::
(2)模板类声明的时候要加上 template<类型>
(3)非友元函数重载的操作符一般用 &返回类对象的引用如return *this,而对于友元函数重载的操作符一般返回对象的值。
(4) 模板类对象声明的时候一定要加上类型。












 

你可能感兴趣的:(面试/笔试)