曾经碰到的面试题目

来源:互联网 发布:java编程思想有第5版吗 编辑:程序博客网 时间:2024/05/22 13:37

一,程序段输出:

(1)
Int sum = 0;
For(int i=0;i<10;i++,sum+=i);
      Printf(“%d”,sum);
Sum的值是55而不是45。因为:0+1+2+3+4+5+6+7+8+9+  10  =55,注意最后有项I++。
(2)

Int x = 3;
Do
{
     Printf(“%d”,x-=2);
}while(!(--x))
输出是:1-2。X=3-2=1,首先x得1。--x是先自减得0,!0得1,while(1)成立,执行下次,0-2=-2,所以得到如上结果。如果是while(!(x--)),结果是1,除非是单行的- - x,x- - 运算顺序是一样的,否则一定会有先后运算差别。

(3)

int main(int argc, char* argv[])
{
     int x=10,y=15;
     printf("%d/n",x=x++);
     printf("%d/n",y=++y);
     return 0;
}
运算结果是10,16。Y的值很容易确定,一般知先自加一次。X知一般要先赋值,但是问题在于赋值后运算X加1这样有效吗?答案是有效的。类似的还有问题4。
(4)
int main(int argc, char* argv[])
{
       int x=20,y=35;
       printf("%d/n",x=y++ + x++);
       printf("%d/n",y=++y + ++x);
       return 0;
}
答案是55,94。同样,对于X运算,都是先赋值输出后再自加。先输出55,再在内存中执行X自加。 
(5)

int Sub(int a,int b)
{
        return a*b;
}
int main(int argc, char* argv[])
{
     typedef int (*SUB)(int,int);
     SUB psub=Sub;
     printf("%d",psub(2,(8,8)));
     return 0;
}
注意在形参位置引用括号的用法,它是把括号中最右边的那个值当作当个形参来运算,如上,结果是16,如果换成printf("%d",psub(2,(8,8,9)));结果是18。

(6)

 char *ptr[10][10];

 char **ptr3[10][10];
 char ptr1[10][10];
 char (*ptr2)[10][10];

 printf("%d /n",sizeof(ptr));

 printf("%d /n",sizeof(ptr3));
 printf("%d /n",sizeof(ptr1));
 printf("%d /n",sizeof(ptr2));

 输出结果是400,400,100,4。后两个很好理解,ptr1是数组首地址,运算得到的是数组长度;ptr2是个数组指针,长度就是4;ptr则是个指针数组的首地址,100个单元,每个单元是指针即4个字节长度,所以最后是400;ptr3归根到底还是个指针数组的名字,只不过是个二维的,所以仍然是400。

(7)

 unsigned int a =17;
 unsigned int b = 0;
 if(a%4&0x0f==0x01)
      b =a +3;
 else
      b =a -3;
 printf("%d /n",b);

输出结果是14。如果忽略了&运算符的优先级比==还要低,则会算得20。

(8)

void func(int x)
{
     if (x/2>0)
     {
            func(x/2);
            printf("%d /n",x);
      }
}

int _tmain()
{
        int a = 10;
        func(a);
        return 0;
}

运算结果是2 5 10。注意递归顺序,否则会得出10 5 2

(9)类比3题跟4题

 int a =4,b=4;
 printf("%d/n",a+=(a++));
 printf("%d/n",b+=(++b));

答案是8 10。a的运算遵循先赋值,再自加。b的运算我一开始以为是9,结果是10;我的理解是先自加,然后前面一个b也是自加后的值。

(10)类比6题

 void *p = malloc(1000);
 printf("%d /n",sizeof(p));

输出是4,指针变量,就占4字节,跟malloc没有任何关系。

(11)类比6题

int _tmain(char str[100])
{
      printf("%d /n",sizeof(str));

}  

输出是4。数组作形参传入,不管数组长度有无定义,此时的数组名就是一个数组首地址。

(12)

void func(int *p,int q)
{
       int temp;
       temp = *p;
       *p = q;
       q = temp;     //内部互换值
}

int main(int argc, char* argv[])
{
       int a = 3,b = 5;
       func(&a,b);
       printf("a is %d ,b is %d \r\n",a,b);
       return 0;
}

输出结果是a is 5 ,b is 5。因为b是复制进去的参数,就算赋值也不会被改变;a则不同,如果将&a的指向值改变,意味着该变量已改变。

(13)

void func(int s[100])
{
printf("sizeof(s) is %d \r\n",sizeof(s));
}
int main(int argc, char* argv[])
{
int pq[100];
func(pq);
return 0;
}

程序的输出是4。该题考的就是数组名作为函数形参时,代表的大小。其实值就是4,数组名作为地址本身就是4字节,与数组长度无关。

(14)

int main(int argc, char* argv[])
{
char s[] = {"abcde"};
char *p = s;
printf("sizeof(p) is %d \r\n",sizeof(p));

char *q = (char*)malloc(100);
printf("sizeof(q) is %d \r\n",sizeof(q));
}

两者的输出都是4。前者p不过是指向字符串的一个指针,归根到底是指针。后者q也是,与malloc分配的空间无关。

二,自编程序:

