Chinaunix首页 | 论坛 | 博客
  • 博客访问: 367038
  • 博文数量: 92
  • 博客积分: 1037
  • 博客等级: 准尉
  • 技术积分: 854
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-27 11:13
文章分类

全部博文(92)

文章存档

2013年(2)

2012年(90)

分类:

2012-05-09 22:03:56

原文地址:《linuxC编程实战》面试题摘选 作者:

1、 int a=5;
       a=(a=3*5,a*4),a+5;
        a=?
       注:赋值运算符要优先于逗号运算符,故 a = 60;

2、交换两个变量(整型)的值,且不允许使用中间值
      int a,b;
      a^=b;
      b^=a;
      a^=b;
      注:a,b必须为整型变量

3、int a=3;
      a+=a-=a*a;
      a=?
     "="为自右向左结合,故a=a-a*a,a=-6; a=a+a,a=-12;

4、int a;
     scanf(" %d\n",&a);
      注:使用scanf函数时,建议不要包含'\n'。如果这样使用,则在输入变量a的值时,应该按两次键,因为字符'\n'的作用相当于键。

5、switch语句的一般形式为:
      switch(表达式)
      {
            case 常量表达式1:语句1
            case 常量表达式2:语句2
            ......
             case 常量表达式n:语句n
            default:语句n+1
        }
        注:switch表达式所计算的结果必须为整型,常量表达式也必须是整型数值,且不能为变量。

6、写出float类型的变量i与零值比较的语句。
       if ((x >=0.00001) &&(x<=-0.00001))

7、
(1)用逻辑表达式、for循环语句求解逻辑题。5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果
       A选手说:B第一,我第三。
      B选手说:我第二,E第四。
       C选手说:我第一,D第二。
      D选手说:C最后,我第三。
      E选手说:我第四,A第一。
       比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
(2)日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词。
      A说:不是我。
      B说:是C。
      C说:是D。
       D说:C在胡说
     已知3个人说了真话,1个人说的是假话。现在请根据这些信息,写一个程序来确定到底谁是凶手。
     解:
       #include
      int main()
      {
               int i,sum=0,flag=0;
              char killer;
              for(i=1;i<=4;i++)
              {
                    killer =64 +i;
                     sum = (killer !='A')+(killer =='C')+(killer == 'D') +(killer!='D');
                    if(sum ==3)
                    {
                             flag=1;
                           printf("%c is the killer.\n",killer);
                            break;
                       }
                  }
                  if(flag ==0)
                       printf("Can not find\n");
                    return 0;
       }

8、
   模块化准则就是把一个大问题分解为许多小问题,每个小问题由一个函数来解决,每个函数都完成一个特定的功能,各个小问题应该尽量独立,即所谓高内聚,低耦合。函数内部应该是高内聚,完成一些紧密相关的任务,函数之间应该只有一些非常必要的联系,即低耦合。

9、
   extern 的使用(变量和函数)
   源文件file1.c:
     #include
      
      extern long power(int);
      int A=2;
      main()
     {
             int n =10,total;
             total = power(n);
              return 0;
      }
      源文件file2.c
      extern A;   //外部声明 一般只只针对的是全局变量
      long power(int n)
      {
           long total =1;
          int i;
          for(i=1;i<=n;i++)
              total = total * A;
          return total;
     }

10、
       数组初始化:
       在所有函数外定义的数组的所有元素将被自动赋予初值0,在函数内部定义的数组,系统不会为其进行初始化,在使用数组元素前必须对元素进行初始化。

11、
      int a[5]={1,2,3,4,5};
      int *p=a;
      p = a +10 ;//不合法的, 因为该数组只有5个元素
      p= a +5 ; //合法的,虽然该数组只有5个元素,从a[0]到a[4],但p可以指向数组存储空间的下一个位置。但不能对该变量执行*p运算,即不能获得此时指针p所指向的变量的值。
     a++;//不合法的,不能对数组名执行++、--操作。这是因为a是数组名,它是数组的首地址,它的值在程序的运行过程中式固定不变的,是常量。
      注:在指针上进行加减运算后所得到的指针,必须指向同一个数组或指向数组存储空间的下一个单元。

12、
       区别int (*p)[5]和int *p[5]。
       前者是一个指针,它指向一个含有5个元素的数组。后者是一个数组,它的长度为5,数组中每一个元素指向一个整型变量。
       区别int *f( int i, int j)和 int (*p)( int i ,int j)
       前者是返回指针的函数,它是一个函数的声明,后者是指向函数的指针,它定义了一个指针。

13、
      void change(int i, int *p)
     {
           i++;
           if(p != NULL)
                (*p)++;
      }
      对于指针型形参,实参也可以是NULL,因此change函数中必须检查p是否为NULL。如果实参为NULL,那么语句(*p)++将导致程序崩溃。    
      注:如果一个函数的参数中有指针,那么出于程序健壮性的考虑,在该函数中须检查参数是否为NULL.

