找工暂告一段落了,最近比较闲了,终于不用到外面去奔波了,在这里将自己在过去一个多月的许多的公司笔试 或面试题目小结一下,有一些代码是自己编写并测试过的在这里贴出希望对大家以后的找工能有一点帮助。具体的体验欢迎访问
http://blog.csdn.net/west_609/archive/2007/11/02/1863829.aspx
- 统计1的计数或是判断(群硕,华为)
int func( int x)
... {
int countx = 0;
while(x)
...{
countx ++;
x = x&(x-1);
}
printf("countx=%d ",countx);
return countx;
} - 关于大小端或位域(深信服)
struct mybitfields
... {
unsigned short a : 4;
unsigned short b : 5;
unsigned short c : 7;
} test;
void main()
... {
union
...{
int theinteger;
char singbyte;
}endianTest;
int a=4,*p;
test.a=1;
test.b=2;
test.c=4;
p=(short *)&test;
printf("0x%X ,0x%X ",6,*p); /**//* 0x6,0x821*/
func(6) ;
a+=(a++); /**//* a=a+(a++);*/
printf("a=%d ",a);
endianTest.theinteger=1;
printf("the singbyte is %d ",endianTest.singbyte);
getch();
} - 全排列问题(深信服)
/**/ /*定义循环左移函数(我没有用左移函数)*/
void chang( char str[], int m)
... {
int i;
char temp=str[0];
for (i=0;i<m;i++)
...{
str[i]=str[i+1];
}
str[i]=temp;
}
void pai( char str[], int m, int n) /**/ /*定义全排列函数*/
... {
int k;
void chang(char str[],int m);
if (m<n) /**//* 定 义 递 归 调 用 出 口 */
...{
for (k=0;k<=m;k++)
...{
pai(str,m+1,n); /**//*递归调用*/
chang(str,m); /**//*调用左移函数*/
}
}
else
...{
printf("%s ",str);
}
}
#include " stdio.h "
main()
... {char str[]="123"; /**//*全排列字符,可以任意多个(相应的下面排列函数中参数"4"改成全排列字符的个数)*/
clrscr();
pai(str,0,3); /**//*这里参数0(下标)表示从第一个元素开始,4表示元素个数(不是下标)*/
getch();
}
- sizeof的运算
void main()
... {
int a[]=...{3,4,5};
int b[]=...{3,4,5};
char *q[20]; /**//* q是数组,它里面的元素是指针*/
char *m[20][20]; /**//* m也是数组,它里面的元素是指针*/
int (*c)[10]; /**//* c首先是指针,是一个指向包含10个整型数值的指针*/
int i;
char str[]="hello",*p=str;
char *str2="hello";
char *p2=(char*)malloc(100*sizeof(char));
short (*ptr[100])[200];
/**//* 如果是指针则sizeof后的值是2或4(32平台),否则它如果是一个数组则就是数
组的大小(Byte)
*/
printf("sizeof(ptr)=%d ",sizeof(ptr)); /**//*200-- Array*/
printf("sizeof(ptr[0])=%d ",sizeof(ptr[0])); /**//*2-- pointer*/
printf("sizeof(*ptr[0])=%d ",sizeof(*ptr[0])); /**//*400-- Array*/
printf("sizeof(q)=%d ",sizeof(q)); /**//*40-- Array*/
printf("sizeof(m)=%d ",sizeof(m)); /**//*800- Array*/
printf("sizeof(c)=%d ",sizeof(c)); /**//*2---pointer*/
printf("sizeof(p2)=%d ",sizeof(p2)); /**//*2---pointer*/
printf("sizeof(p)=%d ",sizeof(p)); /**//*2---pointer*/
printf("sizeof(i)=%d ",sizeof(i)); /**//*2*/
printf("sizeof(a)=%d ",sizeof(a)); /**//*6-- Array*/
printf("sizeof(p2)=%d ",sizeof(p2)); /**//*2---pointer*/
printf("the length(sizeof(str) of str is = %d ",sizeof(str));/**//*6-- Array*/
printf("the length(strlen(str) of str is = %d ",strlen(str)); /**//*5*/
printf("sizeof(str2) is = %d ",strlen(str2)); /**//*5*/
printf("sizeof('ab') is = %d ",sizeof('ab')); /**//*2*/
} - 字符串的操作(深信服,群硕面试)
#include <stdio.h>char *strcpy(char *strDest, const char *strSrc)
{char *address = strDest;
if((strDest!=NULL) && (strSrc!=NULL))
while( (*strDest++ = * strSrc++) !='/0') ;
return address ;
}char *strcat1(char *strDest, const char *strSrc)
{
char *Ptr = strDest;while(*strDest)
{
strDest++;
}while((*strDest++ = *strSrc++)!='/0');return Ptr;
}int strcmp(char* str1, char* str2)
{
if((str1==NULL)&&(str2==NULL))
{
return 0;
}
else
{
while(*str1!='/0' && *str2!='/0' && *str1++==*str2++) ;
if(*str1==*str2)
{
return 0;
}
else if(*str1>*str2)
{
return 1;
}
else
{
return -1;
}
}
}/*递归字符串反转*/char* reverse(char *str)
{
int len=strlen(str);
int i=0;
char *temp1 = (char*)malloc(len/2+1);
char *temp2 = (char*)malloc(len/2+1);if(len<2)
{
return str;
}
else
{
for(i=0;i<len/2;i++)
{
temp1[i] = str[i];
}
temp1[i]=0;
strcpy(temp2,str+len/2);reverse(temp1);
reverse(temp2);
strcpy(str,temp2);
strcat(str,temp1);
return str;
}
}void main(void)
{
char a[20];
char b[6]="hello";
char *str = "pusmain";
/*strcpy(a,b);
puts(a);
strcat1(a,b);
puts(a); */
reverse(str);
puts(str);printf("the result is %d/n",strcmp(NULL,"a"));
getch();
}/**********************************************************************/
/******************************************/
/* 从str中删除remove中含有的字符 */
/******************************************/
void RemoveChar(char str[], char remove[])
{
int dst,src;
char removeArray[256];puts(str);
puts(remove);for(src=0;src<256;src++)
{
removeArray[src]=0;
}
src=0;
while(remove[src])
{
removeArray[remove[src++]]=1;
}src=0;dst=0;while(str[src])
{
if(!removeArray[str[src]])
{
str[dst++]=str[src];
}
src++;
}
str[dst]=0;
puts(str);
}void main(void)
{
char str[4]="lin";
RemoveChar("abcd","ac");
printf("the string length is =%d/n",strlen(str));
getch();
} - 可变参数的实现
/**/ /*函数参数传递*/
#include < stdio.h >
/**/ /*函数是以栈的数据结构存储:即参数从右到左入栈*/
void fun( int a, ...)
... {
int i,*temp = &a;
temp++;
for (i = 0; i < a; ++i) /**//* a表示参数的个数*/
...{
printf("-%d-", *temp);
temp++;
}
printf(" ");
}
/**/ /*ANSI标准形式的声明方式,括号内的省略号表示可选参数*/
int demo( char * msg,...)
... {
/**//*定义保存函数参数的结构*/
va_list argp;
int argno = 0;
char *para;
/**//*argp指向传入的第一个可选参数, msg指向第0个参数*/
va_start(argp, msg ); /**//*确定变参的始起地址*/
puts(*(char*)argp);
while (1)
...{ /**//* va_arg返回一个指向当前参数列表的指针,并使argp指向下一个参数*/
para = va_arg(argp,char*);
if ( strcmp(para,"") == 0 )
break;
printf("Parameter #%d is: %s ", argno, para);
argno++;
}
/**//*
OUTPUT: this is a demo
*/
va_end( argp );
/**//*将argp置为NULL*/
printf(" ");
return 0;
}
/**/ /*************************************************/
void simple_va_fun( int start, ...)
... {
va_list arg_ptr;
int nArgValue =start;
int nArgCout=0; /**//*可变参数的数目*/
va_start(arg_ptr,start); /**//*以固定参数的地址为起点确定变参的内存起始地址。 */
do
...{
++nArgCout;
printf("the %d th arg: %d ",nArgCout,nArgValue); /**//*输出各参数的值 */
nArgValue = va_arg(arg_ptr,int); /**//*得到下一个可变参数的值*/
} while(nArgValue != -1);
printf(" ");
return;
}
/**/ /*****************************************************/
void myprintf( char * fmt, ...) /**/ /* 一个简单的类似于printf的实现,//参数必须都是int 类型 */
... {
char* pArg=NULL; /**//* 等价于原来的va_list */
char c;
pArg = (char*) &fmt; /**//* 注意不要写成p = fmt !!因为这里要对//参数取址,而不是取值 */
pArg += sizeof(fmt); /**//* 等价于原来的va_start */
do
...{
c =*fmt;
if (c != '%')
...{
putchar(c); /**//* 照原样输出字符 */
}
else
...{
/**//* 按格式字符输出数据 */
switch(*++fmt)
...{
case'd':
printf("%d",*((int*)pArg));
break;
case'x':
printf("%#x",*((int*)pArg));
break;
default:
break;
}
pArg += sizeof(char*); /**//* 等价于原来的va_arg */
}
++fmt;
}while (*fmt != ' - 单词反转(例如:输入this is a book,输出:book a is this)
void Strcpy( char * str)
... {
char buf[20],*reseveStr; /**//* 每个单词的最大长度*/
int i,j=0,count,len,newstart;
len = strlen(str);
newstart = len-1;
reseveStr = malloc(len*(sizeof(char))+1);
for(i=len-1;len>0;len--)
...{
if((str[i]>='a')&&(str[i]<='z')) /**//* char */
...{
i--;
}
else
...{
for(count=0,i=i+1;i<=newstart;i++,j++,count++)
...{
reseveStr[j]=str[i];
}
reseveStr[j++]=str[i-count-1];
newstart = newstart-count-1;
i=newstart;
printf("j=%d ",j);
}
}
for(count=0,i=i+1;i<=newstart;i++,j++,count++)
...{
reseveStr[j]=str[i]; /**//* putchar(reseveStr[j]);*/
}
reseveStr[j]=' - 不用运算符实现两个数的比较
/**/ /****不用比较符号实现两个数大小的比较*************/
void max( int i, int j)
... {
if((i-j)>>31) printf("i<j");
else printf("i>j");
} - C的一些常识(迅雷)
void main( void )
... {
int sum=0,i=6,j=5;
/**//*++sum*/
(sum)=j++,j++,sum++,i++;
printf("sum=%d,j=%d,i=%d ",sum,j,i);
i=7;
j=5;
printf("i=6,j=5 i^j=0x%X ",i^j); /**//*异或操作*/
i=0;
while(i=7); /**//*没有报错,但是程序是死循环*/
getch();
} - 进制转换
#include < string .h >
#include < stdio.h >
void StrToInt( char str[])
... {
int sign=1,i,sum;
i=0;
sum=0;
if(str[i] == '-')
...{
sign=-1;
i++;
}
while(str[i])
...{
sum*=10;
sum+=str[i++]-'0';
}
sum*=sign;
printf("str=%d ",sum);
}
void IntToStr( int num)
... {
char str[10];
int i=0,temp;
if(num<0)
...{
str[i++]='-';
num*=-1;
}
do
...{
str[i++]=num%10+'0';
num=num/10;
}while(num);
str[i]=0;
printf(" the str=%s ",str);
}
void OctToBina( int a)
... {
int flag = 0,i = 15;
char str[16];
char *cd;
if(a<0)
...{
a*=-1;
flag = 1 ;
}
str[i]=0;
for(i=14;a;i--,a=a/2)
...{
str[i]=a%2+'0';
}
if(flag)
...{
str[i--]='-';
}
cd=(char*)malloc((16-i+1)*sizeof(char));
strcpy(cd,&str[i+1]);
printf("the binary is ");
puts(cd);
}
void main( void )
... {
int i=-24;
printf("%Xthe low is %X, the high is %X ",i,i&0xFF,(i>>8)&0xff);
StrToInt("-123");
IntToStr(-232);
OctToBina(-24);
getch();
} -
关键字volatile有什么含意?并给出三个不同的例子。
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量
12. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为0x67 a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。这 一 问题的实现方式随着个人风格不同而不同。典型的类似代码如下:
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;
还有一些知识点考点比较深点,就以各个公司分类了一下:
北电的考到了最小生成树的算法,估计去背是没有什么用的,因为算法是别人写的要我们去填空,它采用的是普里姆的贪婪算法。另一个是将一串打乱的字符串整理成如下的格式:最前面的是字母字符,紧随其后的是数字字符,最后的是ASCII码的其它字符,要考虑效率,我采用了Continue语句,从字符串的两头搜索。最后一道是关于快排的算法改错,相信懂得原理的都很容易找出来。
矩力的考的比较多的是操作系统的知识,如处理机的调度,还有就是变量的位置,如全局变量,局部变量等,在Linux下我们可以采用objdump这个命令查看到目标文件中变量的位置,如全局变量,如果是初始化的则放在已初始化data段,还未初始化的则放到未初始化data段,当然就存储位置来说是在静态的存储区的,局部变量相信大家都很清楚是放在栈中的,这一方面在北电一面的时候也问到了,这个知识还有另外的一些变种——就是内存分配问题,这样的题目很多公司都考,例如华为,矩力,CVT等,就是通过调用一个GetMemory函数返回一个指针,它或者是指向栈,或者是堆等,它涉及到了变量存储位置,返回值,内存泄漏等知识,这在高质量C++中有很详细的讲述,在我的空间里的另一篇文章中也有讲到所以这里就不罗嗦了。。呵呵。。。
暂时就想到这么多先,以后有的话再补充……