(1)写段程序,计算输入的任一个字节有多少位被置1
void Calulate(unsigned char Data)
{
      unsigned char Temp=0,Com=0x01;
      for(int i=1;i<=8;i++)
     {
           if((Data&Com)!=0) //注意与运算的优先级低于不等于,所以要加括号
                Temp++;
           Com<<=1;
      }
      printf("%d/n",Temp);
}
int main(int argc, char* argv[])
{
      unsigned char Input;
      scanf("%d",&Input);
      Calulate(Input);
      return 0;
}
(2)写一段程序,不采用多余的变量,将两个参数对调。
方法1:简单来说,就是通过普通的+和-运算来实现。代码如下:
int a,b;
a=10;b=12;
a=b-a; //a=2;b=12 //算出两者之间的差值
b=b-a; //a=2;b=10 //B减去差值成A赋给B
a=b+a; //a=12;b=10//B(实际已经为A了)加上差值成原B赋给A
方法2:通过异或运算也能实现变量的交换,此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变。
int a=10,b=12; //a=1010^b=1100;
a=a^b; //a=0110^b=1100;
b=a^b; //a=0110^b=1010; // a^b^b=A,A就赋值给B了
a=a^b; //a=1100=12;b=1010;// a^ a^b=B,真实的B就赋值给A了。
(3)自编程序输入任意月份和日期,得到一年已过的天数。不考虑闰年,每月的天数固定。采用查表法来完成:
Void PrintData(void)
{
      Unsigned char MonthDays[12]={ 31,28,31,30,31,30,31,31,30,31,30,31};//以左手小指为第一顺序,除第二月28天,按高端31低端30来计,到最右端重一//个再往回计算即可。
     Unsigned char umonth,uday;
     Unsigned int SUM=0;
     Scanf(“%d”,& umonth);
     Scanf(“%d”,& uday);
     For(int i=0;i< umonth;i++)
         SUM  = SUM+ MonthDays[umonth-1]; 
     Printf(“%d”, SUM+ uday);

(4)写一段程序,计算出所有的三位数中满足条件的数,条件一必须是某个数的平方;条件二必须满足其中的两个数是一样的,比如144。

unsigned char m,n,p,nump=0;
unsigned int b,resule[25];
for(unsigned char a =10;a< 32;a++)   //限定后面三位数的范围
{
      b =a*a;
      m = b/100;                    //取百位数
      n = b%100/10;              //取十位数
      p = b%10;                     //取个位数
      if ((m == n)||(m == p)||(n == p))
      {
             resule[nump] = b;  
             nump++;                     //注意三位数是超过256的,所以b跟resule都必须是Int型
       }
       else
       {
              continue;
       }
}
for (unsigned char c =0;c<nump;c++)
{
       printf("%d /n",resule[c]);
}

得结果:100  121 144 225 400 441 484 676 900

(5)写一段程序,验证字符串是否对称。如“aba”。

void func(char *strin)
{
     char *p,*q;
     p = strin;
     q = strin + (strlen(strin)-1);
     while ((*p == *q)&&(p != q))
     {
          printf("%c /n",*p);
          p++;
          q--;
      }
}

int _tmain(int argc, _TCHAR* argv[])
{
       char *str="abc54656cba";
       func(str);

}

输出a b c,把对称的字符输出。

(6)判断一个链表是否是循环链表

void main(LinkList *head)
{
       if(head== null)
            return;
       LinkList *p = head;
       while(p != null)
       {
              p = p->next;
              if(p != null)
              {
                    if(p == head)
                    {    

                           printf("there have circle");

                           return;

                     }
                    else
                          continue;
               }
        }
        if(p == null)
               printf("there have no circle");
}
三,推理问题:

(1)有27个同学去买水,已知三个空瓶子可以换一瓶水,问如果为了保证每个人都有水喝,他们至少要买几瓶水?
列个方程可以算个大概,X+X/3=27,X=20。然后手工推理,得至少19瓶。先用18试。18+6+2,得26瓶,额外的加一瓶,即凑满27瓶。
(2)有3顶黑(B)帽子,2顶白(W)帽子。让三个人从前到后站成一排,给他们每个人头上戴一顶帽子。每个人都看不见自己戴的帽子的颜色,却只能看见站在前面那些人的帽子颜色。(所以最后一个人可以看见前面两个人头上帽子的颜色,中间那个人看得见前面那个人的帽子颜色但看不见在他后面那个人的帽子颜色,而最前面那个人谁的帽子都看不见。现在从最后那个人开始,问他知道自己戴的帽子颜色吗,回答不知道;然后问中间那个人,也回答不知道;得知后两个人都回答不知道,第一个人回答出了自己帽子的颜色。请问:第一个人是什么颜色的帽子?为什么?
假设:A    B   C 三人,C是最后一个,A是第一个,AB有这几种可能。
         B    B ,
        W   W ,B。该种不可能,因为如果前两个白色,C绝对可以知道自己帽子的颜色是黑色。
         B    W ,
         W    B ,B(或者W B W)这两种也不可能。排除第二种情况,虽然C不能判断自己的颜色,但是中间人可以判断自己帽子是黑色。
综上,二四两种情况都排除后,一三两种情况都可保证第一人是黑色帽子。