14、
     函数指针的使用示例:
    #include
    #define GET_MAX 0
    #define GET_MIN 1

    int get_max(int i, int j)
    {
         return i>j?i : j ;
    }
    int get_min(int i, int j)
    {
        return i    }
    int compare(int i, int j,int flag)
    {
        int ret;
        int (*p)(int,int);
       if(flag == GET_MAX)
            p = get_max;
       else
           p = get_min;
       ret = p(i,j);
        return ret;
    }
    int main()
    {
      int i =5,j = 10,ret;
      ret = compare(i,j,GET_MAX);
      printf("The MAX is %d\n",ret);
      return 0;
    }
      注:(1)不能对指向函数的指针做任何运算,如p++、p--、p+n、p-n都是错误的。
          (2)指向函数的指针能通过同类型的函数(即参数相同、返回类型相同)名、函数指针或NULL来进行初始化或赋值。将函数指针初始化或赋值为NULL,表示该指针目前不指向任何函数。
     函数指针做形参:
     #include
     int get_big(int i, int j)
     {
          return i>j?i:j ;
     }
    int get_max(int i, int j,int k,int (*p)(int,int))
     {
         int ret;
         ret = p(i,j);
        ret = p(ret,k);
        return ret;
     }
    int main()
    {
      int i =5 ,j =10, k =15,ret;
       ret =get_max(i,j,k,get_big);
       return 0;
    }
   函数指针作函数返回值:
    #include
    int get_big(int i, int j)
    {
         return i>j?i:j;
    }
    int (*get_function(int a))(int ,int )
    {
        printf("the number is %d\n",a);
       return get_big;
   }
    int main()
     {
         int i=5,j=10,max;
         int (*p)(int,int);
         p = get_function(100);
         max = p(i,j);
        printf("The MAX is %d\n",max);
         return 0;
      }
      注:int (*get_function(int a0)(int ,int)是一个返回函数指针的函数。这个可能比较难以理解。我们首先抓住get_function,因为运算符()的优先级比*高,他的返回值是int(*)(int,int),也就是它返回的是一个指向函数的指针。该指针所指向的函数有两个整型参数。get_function中,将get_big作为函数的返回值。get_big是一个函数名,也是函数get_big的入口地址,他是一个指针。
15、
       char string[] = "Linux C";
       char *p = "Linux C";
      //"Linux C"是一个字符串常量。C语言对于字符串常量通常是这样处理的:在内存中开辟一个字符数组来存储该字符串常量,并把开辟出的字符数组的首地址赋给p.
      注:string[0] = 'a'是可以的,而p[0] = 'a'是非法的,因为p指向的是字符串常量,常量的内容不可改变。把p指向一个字符串常量或字符数组时合法的,例如:p = "Hello World!"; p= string;
16、
      下面这段小程序的输出是什么?
      #include
     void main()
     {
            int a[5] = {1,2,3,4,5};
            int *ptr = (int *)(&a+1);
            printf("%d,%d\n",*(a+1),*(ptr-));
       }
       注: &a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)。对于int *ptr=(int *)(&a+1),ptr是&(a[5]0,也就是a+5。ptr与(&a+1)类型是不一样的,所以ptr-1只会减去sizeof(int *)。a,&a的地址是一样的,但含义不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5]。*(a+1)就是a[1] ,*(ptr-1)是a[4],执行结果是2,5。
17、
        假设你只知道一个数组的数组名(a[]),如何确定这个数组的长度?
        int length = sizeof(a)/sizeof(a[0]);
18、
        下面这个程序编译时会报错,请指出错误并改正。
        #include
      int main(void)
      {
            int **p;
            int arr[100];
             p = &arr;
            return 0;
       }
       &arr是一个指向长度为100的数组的指针,而p是指向指针(该指针指向的是int型变量)的指针。主函数可以改为:
        int main(void)
        {
            int **p,*q;
            int arr[100];
            q=arr;
            p =&q;
             return 0;
    }
     用指针q进行过渡。
    注:两个指针只有在所指向的数据的类型一致时才可以相互赋值。
