面试题1-- C语言3

    技术2022-05-11  1

    )给定结构struct A {       char t:4;       char k:4;       unsigned short i:8;       unsigned long m;};问sizeof(A) = ?给定结构struct A {       char t:4; 4位       char k:4; 4位       unsigned short i:8; 8位             unsigned long m; // 偏移2字节保证4字节对齐}; // 共8字节2)下面的函数实现在一个数上加一个数,有什么错误?请改正。int add_n ( int n ){    static int i = 100;    i += n;    return i;}当你第二次调用时得不到正确的结果,难道你写个函数就是为了调用一次?问题就出在 static上?

    // 帮忙分析一下#include<iostream.h>#include <string.h>#include <malloc.h>#include <stdio.h>#include <stdlib.h>#include <memory.h>typedef struct  AA{        int b1:5;        int b2:2;}AA;void main(){        AA aa;        char cc[100];         strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");       memcpy(&aa,cc,sizeof(AA));        cout << aa.b1 <<endl;        cout << aa.b2 <<endl;}答案是 -16和1首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit.经过strcpy和memcpy后,aa的4个字节所存放的值是:0,1,2,3的ASC码,即00110000,00110001,00110010,00110011所以,最后一步:显示的是这4个字节的前5位,和之后的2位分别为:10000,和01因为int是有正负之分  所以:答案是-16和1

    求函数返回值,输入x=9999; int func ( x ){     int countx = 0;     while ( x )     {         countx ++;         x = x&(x-1);     }     return countx; } 结果呢?知道了这是统计9999的二进制数值中有多少个1的函数,且有9999=9×1024+512+256+15

    9×1024中含有1的个数为2;512中含有1的个数为1;256中含有1的个数为1;15中含有1的个数为4;故共有1的个数为8,结果为8。1000 - 1 = 0111,正好是原数取反。这就是原理。用这种方法来求1的个数是很效率很高的。不必去一个一个地移位。循环次数最少。

    int a,b,c 请写函数实现C=a+b ,不可以改变数据类型,如将c改为long int,关键是如何处理溢出问题bool add (int a, int b,int *c){*c=a+b;return (a>0 && b>0 &&(*c<a || *c<b) || (a<0 && b<0 &&(*c>a || *c>b)));}

    分析:struct bit {   int a:3;     int  b:2;     int c:3; }; int main() {   bit s;   char *c=(char*)&s;    cout<<sizeof(bit)<<endl;  *c=0x99;   cout << s.a <<endl <<s.b<<endl<<s.c<<endl;      int a=-1;   printf("%x",a);  return 0; } 输出为什么是41-1-4ffffffff因为0x99在内存中表示为 100 11 001 , a = 001, b = 11, c = 100当c为有符合数时, c = 100, 最高1为表示c为负数,负数在计算机用补码表示,所以c = -4;同理 b = -1;当c为有符合数时, c = 100,即 c = 4,同理 b = 3

    位域 :   有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:     struct 位域结构名     { 位域列表 };    其中位域列表的形式为: 类型说明符 位域名:位域长度     例如:     struct bs    {    int a:8;    int b:2;    int c:6;    };    位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:     struct bs    {    int a:8;    int b:2;    int c:6;    }data;    说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明:   

    1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:     struct bs    {    unsigned a:4    unsigned :0 /*空域*/    unsigned b:4 /*从下一单元开始存放*/    unsigned c:4    }    在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。   

    2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。   

    3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:     struct k    {    int a:1    int :2 /*该2位不能使用*/    int b:3    int c:2    };    从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。   

    二、位域的使用位域的使用和结构成员的使用相同,其一般形式为: 位域变量名•位域名 位域允许用各种格式输出。    main(){    struct bs    {    unsigned a:1;    unsigned b:3;    unsigned c:4;    } bit,*pbit;    bit.a=1;    bit.b=7;    bit.c=15;    pri

    改错:#include <stdio.h>

    int main(void) {

        int **p;    int arr[100];

        p = &arr;

        return 0;}解答:搞错了,是指针类型不同,int **p; //二级指针&arr; //得到的是指向第一维为100的数组的指针#include <stdio.h>int main(void) {int **p, *q;int arr[100];q = arr;p = &q;return 0;}

    下面这个程序执行后会有什么错误或者效果: #define MAX 255 int main(){   unsigned char A[MAX],i;//i被定义为unsigned char   for (i=0;i<=MAX;i++)      A[i]=i;}解答:死循环加数组越界访问(C/C++不进行数组越界检查)MAX=255 数组A的下标范围为:0..MAX-1,这是其一..其二.当i循环到255时,循环内执行:  A[255]=255;这句本身没有问题..但是返回for (i=0;i<=MAX;i++)语句时,由于unsigned char的取值范围在(0..255),i++以后i又为0了..无限循环下去.

    struct name1{   char  str;   short x;   int   num;}

    struct name2{   char str;   int num;   short x;}

    sizeof(struct name1)=8,sizeof(struct name2)=12在第二个结构中,为保证num按四个字节对齐,char后必须留出3字节的空间;同时为保证整个结构的自然对齐(这里是4字节对齐),在x后还要补齐2个字节,这样就是12字节。

    intel:A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。他们都放在数据区,但是编译器对他们的命名是不同的。如果要使变量在其他模块也有意义的话,需要使用extern关键字。

    struct s1{  int i: 8;  int j: 4;  int a: 3;  double b;};

    struct s2{  int i: 8;  int j: 4;  double b;  int a:3;};

    printf("sizeof(s1)= %d/n", sizeof(s1));printf("sizeof(s2)= %d/n", sizeof(s2));result: 16, 24第一个struct s1{  int i: 8;  int j: 4;  int a: 3;  double b;};理论上是这样的,首先是i在相对0的位置,占8位一个字节,然后,j就在相对一个字节的位置,由于一个位置的字节数是4位的倍数,因此不用对齐,就放在那里了,然后是a,要在3位的倍数关系的位置上,因此要移一位,在15位的位置上放下,目前总共是18位,折算过来是2字节2位的样子,由于double是8字节的,因此要在相对0要是8个字节的位置上放下,因此从18位开始到8个字节之间的位置被忽略,直接放在8字节的位置了,因此,总共是16字节。

    第二个最后会对照是不是结构体内最大数据的倍数,不是的话,会补成是最大数据的倍数上面是基本问题,接下来是编程问题:

    本人很弱,这几个题也搞不定,特来求救:1)读文件file1.txt的内容(例如):123456输出到file2.txt:563412(逆序)2)输出和为一个给定整数的所有组合例如n=55=1+4;5=2+3(相加的数不能重复)则输出1,4;2,3。望高手赐教!!

    第一题,注意可增长数组的应用.#include <stdio.h>#include <stdlib.h>

    int main(void){         int MAX = 10;int *a = (int *)malloc(MAX * sizeof(int));int *b;    FILE *fp1;FILE *fp2;

    fp1 = fopen("a.txt","r");if(fp1 == NULL){printf("error1");    exit(-1);}

        fp2 = fopen("b.txt","w");if(fp2 == NULL){printf("error2");    exit(-1);}

    int i = 0;    int j = 0;

    while(fscanf(fp1,"%d",&a[i]) != EOF){i++;j++;if(i >= MAX){MAX = 2 * MAX;b = (int*)realloc(a,MAX * sizeof(int));if(b == NULL){printf("error3");exit(-1);}a = b;}}

    for(;--j >= 0;)   fprintf(fp2,"%d/n",a[j]);

    fclose(fp1);fclose(fp2);

    return 0;

    }

    第二题.#include <stdio.h>

    int main(void){unsigned long int i,j,k;

    printf("please input the number/n");scanf("%d",&i);    if( i % 2 == 0)        j = i / 2;elsej = i / 2 + 1;

    printf("The result is /n");    for(k = 0; k < j; k++)     printf("%d = %d + %d/n",i,k,i - k);return 0;}

    #include <stdio.h>void main(){unsigned long int a,i=1;scanf("%d",&a);if(a%2==0){     for(i=1;i<a/2;i++)     printf("%d",a,a-i);}elsefor(i=1;i<=a/2;i++)        printf(" %d, %d",i,a-i);}

    兄弟,这样的题目若是做不出来实在是有些不应该, 给你一个递规反向输出字符串的例子,可谓是反序的经典例程.

    void inverse(char *p){    if( *p = = '/0' ) return;    inverse( p+1 );    printf( "%c", *p );}

    int main(int argc, char *argv[]){    inverse("abc/0");

        return 0;}

    借签了楼上的“递规反向输出”#include <stdio.h>void test(FILE *fread, FILE *fwrite){        char buf[1024] = {0};        if (!fgets(buf, sizeof(buf), fread))                return;        test( fread, fwrite );        fputs(buf, fwrite);}int main(int argc, char *argv[]){        FILE *fr = NULL;        FILE *fw = NULL;        fr = fopen("data", "rb");        fw = fopen("dataout", "wb");        test(fr, fw);        fclose(fr);        fclose(fw);        return 0;}

    在对齐为4的情况下struct BBB{   long num;   char *name;   short int data;   char ha;   short ba[5];}*p;p=0x1000000;p+0x200=____;(Ulong)p+0x200=____;(char*)p+0x200=____;希望各位达人给出答案和原因,谢谢拉解答:假设在32位CPU上,sizeof(long) = 4 bytessizeof(char *) = 4 bytessizeof(short int) = sizeof(short) = 2 bytessizeof(char) = 1 bytes

    由于是4字节对齐,sizeof(struct BBB) = sizeof(*p) = 4 + 4 + 2 + 1 + 1/*补齐*/ + 2*5 + 2/*补齐*/ = 24 bytes  (经Dev-C++验证)

    p=0x1000000;p+0x200=____;    = 0x1000000 + 0x200*24

    (Ulong)p+0x200=____;    = 0x1000000 + 0x200

    (char*)p+0x200=____;    = 0x1000000 + 0x200*4

    你可以参考一下指针运算的细节

    写一段程序,找出数组中第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)++;// 无效}输出:12 3 4 5 6 7 8 9 103. 写出程序运行结果

    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程序,防止僵尸进程的出现. 


    最新回复(0)