• 腾讯、百度、阿里、微软面试题精选(不断更新)


    1、for(i=0;i<10;++i,sum+=i);  循环结束时 i 和sum的值分别是多少?
      分析:循环结束时 i=10应该没有问题,sum计算的位置不是很常见,每次sum+=i 时,i 的值都是先自加1,即 i(从0到9),计算sum时是从1加到10,结果55;
    如果是:for(i=0;i<10;++i)  sum+=i;  循环结束时 i 和sum的值分别是多少?
      这次 i 依然是10,但是sum就是0到9的加和,结果45。

    2、请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句。
      #define Max(a,b) ((a-b)&(0x80))? b:a
      #define Max(a,b) ((a-b)&(1<<31))? b:a  两种写法是等价的。
    注意:#define Max(a,b) (a/b)?a:b  这个答案是不全面的,只适用于正整数。

    3、不使用额外空间,将 A,B两链表的元素交叉归并。
      代码使用了递归的方式实现合并两个链表:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 typedef struct node
     5 {
     6     int val;
     7     struct node *next;
     8 }node;
     9 
    10 node* createList(int n)
    11 {
    12     node *head;
    13     node *pHead;//永远指向最新的节点
    14     node *pNext;//指向新添加的节点
    15     for(int i=0;i<n;i++)
    16     {
    17         if(i==0)
    18         {
    19             head=new node;
    20             cout<<"请输入第1个元素(头结点)的值:";
    21             cin>>head->val;
    22             head->next=NULL;
    23             pHead=head;
    24         }
    25         else
    26         {
    27             pNext=new node;
    28             cout<<"请输入第"<<i+1<<"个元素的值:";
    29             cin>>pNext->val;
    30             pNext->next=NULL;
    31             pHead->next=pNext;
    32             pHead=pNext;
    33         }
    34     }
    35     return head;
    36 }
    37 
    38 void mergeTwoList(node *headA,node *headB)//headA的长度大于等于headB的
    39 {
    40     if(headA==NULL||headB==NULL)
    41     {
    42         return;
    43     }
    44     mergeTwoList(headA->next,headB->next);//递归实现
    45     headB->next=headA->next;
    46     headA->next=headB;
    47 }
    48 
    49 int main()
    50 {
    51     node *headA;
    52     node *headB;
    53     node *newList;
    54     cout<<"新建链表A:\n";
    55     headA=createList(5);
    56     cout<<"新建链表B:\n";
    57     headB=createList(3);
    58     newList=headA;
    59     mergeTwoList(headA,headB);
    60     cout<<"合并后的新链表:"<<endl;
    61     while(newList!=NULL)
    62     {
    63         cout<<newList->val<<" ";
    64         newList=newList->next;
    65     }
    66     return 0;
    67 }

    4、*p=NULL *p=new char[100]  sizeof(p)各为多少?(一般都指的32位计算机)只要是指针变量都是4字节的,也就是计算机寻址空间是0到(2^32-1),即32位。

    5、C语言中的内存泄漏:

    动态内存的意思是程序运行时在堆上申请的内存。
    而静态内存是程序编译时,在静态存储区申请的内存。
    动态内存泄露指的是程序运行时,使用的new malloc realloc等函数没有与之匹配的delete free等函数。
    造成程序不断的同操作系统申请内存,而又不还给操作系统,申请的多了,操作系统本身也就没内存可用了。
    而应用程序,一旦退出,那么操作系统是会自动回收该应用程序所在进程的全部资源的,所以,泄露的内存也就会被操作系统全部回收。

    应用程序的内存分为四块:堆区,栈区,全局数据区,代码区  
    其中堆区需要程序员自己管理,我们申请的动态变量就存放在堆区,用完后需要程序员自己手动释放。
    若申请了一块动态内存,未释放,却丢失了指向性,这就叫内存泄露,会导致程序的可用内存减少,严重的话会拖垮操作系统。

    6、

    32位机上根据下面的代码,问哪些说法是正确的?()
    
        signed char a = 0xe0;
        unsigned int b = a;
        unsigned char c = a;
    
        A. a>0 && c>0 为真 
        B. a == c 为真 
        C. b 的十六进制表示是:0xffffffe0 
        D.上面都不对

    有符号数和无符号数之间的转换:c
    首先,a=1110 0000,首位是1,signed是有符号数,所以是负的;unsigned int 是4个字节的,无符号数,把a转换成b时,负数前面补1,正数补0,所以b的16进制表示0xffffffe0;
      c是无符号数,单字节的,c=0xe0,是正数。

    转一篇很好的博客,看了就懂了:

    #include <stdio.h>
    int main(int argc, char *argv[])
    {
    unsigned char a = -1;
    char b = a;
    printf("%d %d",a,b);

    return 0;
    }
    //结果:255  -1
    复制代码
    复制代码
    #include <stdio.h>
    int main(int argc, char *argv[])
    {
    unsigned short a = -1;
    short b = a;
    printf("%d %d",a,b);

    return 0;
    }
    //结果:65535 -1
    复制代码

    这是两段很简单的代码,我就以第二段代码为例。

         在计算机中,负数是以补码来存储的。  转载请注明出处http://www.cnblogs.com/stonehat/archive/2011/10/14/2212141.html

          C语言中常量整数 -1的补码表示为0xFFFFFFFF。截取后面16位FFFF赋值给 变量a(unsigned short)。此时 a = 0xFFFF(a没有符号位,0xFFFF转换为十进制为65535)

          a又将0xFFFF,直接赋值给short b。 此时 b = 0xFFFF(但是要注意,b是有符号的,0xFFFF转换为十进制为-1)

    执行printf("%d %d",a,b);的时候,要将 a和b的值先转换为int型:(这里是重点!!!)

     a没有符号所以转为int型为0x0000FFFF,

     b有符号转换为int型为0xFFFFFFFF。

    十进制输出值 65535  -1.   转载请注明出处http://www.cnblogs.com/stonehat/archive/2011/10/14/2212141.html

    复制代码
    #include <stdio.h>
    int main(int argc, char *argv[])
    {

    unsigned int a = -1;
    int b = a;
    printf("%d %d",a,b);

    return 0;
    }
    //结果 -1 -1
    复制代码

    转载请注明出处http://www.cnblogs.com/stonehat/archive/2011/10/14/2212141.html
    a在内存中值为0xFFFFFFFF,b的值为0xFFFFFFFF,都已经32位,

    a转换为int型的时候就是0xFFFFFFFF,所以输出-1.

    其实,记住两点就行了

    1.unsigned 类型转换为 signed类型的时候是直接复制到低位,高位为0.如果signed类型位数不够,只直接装载unsigned低位。

    2.signed类型转换为unsigned类型的时候,也是将补码直接复制到低位,高位为符号位。如果unsigned位数不够,只直接装载signed低位。

    7、

     1 下面哪些选项能编译通过 2 int i;
     3 char a[10]; 
     4 string f(); 
     5 string g(string &str);  
     6 
     7 A. if(!!i){f();} 
     8 B. g(f()); 
     9 C. a=a+1; 
    10 D. g("abc"); 

    解析:c、c++会给未初始化的变量随机赋值,所以A是可以的;B是错误的,因为一个函数的返回值是一个临时变量,g函数参数是一个引用变量,应该传入一个定义好的变量作为参数,例如 string a="abc";g(a);所以D也是错误的,如果是g(string str)函数,B、D都是对的。C是错的,因为a是指向数组a[10]的首地址的指针,是个常量,不能赋值的,就像5=5+1是不可能的。但是 char *p; p=a;p++;这就可以了,因为p是变量了。

    8、

    问下面的数据都存放在哪些存储区?
    
    int main()
    {
        char *p = "hello,world";
        return 0;
    }
    
    A. 堆和静态数据区
    B. 栈和静态数据区
    C. 栈和常量区
    D. 栈和堆

    解析:根据C语言中的特性和定义p是一个局部变量,而C语言中局部变量存在于栈中,"hello wrold"是一个字符串常量,因此存储于程序的只读存储区中,p在这里其实只是指向了"hello wrold"在只读存储区中的地址而已。

    12、问题:在一个二维数组中,每行的元素从左到右是递增的,每列元素从上到下是递增的。写一个函数,查找一给定的元素是否在此数组中

    输入:一个二维数组,和一个待查找的数

    输出:待查找的数在数组中输出“YES",否则输出”NO"

    原始思路:最简单思路就是暴力搜索,遍历一遍数组中的元素时间复杂度为O(n2)。但是这样就没有用问题的已知条件(从左到右、从上到下递增),因此不是个好的解法

    改进1:从第一行开始找,找到待查元素大的,如果还没找到,接着从第二行开始找,直到找到或到最后一个元素为止(如图),但是如果带查找的元素在最后,还得遍历到最后,时间复杂度还是O(n2)

            

    改进2:上来在随机在里面挑一个,如果正好逮住,那就结束了;如果比待查找的元素大,那么他的左边和上边;否则在右边和下边。如下图。这样下来可以减少一部分元素的比较。在寻找1时,会话费反而很多时间,并不是个好的解决办法。

               

    改进3:看两个比较关键的两个点——左下角和右上角。以右上角为例(如下图)。如果右上角元素等于带查找元素,那就返回真;如果右上角元素大于待查找元素,那就删除右上角元素所在列;否则删除其所在行。依次进行下去。

                      

    举例说明
          

    参考代码一

     
    #include <stdio.h>
    
    int find_value(int a[][4], int value, int x, int y)//(x,y)表示右上角坐标
    {
        if ((x >= 0) && (y < 4))
        {
            if (a[x][y] ==  value)
                return 1;
            else if (a[x][y] > value)
                return find_value(a, value, x-1, y);
            else
                return find_value(a, value, x, y+1);
        }
    
        return 0;
    }
    
    int main()
    {
        int a[4][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        int val;
        printf("Enter your number:");
        scanf("%d", &val);
        if(find_value(a, val, 3, 0))
            printf("Yes, find it\n");
        else
            printf("No, not find it\n");
    
        return 0;
    }
  • 相关阅读:
    从内积的观点来看线性方程组
    《线性规划》(卢开澄,卢华明) 例2.1
    斐波那契数列
    共几只桃子
    计算 $s=1+(1+2)+(1+2+3)+cdots+(1+2+3+cdots+n)$
    【★】路由环路大总结!
    Apache与Tomcat有什么关系和区别
    Apache与Tomcat有什么关系和区别
    逻辑卷、物理卷、卷组 的关系
    逻辑卷、物理卷、卷组 的关系
  • 原文地址:https://www.cnblogs.com/nannanITeye/p/3005999.html
Copyright © 2020-2023  润新知