19、
     写一个程序,以递归方式反序输出一个字符串。如给定字符串“abc"输出“cba ”。
     #include
     void reverse(char *p)
     {
         if( *p == '\0')
              return;
        reverse(p+1);
         printf(“%c",*p);
   }
int main()
{
        reverse("abc");
        printf("\n");
         return 0;
    }
20、写一个递归程序,判断数组a[n]是否是一个递增的数组。
       #include
      int fun( int a[],int n)
      {
          if(n ==1)
             return 1;
          if( n == 2)
             return (a[n-1]>=a[n-2];
           return (fun(a,n-1)&&(a[n-1]>=a[n-2]));
    }
     int main()
    {
          int a[] = {1,2,3,4,5,6};
         if( fun(a,sizeof(a)/sizeof(a[0]) == 1)
              printf("a:ok\n");
          else
             printf("a:no\n");
         return 0;
      }
21、
       写一个函数,它的原型是:
      int findnumstring (char *outputsr, char *intputstr)
      功能:在字符串中找出连续最长的数字串,把这个串的长度返回,并把这个最长数字串赋给其中一个函数参数outputstr所指内存。
      例如:“abcd12345eee125sss123456789 “的首地址传给 intputstr后,函数将返回9,outputstr所指的值为123456789。
      #include
      #include
     #include
     int findnumstring(char *outputstr,char *inputstr)
    {
        char *in = inputstr , *out = outputstr , *temp , *final;
        int count = 0,maxlen = 0;
         while( *in != '\0')
        {
             if( *in > 47 && *in <58)
    {
                 for( temp = in; *in >47 && *in <58; in++)
                     count ++;
              }
              else
                     in++;
              if( maxlen < count )
              {
                   maxlen = count;
                  final = temp;
               }
              count = 0 ;
         }
         for( int i=0;i          {
               *out = *final;
               out++;
               final++;
          }
          *out = '\0';
          return maxlen;
       }
       void main()
      {
          char string[] ="abcd12345eee125ss123456789";
          char *p = (char *)malloc( strlen(string) +1);
          int count = findnumstring(p,string);
          printf("%s\n number string length =%d\n",p ,count);
     }         
22、
     写一个实现字符串拷贝的函数。给定字符串拷贝函数strcpy的原型:
       char *strcpy(char *dest,const char *src);
       要求:(1)不调用任何库函数。(2)说明函数为什么返回char *.
   char *strcpy(char *dest,char *src)
     {
         if( (dest == NULL) || (src == NULL) )
         {
               return NULL;
         }
          char *ret_string = dest;
         while( *dest ++ = *src++)!='\0');
          return ret_string;
      }
     注:返回char * 指针的原因是为了实现链式表达式,如:
             int length = strlen( strcpy( dest, "hello world") );
23、
       练习题:
       (1)用递归的方法求一个有n个元素的int型数组的最大值。
       (2)利用数组可以实现高精度计算,方法是将大整数每位上的数字存储为数组的一个元素。对于:  
                  m= 88200807199688
                  n= 345678912345678
               编写函数,实现大整数m、n的加、减、乘运算。
     (3)约瑟夫问题:
       古代某法官要判决n个犯人死刑,他有一条荒唐的逻辑,将犯人首尾的相接排成圆圈,然后从第s个人开始数起,每数到第m个犯人,就拉出来处决;然后又数m个,数到的犯人又拉出来处决,依次类推。剩下的最后一人可以豁免。
       编写程序,给出处决顺序,并给出哪一个人可以活下来。
     (4)编写一个函数,求两个字符串的长度最大的公共子串。
24、
       宏的作用范围是从宏定义开始到本源程序文件结束为止。也可以使用#undef来提前终止作用范围。例如:
         #define MAX 256
         int main()
         {
              .........
        }
        #undef MAX
       int f()
      {
            .....
      }
      由于使用了#undef,使宏名MAX只在main函数中有效。
25、编程小技巧
        示例:#ifdef DEBUG
                  printf("a=%d,b=%d",a,b);
                 #endif
        在调试程序时,可以在源程序头部加入如下语句:
              #define DEBUG
           这样在软件开发阶段,编译运行程序时会输出变量a,b的值。当程序调试完毕,在源程序文件头部删除这一行,则用户运行时不会输出a,b的值。这里打印出a,b值只是供调试使用。
26、
      不能把共用体变量作为函数参数,也不能使函数返回共用体变量,但可以使用指向共用体变量的指针。
27、
     typedif int NUMBER[10];
      NUMBER 声明为含有10个元素的数组类型。
      NUMBER n;
     n[0] =1;
     n为含有10个元素的数组。
28、
     C语言允许在一个结构体重以位为单位来使用内存,这种以为为单位的成员称为位域或位段。
     struct bit_data
     {
          int a:6;
         int b:4;
         int c:4;
         int d;
      }
       注:0~5的6位存放a,6~9的4位存放b,10~13的4位存放c,14~31的18位空闲,32~63的32位存放d.
     若某一位段要从另外一个存储单元开始存放,结构体中的成员可以定义成如下形式:
     int a:6;
     int b:4;
     int :0;
     int c:4;
     int d;
     注:a使用0~5的6位,b使用6~9的4位。c从下一个存储单元开始存放,即存放在32~35位,10~31位空闲。
   struct bit_data
   {
        int a:6;
        int b:4;
        int :8;
        int c:4;
        int d;
   };
   注:0~5位存放a,6~9位存放b,10~17位的8位强制空闲,18~21位存放c,22~31位的10位也空闲。32~63的32位存放d。
29、
      快速统计给定整数二进制形式中1的个数.
      int func( int x)
      {
           int count = 0;
           while (x)
           {
              count ++;
               x = x & (x-1);
           }
          return count;
      }
      如输入9999,该函数返回8。
     注:9999 = 9 x1024 +512 +256 +15
30、
     附注:参考书籍及学习计划
     C语言:《C程序设计语言》《C语言教程:模块化程序设计》
     gcc :gcc使用手册
     gdb:    gdb中文使用手册
     make: make中文使用手册
     计算机原理:《深入理解计算机系统》
    
    注:多动手才是王道
阅读(871) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~