zoukankan      html  css  js  c++  java
  • C经典笔试题大权(2)

    写一段程序,找出数组中第k大小的数,输出数所在的位置。例如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。函数接口为:int find_orderk(const int* narry,const int n,const int k)
    要求算法复杂度不能是O(n^2)
    谢谢!
    可以先用快速排序进行排序,其中用另外一个进行地址查找
    代码如下,在VC++6.0运行通过。给分吧^-^

    //快速排序

    #include<iostream>

    usingnamespacestd;

    intPartition (int*L,intlow,int high)
    {
    inttemp = L[low];
    intpt = L[low];

    while (low < high)
    {
    while (low < high && L[high] >= pt)
    --high;
    L[low] = L[high];
    while (low < high && L[low] <= pt)
    ++low;
    L[low] = temp;
    }
    L[low] = temp;

    returnlow;
    }

    voidQSort (int*L,intlow,int high)
    {
    if (low < high)
    {
    intpl = Partition (L,low,high);

    QSort (L,low,pl - 1);
    QSort (L,pl + 1,high);
    }
    }

    intmain ()
    {
    intnarry[100],addr[100];
    intsum = 1,t;

    cout << "Input number:" << endl;
    cin >> t;

    while (t != -1)
    {
    narry[sum] = t;
    addr[sum - 1] = t;
    sum++;

    cin >> t;
    }

    sum -= 1;
    QSort (narry,1,sum);

    for (int i = 1; i <= sum;i++)
    cout << narry[i] << '/t';
    cout << endl;

    intk;
    cout << "Please input place you want:" << endl;
    cin >> k;

    intaa = 1;
    intkk = 0;
    for (;;)
    {
    if (aa == k)
    break;
    if (narry[kk] != narry[kk + 1])
    {
    aa += 1;
    kk++;
    }

    }

    cout << "The NO." << k << "number is:" << narry[sum - kk] << endl;
    cout << "And it's place is:" ;
    for (i = 0;i < sum;i++)
    {
    if (addr[i] == narry[sum - kk])
    cout << i << '/t';
    }


    return0;
    }

    1、找错
    Void test1()
    {
    char string[10];
    char* str1="0123456789";
    strcpy(string, str1);// 溢出,应该包括一个存放'/0'的字符string[11]
    }


    Void test2()
    {
    char string[10], str1[10];
    for(I=0; I<10;I++)
    {
    str1[i] ='a';
    }
    strcpy(string, str1);// I,i没有声明。
    }

    Void test3(char* str1)
    {
    char string[10];
    if(strlen(str1)<=10)// 改成<10,字符溢出,将strlen改为sizeof也可以
    {
    strcpy(string, str1);
    }
    }

    2.
    void g(int**);
    int main()
    {
    int line[10],i;
    int *p=line; //p是地址的地址
    for (i=0;i<10;i++)
    {
    *p=i;
    g(&p);//数组对应的值加1
    }
    for(i=0;i<10;i++)
    printf("%d/n",line[i]);
    return 0;
    }

    void g(int**p)
    {
    (**p)++;
    (*p)++;// 无效
    }
    输出:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    3. 写出程序运行结果

    int sum(int a)
    {
    auto int c=0;
    static int b=3;
    c+=1;
    b+=2;
    return(a+b+c);
    }

    void main()
    {
    int I;
    int a=2;
    for(I=0;I<5;I++)
    {
    printf("%d,", sum(a));
    }
    }
    // static会保存上次结果,记住这一点,剩下的自己写
    输出:8,10,12,14,16,


    4.

    int func(int a)
    {
    int b;
    switch(a)
    {
    case 1: 30;
    case 2: 20;
    case 3: 16;
    default: 0
    }
    return b;
    }
    则func(1)=?
    // b定义后就没有赋值。

    5:
    int a[3];
    a[0]=0; a[1]=1; a[2]=2;
    int *p, *q;
    p=a;
    q=&a[2];
    则a[q-p]=a[2]
    解释:指针一次移动一个int但计数为1

    今天早上的面试题9道,比较难,向牛人请教,国内的一牛公司,坐落在北京北四环某大厦:
    1、线形表a、b为两个有序升序的线形表,编写一程序,使两个有序线形表合并成一个有序升序线形表h;
    答案在 请化大学 严锐敏《数据结构第二版》第二章例题,数据结构当中,这个叫做:两路归并排序
    Linklist *unio(Linklist *p,Linklist *q){
    linklist *R,*pa,*qa,*ra;
    pa=p;
    qa=q;
    R=ra=p;
    while(pa->next!=NULL&&qa->next!=NULL){
    if(pa->data>qa->data){
    ra->next=qa;
    qa=qa->next;
    }
    else{
    ra->next=pa;
    pa=pa->next;
    }
    }
    if(pa->next!=NULL)
    ra->next=pa;
    if(qa->next!=NULL)
    ra->next==qa;
    return R;
    }
    2、运用四色定理,为N个局域举行配色,颜色为1、2、3、4四种,另有数组adj[][N],如adj[i][j]=1则表示i区域与j区域相邻,数组color[N],如color[i]=1,表示i区域的颜色为1号颜色。
    四色填充
    3、用递归算法判断数组a[N]是否为一个递增数组。
    递归的方法,记录当前最大的,并且判断当前的是否比这个还大,大则继续,否则返回false结束:
    bool fun( int a[], int n )
    {
    if( n= =1 )
    return true;
    if( n= =2 )
    return a[n-1] >= a[n-2];
    return fun( a,n-1) && ( a[n-1] >= a[n-2] );
    }
    4、编写算法,从10亿个浮点数当中,选出其中最大的10000个。
    用外部排序,在《数据结构》书上有
    《计算方法导论》在找到第n大的数的算法上加工
    5、编写一unix程序,防止僵尸进程的出现.
    *********************************************************************
    同学的4道面试题,应聘的职位是搜索引擎工程师,后两道超级难,(希望大家多给一些算发)
    1.给两个数组和他们的大小,还有一动态开辟的内存,求交集,把交集放到动态内存dongtai,并且返回交集个数
    long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[])
    2.单连表的建立,把'a'--'z'26个字母插入到连表中,并且倒叙,还要打印!
    方法1:
    typedef struct val
    {   int date_1;
        struct val *next;
    }*p;

    void main(void)
    {   char c;
        
        for(c=122;c>=97;c--)
           { p.date=c;
             p=p->next;
            }

        p.next=NULL;
    }
    }
    方法2:
    node *p = NULL;
    node *q = NULL;

    node *head = (node*)malloc(sizeof(node));
    head->data = ' ';head->next=NULL;

    node *first = (node*)malloc(sizeof(node));
    first->data = 'a';first->next=NULL;head->next = first;
    p = first;

    int longth = 'z' - 'b';
    int i=0;
    while ( i<=longth )
    {
    node *temp = (node*)malloc(sizeof(node));
    temp->data = 'b'+i;temp->next=NULL;q=temp;

    head->next = temp; temp->next=p;p=q;
    i++;
    }

    print(head);

     

    1.这样的初始化有什么问题?char *p = malloc(10); 编译器提示“非法初始式” 云云。

    答:这个声明是静态或非局部变量吗?函数调用只能出现在自动变量(即局部非静态变量) 的初始式中。
    因为静态变量的地址必须在编译的过程中就确定下来而malloc()申请的内存地址是在运行时确定的。

    2. *p++ 自增p 还是p 所指向的变量?

    答:后缀++ 和-- 操作符本质上比前缀一目操作的优先级高, 因此*p++ 和*(p++) 等价, 它自增p 并返回p 自增之前所指向的值。
    要自增p 指向的值, 使用(*p)++, 如果副作用的顺序无关紧要也可以使用++*p。

    3 我有一个char * 型指针正巧指向一些int 型变量, 我想跳过它们。为什么如下的代码((int *)p)++; 不行?

    答:在C 语言中, 类型转换意味着“把这些二进制位看作另一种类型, 并作相应的对待”; 这是一个转换操作符,
    根据定义它只能生成一个右值(rvalue)。而右值既不能赋值, 也不能用++ 自增。(如果编译器支持这样的扩展,
    那要么是一个错误, 要么是有意作出的非标准扩展。) 要达到你的目的可以用:p = (char *)((int *)p + 1);
    或者,因为p 是char * 型, 直接用p += sizeof(int);

    4.空指针和未初始化的指针是一回事吗?

    答:空指针在概念上不同于未初始化的指针:空指针可以确保不指向任何对象或函数;
     而未初始化指针则可能指向任何地方。

    5.我可以用0来表示空指针吗?

    答:根据语言定义, 在指针上下文中的常数0 会在编译时转换为空指针。也就是说, 在初始化、赋值或比较的时候,
    如果一边是指针类型的值或表达式, 编译器可以确定另一边的常数0 为空指针并生成正确的空指针值。因此下边的代码段完全合法:
    char *p = 0;
    if(p != 0)

    然而, 传入函数的参数不一定被当作指针环境, 因而编译器可能不能识别未加修饰的0 “表示” 指针。
    在函数调用的上下文中生成空指针需要明确的类型转换,强制把0 看作指针。
    例如, Unix 系统调用execl 接受变长的以空指针结束的字符指针参数。它应该如下正确调用:
    execl("/bin/sh", "sh", "-c", "date", (char *)0);
    如果省略最后一个参数的(char *) 转换, 则编译器无从知道这是一个空指针,从而当作一个0 传入。(注意很多Unix 手册在这个例子上都弄错了。)


    摘要:
    ==========================|=============================
    ||   可以使用未加修饰的0   | 需要显示的类型转换         ||
    ||------------------------|---------------------------||
    ||   *初始化              | *函数调用, 作用域内无原型  ||
    ||   *赋值                | *变参函数调用中的可变参数  ||
    ||   *比较                |                           ||
    ||   *固定参数的函数调用   |                           ||
    ||    且在作用域内有原型   |                           ||
    ==========================|=============================

    有两条简单规则你必须遵循:
    1) 当你在源码中需要空指针常数时, 用“0” 或“NULL”。
    2) 如果在函数调用中“0” 或“NULL” 用作参数, 把它转换成被调函数需要的指针类型

    3.可怕的题目终于来了
    象搜索的输入信息是一个字符串,统计300万输入信息中的最热门的前十条,我们每次输入的一个字符串为不超过255byte,内存使用只有1G,
    请描述思想,写出算发(c语言),空间和时间复杂度,
    4.国内的一些帖吧,如baidu,有几十万个主题,假设每一个主题都有上亿的跟帖子,怎么样设计这个系统速度最好,请描述思想,写出算发(c语言),空间和时间复杂度,


    #include   string.h
    main(void)
    {   char   *src="hello,world";
        char   *dest=NULL;
        dest=(char   *)malloc(strlen(src));
        int   len=strlen(str);
        char   *d=dest;
        char   *s=src[len];
        while(len--!=0)
          d++=s--;
        printf("%s",dest);
    }
    找出错误!!
    #include   "string.h"
    #include "stdio.h"
    #include "malloc.h"
    main(void)
    {  
    char   *src="hello,world";
        char   *dest=NULL;
        dest=(char   *)malloc(sizeof(char)*(strlen(src)+1));
        int   len=strlen(src);
        char   *d=dest;
        char   *s=src+len-1;
        while(len--!=0)
          *d++=*s--;
    *d='/0';
        printf("%s",dest);
    }

    1.    简述一个Linux驱动程序的主要流程与功能。

    2.    请列举一个软件中时间换空间或者空间换时间的例子。
    void swap(int a,int b)
    {
    int c; c=a;a=b;b=a;
    }
    --->空优
    void swap(int a,int b)
    {
    a=a+b;b=a-b;a=a-b;
    }
    6.    请问一下程序将输出什么结果?
    char *RetMenory(void)
    {
           char p[] = “hellow world”;
           return p;
    }
    void Test(void)
    {
           char *str = NULL;
           str = RetMemory();
           printf(str);
    }
    RetMenory执行完毕,p资源被回收,指向未知地址。返回地址,str的内容应是不可预测的, 打印的应该是str的地址


    写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)
    功能:
    在字符串中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回
    9,outputstr所指的值为123456789
    int continumax(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;
    count = 0;
    final = temp;
    }
    }
    for(int i = 0; i < maxlen; i++)
    {
    *out = *final;
    out++;
    final++;
    }
    *out = '/0';
    return maxlen;
    }

    不用库函数,用C语言实现将一整型数字转化为字符串
    方法1:
    int getlen(char *s){
        int n;
        for(n = 0; *s != '/0'; s++)
               n++;
        return n;
    }
    void reverse(char s[])
    {
       int c,i,j;
       for(i = 0,j = getlen(s) - 1; i < j; i++,j--){
           c = s[i];
           s[i] = s[j];
           s[j] = c;
       }
    }
    void itoa(int n,char s[])
    {
       int i,sign;
       if((sign = n) < 0)
            n = -n;
       i = 0;
       do{/*以反序生成数字*/
          s[i++] = n%10 + '0';/*get next number*/
       }while((n /= 10) > 0);/*delete the number*/

       if(sign < 0)
          s[i++] = '-';

       s[i] = '/0';
       reverse(s);
    }
    方法2:
    #include <iostream>
    using namespace std;

    void itochar(int num);

    void itochar(int num)
    {
    int i = 0;
    int j ;
    char stra[10];
    char strb[10];
    while ( num )
    {
    stra[i++]=num%10+48;
    num=num/10;
    }
    stra[i] = '/0';
    for( j=0; j < i; j++)
    {
    strb[j] = stra[i-j-1];
    }
    strb[j] = '/0';
    cout<<strb<<endl;

    }
    int main()
    {
    int num;
    cin>>num;
    itochar(num);
    return 0;
    }

    前几天面试,有一题想不明白,请教大家!
      typedef struct
      {
         int a:2;
         int b:2;
         int c:1;
      }test;

      test t;
      t.a = 1;
      t.b = 3;
      t.c = 1;

      printf("%d",t.a);
      printf("%d",t.b);
      printf("%d",t.c);

      谢谢!
    t.a为01,输出就是1
    t.b为11,输出就是-1
    t.c为1,输出也是-1
    3个都是有符号数int嘛。
    这是位扩展问题
    01
    11
    1
    编译器进行符号扩展

    求组合数: 求n个数(1....n)中k个数的组合....
               如:combination(5,3)
      要求输出:543,542,541,532,531,521,432,431,421,321,
    #include<stdio.h>

    int pop(int *);
    int push(int );
    void combination(int ,int );

    int stack[3]={0};
    top=-1;

    int main()
    {
    int n,m;
    printf("Input two numbers:/n");
    while( (2!=scanf("%d%*c%d",&n,&m)) )
    {
    fflush(stdin);
    printf("Input error! Again:/n");
    }
    combination(n,m);
    printf("/n");
    }
    void combination(int m,int n)
    {
    int temp=m;
    push(temp);
    while(1)
    {
    if(1==temp)
    {
    if(pop(&temp)&&stack[0]==n) //当栈底元素弹出&&为可能取的最小值,循环退出
    break;
    }
    else if( push(--temp))
    {
    printf("%d%d%d  ",stack[0],stack[1],stack[2]);//§ä¨ì¤@?
    pop(&temp);
    }
    }
    }
    int push(int i)
    {
    stack[++top]=i;
    if(top<2)
    return 0;
    else
    return 1;
    }
    int pop(int *i)
    {
    *i=stack[top--];
    if(top>=0)
    return 0;
    else
    return 1;
    }

    1、用指针的方法,将字符串“ABCD1234efgh”前后对调显示
    #include <stdio.h>
    #include <string.h>
    #include <dos.h>
    int main()
    {
        char str[] = "ABCD1234efgh";
        int length = strlen(str);
        char * p1 = str;
        char * p2 = str + length - 1;
        while(p1 < p2)
        {
            char c = *p1;
            *p1 = *p2;
            *p2 = c;
            ++p1;
            --p2;
        }
        printf("str now is %s/n",str);
        system("pause");
        return 0;
    }
    2、有一分数序列:1/2,1/4,1/6,1/8……,用函数调用的方法,求此数列前20项的和
    #include <stdio.h>
    double getValue()
    {
        double result = 0;
        int i = 2;
        while(i < 42)
        {
            result += 1.0 / i;//一定要使用1.0做除数,不能用1,否则结果将自动转化成整数,即0.000000
            i += 2;
        }
        return result;
    }
    int main()
    {
        printf("result is %f/n", getValue());
        system("pause");
        return 0;
    }

    有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。
    以7个数为例:
       {0,1,2,3,4,5,6,7} 0-->1-->2(删除)-->3-->4-->5(删除)-->6-->7-->0(删除),如此循环直到最后一个数被删除。
    方法1:数组
    #include <iostream>
    using namespace std;
    #define null 1000

    int main()
    {
    int arr[1000];
    for (int i=0;i<1000;++i)
    arr[i]=i;
    int j=0;
    int count=0;
    while(count<999)
    {
    while(arr[j%1000]==null)
    j=(++j)%1000;
    j=(++j)%1000;
    while(arr[j%1000]==null)
    j=(++j)%1000;
    j=(++j)%1000;
    while(arr[j%1000]==null)
    j=(++j)%1000;
    arr[j]=null;
    ++count;
    }
    while(arr[j]==null)
    j=(++j)%1000;

    cout<<j<<endl;
    return 0;
    }方法2:链表
    #include<iostream>
    using namespace std;
    #define null 0
    struct node
    {
    int data;
    node* next;
    };
    int main()
    {
    node* head=new node;
    head->data=0;
    head->next=null;
    node* p=head;
    for(int i=1;i<1000;i++)
    {
    node* tmp=new node;
    tmp->data=i;
    tmp->next=null;
    head->next=tmp;
    head=head->next;
    }
    head->next=p;
    while(p!=p->next)
    {
    p->next->next=p->next->next->next;
    p=p->next->next;
    }
    cout<<p->data;
    return 0;
    }
    方法3:通用算法
    #include <stdio.h>
    #define MAXLINE 1000   //元素个数
    /*
    MAXLINE   元素个数
    a[]       元素数组
    R[]       指针场
    suffix    下标
    index     返回最后的下标序号
    values    返回最后的下标对应的值
    start     从第几个开始
    K         间隔
    */
    int find_n(int a[],int R[],int K,int& index,int& values,int s=0) {
       int suffix;
       int front_node,current_node;
       suffix=0;
          if(s==0) {
          current_node=0;
          front_node=MAXLINE-1;
          }
          else {
          current_node=s;
          front_node=s-1;
          }
            while(R[front_node]!=front_node) {
                printf("%d/n",a[current_node]);
                R[front_node]=R[current_node];
                if(K==1) {
                  current_node=R[front_node];
                  continue;
                }
                for(int i=0;i<K;i++){
                   front_node=R[front_node];
                }
                current_node=R[front_node];
            }
     index=front_node;
     values=a[front_node];

     return 0;
    }
    int main(void) {
    int a[MAXLINE],R[MAXLINE],suffix,index,values,start,i,K;
    suffix=index=values=start=0;
    K=2;

    for(i=0;i<MAXLINE;i++) {
    a[i]=i;
    R[i]=i+1;
    }
    R[i-1]=0;
    find_n(a,R,K,index,values,2);
    printf("the value is %d,%d/n",index,values);
    return 0;
    }

    试题:
    void test2()
    {
       char string[10], str1[10];
       int i;
       for(i=0; i<10; i++)
       {
          str1[i] = 'a';
       }
       strcpy( string, str1 );
    }
    解答:对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;
    str1不能在数组内结束:因为str1的存储为:{a,a,a,a,a,a,a,a,a,a},没有'/0'(字符串结束符),所以不能结束
    strcpy( char *s1,char *s2)他的工作原理是,扫描s2指向的内存,逐个字符付到s1所指向的内存,直到碰到'/0',因为str1结尾没有'/0',所以具有不确定性,不知道他后面还会付什么东东。
    正确应如下
    void test2()
    {
       char string[10], str1[10];
       int i;
       for(i=0; i<9; i++)
       {
          str1[i] = 'a'+i; //把abcdefghi赋值给字符数组
       }
       str[i]='/0';//加上结束符
       strcpy( string, str1 );
    }

    第二个code题是实现strcmp
    int StrCmp(const char *str1, const char *str2)
    做是做对了,没有抄搞,比较乱
    int StrCmp(const char *str1, const char *str2)
    {
        assert(str1 && srt2);
        while (*str1 && *str2 && *str1 == *str2) {
            str1++, str2++;
        }
        if (*str1 && *str2)
            return (*str1-*str2);
        elseif (*str1 && *str2==0)
            return 1;
        elseif (*str1 = = 0 && *str2)
            return -1;
        else
            return 0;
    }

    int StrCmp(const char *str1, const char *str2)
    {
             //省略判断空指针(自己保证)
    while(*str1 && *str1++ = = *str2++);
    return *str1-*str2;
    }
    第三个code题是实现子串定位
    int FindSubStr(const char *MainStr, const char *SubStr)
    做是做对了,没有抄搞,比较乱
    int MyStrstr(const char* MainStr, const char* SubStr)
    {
    const char *p;
    const char *q;
    const char * u = MainStr;
       
    //assert((MainStr!=NULL)&&( SubStr!=NULL));//用断言对输入进行判断
    while(*MainStr) //内部进行递增
    {
    p = MainStr;
    q = SubStr;
    while(*q && *p && *p++ == *q++);
    if(!*q )
    {
    return MainStr - u +1 ;//MainStr指向当前起始位,u指向
    }
    MainStr ++;
    }
    return -1;
    }

    分析:
    int arr[] = {6,7,8,9,10};
    int *ptr = arr;
    *(ptr++)+=123;
    printf(“ %d %d ”, *ptr, *(++ptr));
    输出:8 8
    过程:对于*(ptr++)+=123;先做加法6+123,然后++,指针指向7;对于printf(“ %d %d ”, *ptr, *(++ptr));从后往前执行,指针先++,指向8,然后输出8,紧接着再输出8

    华为全套完整试题
    高级题
    6、已知一个单向链表的头,请写出删除其某一个结点的算法,要求,先找到此结点,然后删除。
    slnodetype *Delete(slnodetype *Head,int key){}中if(Head->number==key)
    {
    Head=Pointer->next;
    free(Pointer);
    break;
    }
    Back = Pointer;
            Pointer=Pointer->next;
    if(Pointer->number==key)
    {
                Back->next=Pointer->next;
    free(Pointer);
    break;
    }
    void delete(Node* p)
    {
        if(Head = Node)

        while(p)
    }

    有一个16位的整数,每4位为一个数,写函数求他们的和。
    解释:
    整数1101010110110111
    和  1101+0101+1011+0111
    感觉应该不难,当时对题理解的不是很清楚,所以写了一个函数,也不知道对不对。
    疑问:
        既然是16位的整数,1101010110110111是2进制的,那么函数参数怎么定义呢,请大虾指教。
    答案:用十进制做参数,计算时按二进制考虑。
    /* n就是16位的数,函数返回它的四个部分之和 */
    char SumOfQuaters(unsigned short n)
    {
        char c = 0;
        int i = 4;
        do
        {
            c += n & 15;
            n = n >> 4;
        } while (--i);

        return c;
    }

    有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数.(华为)
    #include<iostream.h>

    int main()
    {
        int a[]  = {10,6,9,5,2,8,4,7,1,3};
        int len = sizeof(a) / sizeof(int);
        int temp;

        for(int i = 0; i < len; )
        {
    temp = a[a[i] - 1];
    a[a[i] - 1] = a[i];
    a[i] = temp;

    if ( a[i] == i + 1)
      i++;
        }
        for (int j = 0; j < len; j++)
          cout<<a[j]<<",";

        return 0;
    }

    (慧通)
    1 写出程序把一个链表中的接点顺序倒排
    typedef struct linknode
    {
    int data;
    struct linknode *next;
    }node;
    //将一个链表逆置
    node *reverse(node *head)
    {
    node *p,*q,*r;
    p=head;
    q=p->next;
    while(q!=NULL)
    {
    r=q->next;
    q->next=p;
    p=q;
    q=r;
    }

    head->next=NULL;
    head=p;
    return head;
    }
    2 写出程序删除链表中的所有接点
    void del_all(node *head)
    {
    node *p;
    while(head!=NULL)
    {
    p=head->next;
    free(head);
    head=p;
    }
    cout<<"释放空间成功!"<<endl;
    }
    3两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串
    void insert(char *s, char *t, int i)
    {
    char *q = t;
    char *p =s;
    if(q == NULL)return;
    while(*p!='/0')
    {
    p++;
    }
    while(*q!=0)
    {
    *p=*q;
    p++;
    q++;
    }
    *p = '/0';
    }


    分析下面的代码:
    char *a = "hello";
    char *b = "hello";
    if(a= =b)
    printf("YES");
    else
    printf("NO");
    这个简单的面试题目,我选输出 no(对比的应该是指针地址吧),可在VC是YES 在C是NO
    lz的呢,是一个常量字符串。位于静态存储区,它在程序生命期内恒定不变。如果编译器优化的话,会有可能a和b同时指向同一个hello的。则地址相同。如果编译器没有优化,那么就是两个不同的地址,则不同
    ************************************************************************************
    写一个函数,功能:完成内存之间的拷贝
    memcpy source code:
        270 void* memcpy( void *dst, const void *src, unsigned int len )
        271 {
        272    register char *d;
        273    register char *s;
        27
        275    if (len == 0)
        276       return dst;
        277
        278    if (is_overlap(dst, src, len, len))
        279       complain3("memcpy", dst, src, len);
        280
        281    if ( dst > src ) {
        282       d = (char *)dst + len - 1;
        283       s = (char *)src + len - 1;
        284       while ( len >= 4 ) {
        285          *d-- = *s--;
        286          *d-- = *s--;
        287          *d-- = *s--;
        288          *d-- = *s--;
        289          len -= 4;
        290       }
        291       while ( len-- ) {
        292          *d-- = *s--;
        293       }
        294    } else if ( dst < src ) {
        295       d = (char *)dst;
        296       s = (char *)src;
        297       while ( len >= 4 ) {
        298          *d++ = *s++;
        299          *d++ = *s++;
        300          *d++ = *s++;
        301          *d++ = *s++;
        302          len -= 4;
        303       }
        304       while ( len-- ) {
        305          *d++ = *s++;
        306       }
        307    }
        308    return dst;
        309 }
    公司考试这种题目主要考你编写的代码是否考虑到各种情况,是否安全(不会溢出)
    各种情况包括:
    1、参数是指针,检查指针是否有效
    2、检查复制的源目标和目的地是否为同一个,若为同一个,则直接跳出
    3、读写权限检查
    4、安全检查,是否会溢出
    memcpy拷贝一块内存,内存的大小你告诉它
    strcpy是字符串拷贝,遇到'/0'结束

    /* memcpy ─── 拷贝不重叠的内存块 */ 
    void memcpy(void* pvTo, void* pvFrom, size_t size)
    {
    void* pbTo = (byte*)pvTo;
    void* pbFrom = (byte*)pvFrom;
    ASSERT(pvTo != NULL && pvFrom != NULL); //检查输入指针的有效性
    ASSERT(pbTo>=pbFrom+size || pbFrom>=pbTo+size);//检查两个指针指向的内存是否重叠
    while(size-->0)
    *pbTo++ == *pbFrom++;
    return(pvTo);
    }


    华为面试题:怎么判断链表中是否有环?
    bool CircleInList(Link* pHead)
    {
    if(pHead = = NULL || pHead->next = = NULL)//无节点或只有一个节点并且无自环
    return (false);
    if(pHead->next = = pHead)//自环
    return (true);
    Link *pTemp1 = pHead;//step 1
    Link *pTemp = pHead->next;//step 2
    while(pTemp != pTemp1 && pTemp != NULL && pTemp->next != NULL)
    {
    pTemp1 = pTemp1->next;
    pTemp = pTemp->next->next;
    }
    if(pTemp = = pTemp1)
    return (true);
    return (false);
    }

    两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串
    void insert(char *s, char *t, int i)
    {
    memcpy(&s[strlen(t)+i],&s[i],strlen(s)-i);
    memcpy(&s[i],t,strlen(t));
    s[strlen(s)+strlen(t)]='/0';
    }

    1。编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的。
    char * search(char *cpSource, char ch)
    {
             char *cpTemp=NULL, *cpDest=NULL;
             int iTemp, iCount=0;
             while(*cpSource)
             {
                     if(*cpSource == ch)
                     {
                              iTemp = 0;
                              cpTemp = cpSource;
                              while(*cpSource == ch)
    ++iTemp, ++cpSource;
                              if(iTemp > iCount)
    iCount = iTemp, cpDest = cpTemp;
            if(!*cpSource)
    break;
                     }
                     ++cpSource;
     }
     return cpDest;
    }     
    2。请编写一个 C 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。
    int search(char *cpSource, int n, char ch)
    {
             int i;
             for(i=0; i<n && *(cpSource+i) != ch; ++i);
             return i;
    }

    一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?
    将这个指针指向的next节点值copy到本节点,将next指向next->next,并随后删除原next指向的节点。


    #include <stdio.h>
    void foo(int m, int n)
    {
        printf("m=%d, n=%d/n", m, n);
    }

    int main()
    {
        int b = 3;
        foo(b+=3, ++b);
        printf("b=%d/n", b);
    return 0;
    }
    输出:m=7,n=4,b=7(VC6.0)
    这种方式和编译器中得函数调用关系相关即先后入栈顺序。不过不同
    编译器得处理不同。也是因为C标准中对这种方式说明为未定义,所以
    各个编译器厂商都有自己得理解,所以最后产生得结果完全不同。
    因为这样,所以遇见这种函数,我们首先要考虑我们得编译器会如何处理
    这样得函数,其次看函数得调用方式,不同得调用方式,可能产生不同得
    结果。最后是看编译器优化。


    2.写一函数,实现删除字符串str1中含有的字符串str2.
    第二个就是利用一个KMP匹配算法找到str2然后删除(用链表实现的话,便捷于数组)


    /*雅虎笔试题(字符串操作)
    给定字符串A和B,输出A和B中的最大公共子串。
    比如A="aocdfe" B="pmcdfa" 则输出"cdf"
    */
    //Author: azhen
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>

    char *commanstring(char shortstring[], char longstring[])
    {
    int i, j;

    char *substring=malloc(256);

    if(strstr(longstring, shortstring)!=NULL)              //如果……,那么返回shortstring
    return shortstring; 

    for(i=strlen(shortstring)-1;i>0; i--)                 //否则,开始循环计算
    {
    for(j=0; j<=strlen(shortstring)-i; j++){
    memcpy(substring, &shortstring[j], i);
    substring[i]='/0';
    if(strstr(longstring, substring)!=NULL)
    return substring;
    }
    }
    return NULL;
    }


    main()
    {
    char *str1=malloc(256);
    char *str2=malloc(256);
    char *comman=NULL;

    gets(str1);
    gets(str2);

    if(strlen(str1)>strlen(str2))                         //将短的字符串放前面
    comman=commanstring(str2, str1);
    else
    comman=commanstring(str1, str2);

    printf("the longest comman string is: %s/n", comman);
    }


    11.写一个函数比较两个字符串str1和str2的大小,若相等返回0,若str1大于
    str2返回1,若str1小于str2返回-1
    int strcmp ( const char * src,const char * dst)
    {
            int ret = 0 ;
            while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
    {
                    ++src;
    ++dst;
    }
            if ( ret < 0 )
                    ret = -1 ;
            else if ( ret > 0 )
                    ret = 1 ;
            return( ret );
    }

    求1000!的未尾有几个0(用素数相乘的方法来做,如72=2*2*2*3*3);
    求出1->1000里,能被5整除的数的个数n1,能被25整除的数的个数n2,能被125整除的数的个数n3,
    能被625整除的数的个数n4.
    1000!末尾的零的个数=n1+n2+n3+n4;
    #include<stdio.h>
    #define NUM 1000

    int find5(int num){
    int ret=0;
    while(num%5==0){
    num/=5;
    ret++;
    }
    return ret;
    }
    int main(){
    int result=0;
    int i;
    for(i=5;i<=NUM;i+=5)
    {
    result+=find5(i);
    }
    printf(" the total zero number is %d/n",result);
    return 0;
    }


    1. 有双向循环链表结点定义为:
    struct node
    { int data;
    struct node *front,*next;
    };
    有两个双向循环链表A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两链表中data值相同的结点删除
    BOOL DeteleNode(Node *pHeader, DataType Value)
    {
    if (pHeader == NULL) return;

    BOOL bRet = FALSE;
    Node *pNode = pHead;
    while (pNode != NULL)
    {
    if (pNode->data == Value)
    {
    if (pNode->front == NULL)
    {
    pHeader = pNode->next;
    pHeader->front = NULL;
    }
    else
    {
    if (pNode->next != NULL)
    {
    pNode->next->front = pNode->front;
    }
    pNode->front->next = pNode->next;
    }

    Node *pNextNode = pNode->next;
    delete pNode;
    pNode = pNextNode;

    bRet = TRUE;
    //不要break或return, 删除所有
    }
    else
    {
    pNode = pNode->next;
    }
    }

    return bRet;
    }

    void DE(Node *pHeadA, Node *pHeadB)
    {
    if (pHeadA == NULL || pHeadB == NULL)
    {
    return;
    }

    Node *pNode = pHeadA;
    while (pNode != NULL)
    {
    if (DeteleNode(pHeadB, pNode->data))
    {
    if (pNode->front == NULL)
    {
    pHeadA = pNode->next;
    pHeadA->front = NULL;
    }
    else
    {
    pNode->front->next = pNode->next;
    if (pNode->next != NULL)
    {
    pNode->next->front = pNode->front;
    }
    }
    Node *pNextNode = pNode->next;
    delete pNode;
    pNode = pNextNode;
    }
    else
    {
    pNode = pNode->next;
    }
    }
    }
    2. 编程实现:找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为"cad"
    int GetCommon(char *s1, char *s2, char **r1, char **r2)
    {
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int maxlen = 0;

    for(int i = 0; i < len1; i++)
    {
    for(int j = 0; j < len2; j++)
    {
    if(s1[i] == s2[j])
    {
    int as = i, bs = j, count = 1;
    while(as + 1 < len1 && bs + 1 < len2 && s1[++as] == s2[++bs])
    count++;

    if(count > maxlen)
    {
    maxlen = count;
    *r1 = s1 + i;
    *r2 = s2 + j;
    }
    }
    }
    }
    3. 编程实现:把十进制数(long型)分别以二进制和十六进制形式输出,不能使用printf系列库函数
    char* test3(long num) {
    char* buffer = (char*)malloc(11);
    buffer[0] = '0';
    buffer[1] = 'x';
    buffer[10] = '/0';

    char* temp = buffer + 2;
    for (int i=0; i < 8; i++) {
    temp[i] = (char)(num<<4*i>>28);
    temp[i] = temp[i] >= 0 ? temp[i] : temp[i] + 16;
    temp[i] = temp[i] < 10 ? temp[i] + 48 : temp[i] + 55;
    }
    return buffer;
    }


    输入N, 打印 N*N 矩阵
    比如 N = 3,打印:

    1  2  3
    8  9  4
    7  6  5

    N = 4,打印:

    1   2   3   4
    12  13  14  5
    11  16  15  6
    10  9   8   7
    解答:
    1 #define N 15
    int s[N][N];
    void main()
    {
    int k = 0, i = 0, j = 0;
    int a = 1;
    for( ; k < (N+1)/2; k++ )
    {
    while( j < N-k ) s[i][j++] = a++; i++; j--;
    while( i < N-k ) s[i++][j] = a++; i--; j--;
    while( j > k-1 ) s[i][j--] = a++; i--; j++;
    while( i > k )   s[i--][j] = a++; i++; j++;
    }
    for( i = 0; i < N; i++ )
    {
    for( j = 0; j < N; j++ )
    cout << s[i][j] << '/t';
    cout << endl;
    }
    }
    2 define MAX_N  100
    int matrix[MAX_N][MAX_N];

    /*
     *(x,y):第一个元素的坐标
     * start:第一个元素的值
     * n:矩阵的大小
     */
    void SetMatrix(int x, int y, int start, int n) {
        int i, j;

        if (n <= 0)    //递归结束条件
            return;
        if (n == 1) {  //矩阵大小为1时
            matrix[x][y] = start;
            return;
        }
        for (i = x; i < x + n-1; i++)   //矩阵上部
            matrix[y][i] = start++;

        for (j = y; j < y + n-1; j++)   //右部
            matrix[j][x+n-1] = start++;

        for (i = x+n-1; i > x; i--)     //底部
            matrix[y+n-1][i] = start++;

        for (j = y+n-1; j > y; j--)     //左部
            matrix[j][x] = start++;

        SetMatrix(x+1, y+1, start, n-2);   //递归
    }

    void main() {
       int i, j;
       int n;

       scanf("%d", &n);
       SetMatrix(0, 0, 1, n);
      
       //打印螺旋矩阵
       for(i = 0; i < n; i++) {
          for (j = 0; j < n; j++)
    printf("%4d", matrix[i][j]);
          printf("/n");
       }
    }


    斐波拉契数列递归实现的方法如下:
     int  Funct( int n )
    {
       if(n==0) return 1;
       if(n==1) return 1;
       retrurn  Funct(n-1) + Funct(n-2);
    }
    请问,如何不使用递归,来实现上述函数?
    请教各位高手!
    解答:int  Funct( int n )  //  n 为非负整数
    {
       int a=0;
       int b=1;
       int c;
       if(n==0) c=1;
       else if(n==1) c=1;
       else for(int i=2;i<=n;i++)  //应该n从2开始算起
       {
         c=a+b;
         a=b;
         b=c;
       }
       return c;
    }
    解答:
    现在大多数系统都是将低字位放在前面,而结构体中位域的申明一般是先声明高位。
    100  的二进制是 001 100 100
    低位在前   高位在后 
    001----s3
    100----s2
    100----s1
    所以结果应该是 1
    如果先申明的在低位则:
    001----s1
    100----s2
    100----s3
    结果是 4
    1、原题跟little-endian,big-endian没有关系
    2、原题跟位域的存储空间分配有关,到底是从低字节分配还是从高字节分配,从Dev C++和VC7.1上看,都是从低字节开始分配,并且连续分配,中间不空,不像谭的书那样会留空位
    3、原题跟编译器有关,编译器在未用堆栈空间的默认值分配上有所不同,Dev C++未用空间分配为
    01110111b,VC7.1下为11001100b,所以在Dev C++下的结果为5,在VC7.1下为1。

    注:PC一般采用little-endian,即高高低低,但在网络传输上,一般采用big-endian,即高低低高,华为是做网络的,所以可能考虑big-endian模式,这样输出结果可能为4

    判断一个字符串是不是回文
    int IsReverseStr(char *aStr)
    {
    int i,j;
    int found=1;
    if(aStr==NULL)
    return -1;
    j=strlen(aStr);
    for(i=0;i<j/2;i++)
    if(*(aStr+i)!=*(aStr+j-i-1))
    {
    found=0;
    break;
    }
    return found;
    }

    osephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

    数组实现:
    #include <stdio.h>
    #include <malloc.h>
    int Josephu(int n, int m)
    {
      int flag, i, j = 0;
      int *arr = (int *)malloc(n * sizeof(int));
      for (i = 0; i < n; ++i)
        arr[i] = 1;
      for (i = 1; i < n; ++i)
      {
        flag = 0;
        while (flag < m)
        {
          if (j == n)
            j = 0;
          if (arr[j])
            ++flag;
          ++j;
        }
        arr[j - 1] = 0;
        printf("第%4d个出局的人是:%4d号/n", i, j);
      }
      free(arr);
      return j;
    }
    int main()
    {
      int n, m;
      scanf("%d%d", &n, &m);
      printf("最后胜利的是%d号!/n", Josephu(n, m));
      system("pause");
      return 0;
    }
    链表实现:
    #include <stdio.h>
    #include <malloc.h>
    typedef struct Node
    {
      int index;
      struct Node *next;
    }JosephuNode;
    int Josephu(int n, int m)
    {
      int i, j;
      JosephuNode *head, *tail;
      head = tail = (JosephuNode *)malloc(sizeof(JosephuNode));
      for (i = 1; i < n; ++i)
      {
        tail->index = i;
        tail->next = (JosephuNode *)malloc(sizeof(JosephuNode));
        tail = tail->next;
      }
      tail->index = i;
      tail->next = head;
     
      for (i = 1; tail != head; ++i)
      {
        for (j = 1; j < m; ++j)
        {
          tail = head;
          head = head->next;
        }
        tail->next = head->next;
        printf("第%4d个出局的人是:%4d号/n", i, head->index);
        free(head);
        head = tail->next;
      }
      i = head->index;
      free(head);
      return i;
    }
    int main()
    {
      int n, m;
      scanf("%d%d", &n, &m);
      printf("最后胜利的是%d号!/n", Josephu(n, m));
      system("pause");
      return 0;
    }

    已知strcpy函数的原型是:
            char * strcpy(char * strDest,const char * strSrc);
        1.不调用库函数,实现strcpy函数。
        2.解释为什么要返回char *。
        解说:
        1.strcpy的实现代码
            char * strcpy(char * strDest,const char * strSrc)
            {
                    if ((strDest==NULL)||(strSrc==NULL)) file://[/1]
                            throw "Invalid argument(s)"; //[2]
                    char * strDestCopy=strDest;  file://[/3]
                    while ((*strDest++=*strSrc++)!='/0'); file://[/4]
                    return strDestCopy;
            }
        错误的做法:
        [1]
        (A)不检查指针的有效性,说明答题者不注重代码的健壮性。
        (B)检查指针的有效性时使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),说明答题者对C语言中类型的隐式转换没有深刻认识。在本例中char *转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。所以C++专门增加了bool、true、false三个关键字以提供更安全的条件表达式。
        (C)检查指针的有效性时使用((strDest==0)||(strSrc==0)),说明答题者不知道使用常量的好处。直接使用字面常量(如本例中的0)会减少程序的可维护性。0虽然简单,但程序中可能出现很多处对指针的检查,万一出现笔误,编译器不能发现,生成的程序内含逻辑错误,很难排除。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。
        [2]
        (A)return new string("Invalid argument(s)");,说明答题者根本不知道返回值的用途,并且他对内存泄漏也没有警惕心。从函数中返回函数体内分配的内存是十分危险的做法,他把释放内存的义务抛给不知情的调用者,绝大多数情况下,调用者不会释放内存,这导致内存泄漏。
        (B)return 0;,说明答题者没有掌握异常机制。调用者有可能忘记检查返回值,调用者还可能无法检查返回值(见后面的链式表达式)。妄想让返回值肩负返回正确值和异常值的双重功能,其结果往往是两种功能都失效。应该以抛出异常来代替返回值,这样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。
        [3]
        (A)忘记保存原始的strDest值,说明答题者逻辑思维不严密。
        [4]
        (A)循环写成while (*strDest++=*strSrc++);,同[1](B)。
        (B)循环写成while (*strSrc!='/0') *strDest++=*strSrc++;,说明答题者对边界条件的检查不力。循环体结束后,strDest字符串的末尾没有正确地加上'/0'。

    6. 既然数组引用会蜕化为指针, 如果arr 是数组, 那么arr 和&arr 又有什么区别呢?

    答:区别在于类型:
    在标准C 中, &arr 生成一个“T 型数组” 的指针, 指向整个数组。
    在所有的C 编译器中, 对数组的简单引用(不包括& 操作符)生成一个T 的指针类型的指针, 指向数组的第一成员。

    7. 我如何声明一个数组指针?

    答:通常, 你不需要。当人们随便提到数组指针的时候, 他们通常想的是指向它的第一个元素的指针。
    考虑使用指向数组某个元素的指针, 而不是数组的指针。类型T 的数组蜕变成类型T 的指针, 这很方便;
    在结果的指针上使用下标或增量就可以访问数组中单独的成员。而真正的数组指针, 在使用下标或增量时, 会跳过整个数组,
    通常只在操作数组的数组时有用—— 如果还有一点用的话。如果你真的需要声明指向整个数组的指针,
    使用类似“int (*ap)[N];”这样的声明。其中N 是数组的大小。如果数组的大小未知, 原则上可以省略N, 但是这样生成的类型,
    “指向大小未知的数组的指针”, 毫无用处。

    8.当我向一个接受指针的指针的函数传入二维数组的时候, 编译器报错了,这是怎么回事?

    答:数组蜕化为指针的规则不能递归应用。数组的数组(即C 语言中的二维数组) 蜕化为数组的指针, 而不是指针的指针。
    数组指针常常令人困惑, 需要小心对待; 如果你向函数传递二位数组:
    int array[NROWS][NCOLUMNS];
    f(array);
    那么函数的声明必须匹配:
    void f(int a[][NCOLUMNS])
    { ... }
    或者
    void f(int (*ap)[NCOLUMNS]) /* ap 是个数组指针*/
    { ... }
    在第一个声明中, 编译器进行了通常的从“数组的数组” 到“数组的指针” 的隐式转换; 第二种形式中的指针定义显而易见。
    因为被调函数并不为数组分配地址,所以它并不需要知道总的大小, 所以行数NROWS 可以省略。但数组的宽度依然重要,
    所以列维度NCOLUMNS (对于三维或多*数组, 相关的维度) 必须保留。
    如果一个函数已经定义为接受指针的指针, 那么几乎可以肯定直接向它传入二维数组毫无意义。


    9. 我的strcat() 不行.我试了char *s1 = "Hello, "; char *s2 = "world!";
    char *s3 = strcat(s1, s2); 但是我得到了奇怪的结果。

    答:这里主要的问题是没有正确地为连接结果分配空间。C 没有提供自动管理的字符串类型。
    C 编译器只为源码中明确提到的对象分配空间(对于字符串, 这包括字符数组和串常量)。
    程序员必须为字符串连接这样的运行期操作的结果分配足够的空间,

    常可以通过声明数组或调用malloc() 完成。strcat() 不进行任何分配; 第二个串原样不动地附加在第一个之后。
    因此, 一种解决办法是把第一个串声明为数组:
    char s1[20] = "Hello, ";
    由于strcat() 返回第一个参数的值, 本例中为s1, s3 实际上是多余的; 在strcat() 调用之后, s1 包含结果。
    提问中的strcat() 调用实际上有两个问题: s1 指向的字符串常数, 除了空间不足以放入连接的字符串之外,
    甚至都不一定可写。


    10. 那么返回字符串或其它集合的正确方法是什么呢?

    答:返回指针必须是静态分配的缓冲区, 或者调用者传入的缓冲区,
    或者用malloc() 获得的内存, 但不能是局部(自动) 数组。

    11. 我有个程序分配了大量的内存, 然后又释放了。但是从操作系统看,内存的占用率却并没有回去。

    答:多数malloc/free 的实现并不把释放的内存返回操作系统, 而是留着供同一程序的后续malloc() 使用。

    12. calloc() 和malloc() 有什么区别?利用calloc 的零填充功能安
    全吗?free() 可以释放calloc() 分配的内存吗, 还是需要一个cfree()?

    答:calloc(m, n) 本质上等价于:
    p = malloc(m * n);
    memset(p, 0, m * n);
    填充的零是全零, 因此不能确保生成有用的空指针值或浮点零值free()

    可以安全地用来释放calloc() 分配的内存。

    13. 我认为我的编译器有问题: 我注意到sizeof('a') 是2 而不是1 (即,不是sizeof(char))。

    答:可能有些令人吃惊, C语言中的字符常数是int 型, 因此sizeof('a') 是sizeof(int),这是另一个与C++ 不同的地方。

    14. 为什么声明extern int f(struct x *p); 报出了一个奇怪的警告信息“结构x 在参数列表中声明”?

    答:与C 语言通常的作用范围规则大相径庭的是, 在原型中第一次声明(甚至提到)的结构不能和同一源文件中的其它结构兼容,
    它在原型的结束出就超出了作用范围。要解决这个问题, 在同一源文件的原型之前放上这样的声明:
    struct x;
    它在文件范围内提供了一个不完整的结构x 的声明, 这样, 后续的用到结构x的声明至少能够确定它们引用的是同一个结构x。


    15. 我不明白为什么我不能象这样在初始化和数组维度中使用常量:const int n = 5; int a[n];

    答:const 限定词真正的含义是 “只读的”; 用它限定的对象是运行时 (同常) 不能被赋值的对象。
    因此用 const 限定的对象的值并不完全是一个真正的常量。
    在这点上 C 和 C++ 不一样。如果你需要真正的运行时常量, 使用预定义宏 #define(或enum)。

    16. 我能否把 main() 定义为 void, 以避免扰人的 “main无返回值”警告?

    答:不能。main() 必须声明为返回 int, 且没有参数或者接受适当类型的两个参数。
    如果你调用了 exit() 但还是有警告信息, 你可能需要插入一条冗余的 return语句
    (或者使用某种 “未到达”指令, 如果有的话)。很多书不负责任地在例子中使用 void main(),
    并宣称这样是正确的。但他们错了。


    17. #pragma 是什么, 有什么用?

    答:#pragam 指令提供了一种单一的明确定义的 “救生舱”, 可以用作各种 (不可移植的) 实现相关的控制和扩展:
    源码表控制、结构压缩、警告去除 (就像 lint 的老 /* NOTREACHED */注释), 等等。

    18. “#pragma once” 是什么意思?我在一些头文件中看到了它。

    答:这是某些预处理器实现的扩展用于使头文件自我识别; 它跟#ifndef技巧等价, 不过移植性差些。

  • 相关阅读:
    android 6.0 新特性
    接口_ _接口回调机制
    bug_ _
    volley_缓存介绍
    bug__android studio 出现布局文件不提示,且点击代码不能跟踪代码
    文章--笔记本蓝牙可以搜索到手机,但是怎么连接不了?
    Dialog_ _dialog系统样式讲解 及 透明背景
    动画_ _ Android应用开发之所有动画使用详解
    view坐标_ _ Android应用坐标系统全面详解
    html__脚本之家
  • 原文地址:https://www.cnblogs.com/dyufei/p/2574030.html
Copyright © 2011-2022 走看看