• c& c++笔试题


    1 printf 和cout都是将输入按照从右到左压栈,然后输出依次出栈

    例子
    int arr[] = {6,7,8,9,10};
    int* ptr = arr;
    *(ptr++) += 123;
    cout<<*ptr<<" "<<*(++ptr)<<endl
    =================================
    8,8
    =================================
    在计算时,遇到x++会记录此时的x的值作为最后的输出结果。遇到x和++x的时候则不会将此时的计算结果作为最终的输出,只会修改x的值,在最终输出的时候都输出x的值(所以++x和x的结果总是一样的)。

    为什么会是这个样子呢?参见某高手解释吧:

          对于a++的结果,是有ebp寻址函数栈空间来记录中间结果的,在最后给printf压栈的时候,再从栈中把中间结果取出来;而对于++a的结果,则直接压寄存器变量,寄存器经过了所有的自增操作。 

    分析上面的,依次压入,但是,根据前面的定义,两者实际相等
     
    int x=1;   printf("%d %d %d %d %d ",x,x++,++x,x++,x);
    ===============================
    4 3 4 1 4
    ===============================
     
    2 两个数的较大值
    int max = (a+b+abs(a-b))/2
     
    3 宏定义最大值
    #deine MAX(A,B) ((A)>(B)?(A):(B))
     
    4 const 用途
    (1) 修饰常量
    (2) 修饰函数参数
    (3) 修饰函数返回值
    (4) 修饰函数定义
     
    5 sizeof 
    char s[] = "abc";
        cout<<strlen(s)<<endl;
        cout<<sizeof(s);
    =================
    3
    4
    =================
     
    6 指针数组 数组指针
    指针数组:指一个数组里面装着指针 int *ptr[]
    数组指针:指向数组的指针 int (*ptr)[] 
     
    7 int a[] = {1,2,3,4,5};
    int* ptr = (int*)(&a+1);
    printf("%d %d",*(a+1),*(ptr-1));
    a是数组名,是a[0]的一个别名,这样,&a相当于是一个指向a[0]的一个数组指针,数组指针+1相当于对整个数组的增加,所以,ptr现在是指向第6个(不存在),这样*(ptr-1)指向第5个元素,即5
    ===============================
    2,5
    ===============================
     
    8 c++有了malloc/free 为什么还用new/delete
    (1) malloc是c标准库,new是运算符
    (2)对于非内部类型的对象,例如class等,malloc无法完成
     
    9 char *a[] = {"abc","the","apple"};
        char**p = a;
        p++;
        cout<<*p<<endl;
    ====================
    the
    ====================
     
    10. TCP与UDP之间的区别
    (1)TCP是传输控制协议,提供的是面向连接、可靠的字节流服务,拥塞控制协议。
    TCP套接字由一个四元组(源IP,源端口号,目的IP,目的端口号)
    UDP(目的IP,目的端口号)
    1.基于连接与无连接;

    2.对系统资源的要求(TCP较多,UDP少);
    3.UDP程序结构较简单;
    4.流模式与数据报模式 ;
    5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。

     
     
    11
        char str1[] = "abc";
    char str2[] = "abc";
    const char str3[] = "abc";
    const char str4[] = "abc";
    const char* str5 = "abc";
    const char* str6 = "abc";
    cout << boolalpha << ( str1==str2 ) << endl; // 输ê?出3?什ê2么′?£?
    cout << boolalpha << ( str3==str4 ) << endl; // 输ê?出3?什ê2么′?£?
    cout << boolalpha << ( str5==str6 ) << endl; // 输ê?出3?什ê2么′?£?
    ==============================
    分别输出false,false,true。str1和str2都是字符数组,每个都有其自己的存储区,它们的值则是各存储区首地址,不等;str3和str4同上,只是按const语义,它们所指向的数据区不能修改。str5和str6并非数组而是字符指针,并不分配存储区,其后的“abc”以常量形式存于静态数据区,而它们自己仅是指向该区首地址的指针,相等。
    ==============================
     
    12 说一说C与C++的内存分配方式?

      1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,如全局变量,static变量。

      2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

      3)从堆上分配(动态内存分配)程序在运行的时候用malloc或new申请任意多少的内存,程序员负责在何时用free或delete释放内存。动态内存的生存期自己决定,使用非常灵活。


     
    13 析构函数为什么一般情况下要声明为虚函数?
    A2:虚函数是实现多态的基础,当我们通过基类的指针是析构子类对象时候,如果不定义成虚函数,那只调用基类的析构函数,子类的析构函数将不会被调用。如果定义为虚函数,则子类父类的析构函数都会被调用。
     
    14 c++中static用法
    (1)全局变量
    (2)变量作用域只限于此文件
     
    15
    union
    {
        int i;
        char x[2];
    }a;
     
    int main()
    {
        a.x[0] =10; 
        a.x[1] =1;
        printf("%d",a.i);
    }
    =================================
    266
    =================================
    低位低地址,高位高地址
    在内存中的情况应该是这样的:
    00000001 00001010(二进制)
    你要打印的i和x共享一片内存,输出来就是十进制266了。

    15

        char const str1[] = "abc";
        char const str2[] = "abc";
        const char* str3 = "abc";
        const char* str4 = "abc";
        cout<<boolalpha<<(str1==str2)<<endl;
        cout<<boolalpha<<(str3==str4)<<endl;

    ===================

    false

    true

    ===================

    解答:str1和str2两个字符数组存储在栈上,因此地址不相等,但是str3和str4以常量形式存储与常量区。

    16:

    int a[5]={1,2,3,4,5};
    int *ptr=(int *)(&a+1);
    printf("%d,%d",*(a+1),*(ptr-1));

    ============

    2,5

    ============

    17:

    struct A{
    int a;
    short b;
    char c;
    }*p;

    求p+0x10,(Ulong)p+0x10,(short*)p+0x10

    sizeof(A)为8,指针加减其实是指针所指向的元素的前后移动,因此加减的是指针的sizeof.因此第一个为p+(sizeof A)*0x10. 

    第二个则直接转换为整数,所以直接加减

    第三个则为p + (sizeof short)*0x10

    18:

    char a[] = "abc" #栈上分配

    char*a = "abc" #常量

    所以可以strcpy(a,"h")第一个可以,第二个不可以,因为常量不可修改

  • 相关阅读:
    洛谷 P1410 子序列(DP)
    LibreOJ #539. 「LibreOJ NOIP Round #1」旅游路线(倍增+二分)
    LibreOJ #541. 「LibreOJ NOIP Round #1」七曜圣贤(单调队列)
    浴谷八连测R6题解(收获颇丰.jpg)
    数论的一些小结论
    Fence9
    二模 (2) day1
    二模 (1) day2
    二模 (1) day1
    一些编码时的老错误
  • 原文地址:https://www.cnblogs.com/yxzfscg/p/4753301.html
Copyright © 2020-2023  润新知