C/C++ 2月

来源:互联网 发布:c语言逻辑符号 编辑:程序博客网 时间:2024/06/03 14:49
2017年4月18日 20:57:28


2017年2月20日
1.
    int main()
    {
        int a[5] = {1,2,3,4,5};
        int *ptr = (int *)(&a + 1);
        printf("%d,%d",*(a+1),*(ptr - 1));     //输出2,5
        return 0;
    }

2.
    template<class , T > class BigNumber
    {
        long n;
    public :
        BigNumber(T i) : n(i)
        {

        }

        BigNumber operator + (BigNumber b)
        {
            return BigNumber(n + b.n);
        }
    };

    3+b1错误,b1+3正确,b1+b2正确

3.
    class Test
    {
    public :
        int a;
        int b;
        virtual void fun() {}
        ....
    };

    int main()
    {
        Test obj(5,10);
        int *pInt = (int *) & obj;
        *(pInt + 0) = 100;        //pInt指向了地址的首部也就是虚函数表指针
        *(pInt + 1) = 200;        //所以*(pInt + 0)改变的是虚函数表指针,*(pInt + 1)改变的是变量a。b没有改变
        return 0;       
    }

4.构造函数初始化时必须采用初始化列表的情况:
    (1)需要初始化的数据成员是对象(继承时调用基类构造函数)
    (2)需要初始化const修饰的类成员
    (3)需要初始化引用成员数据        float * &c;//这是指针的引用
            static 修饰的属于类,不能在类内初始化,必须在类定义体的外部定义,类内只是声明
            const 成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行且必须有构造函数
            const 只有某个对象生存期内是常量,对于整个类是可变的

5. 以下返回为1的选项
    A. 正常退出                //return 0
    B. return (7&1);        // 7 & 1 即 111 & 001 = 001
    C. char *str = "mic"; return str == "mic";    //str指向"mic"的首地址,所以两个地址相同
    D. return "mic" == "mic";    //两个地址相同


2017年2月21日
1.    x = 9999时
    int func(int x)
    {
        int count = 0;
        while(x)        //一个数与这个数减1的结果进行'&'按位与运算,结果为:这个数二进制最右边的1变为0
        {
            count++;
            x = x & (x - 1);    //统计x中1的个数
        }
        return count;
    }

2. 编译时只是把函数的符号地址记录下来,链接时,该函数符号有定义才会变成具体的地址
    链接是处理可重定义文件,把它们的各种符号,引用和符号定义转换为可执行文件中的合适信息
    (一般是虚拟内存地址)的过程
    所以链接可以发现被调用函数未定义

3. 64位操作系统上,内存对齐时,默认8字节空间

4. int Function(unsigned int n)
   {
       n = (n & 0x5555 5555) + ((n >> 1) & 0x5555 5555);    //相邻两位1的个数,5 : 0101
       n = (n & 0x3333 3333) + ((n >> 2) & 0x3333 3333);    //相邻四位1的个数
       n = (n & 0x0f0f 0f0f) + ((n >> 4) & 0x0f0f 0f0f);    //相邻八位1的个数
       n = (n & 0x00ff 00ff) + ((n >> 8) & 0x00ff 00ff);    //相邻16位1的个数
       n = (n & 0x0000 ffff) + ((n >> 16) & 0x0000 ffff);    //相邻32位1的个数
       return n;
   }


2017年2月22日

1、当使用容器时的insert或erase函数,通过迭代器插入或删除元素,“可能”会使迭代器失效的两种情况:
    (1)iterator变量已变成“野指针”
    (2)iterator 所指变量不是程序员所认为的变量
    数组型数据结构:
        元素分配在连续的内存中,insert和erase操作,会使得之后的元素移位,所以该点和之后元素的
        迭代器全部失效。
        解决方法:erase(iter)返回值为下一个有效迭代器
                  所以:iter = cont.erase(iter);

    结点类容器:
    (1)链表型:不会失效其他迭代器,方法:iter = cont.erase(iter); 或  cont.erase(iter++);
     (2) 树形:使用红黑树存储数据,不会使任何迭代器失效,所以:cont.erase(iter++);

2、逗号运算符的优先级最低(比‘=’还低)

3、map不是顺序存储,只有删除元素时,对指向删除元素的迭代器有影响
   vector 中,如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的remove或add方法之外
   的其他方法),则迭代器将抛出ConcurrentModification Exception


2017年2月23日

1、 引用是除指针外,可以产生多态效果的手段,一个基类的引用可以指向它的派生类

2、 C#抽象类用abstract修饰

2017年2月24日   

1、void test (int a) { ... }
   void test (float a) { ... }
   调用:
   test(0.5);    //调用失败,因为0.5默认为doule,转换失败

2、void recursive(int n, int m, int o)
   {
           if(n <= 0)
           {
               printf("%d,%d\n",m,o);
           }
           else
           {
            recursive(n - 1, m + 1, o);
            recursive(n - 1, m, o + 1);               
           }
   }
   //时间复杂度为O(2^n),因为n递归两次n - 1, n - 1 递归两次 n - 2 .......
   //所以是一个完全二叉树,总共2^n - 1次

3、 * 优先级低,比 [] 低
    所以 : X[1][2] 与 *(X+1)[2]不等,后者相当于对地址(X+1)[2]取值

4、 数组作为形参时,数组名会退化成一个指向该类型数组的指针

2017年2月25日

1、在嵌套使用 if 语句时,C语言规定:
    else 总是和之前与其最近且不带 else 的 if 配对

2、在64位机上,指针为8字节,int 仍然为4字节,char 为 1 字节

2017年2月27日

1、void GetMemory(char *p)
  {
           p = (char *)malloc(100);    //局部变量分配空间,str仍指向NULL
   }

   void Test()
   {
           char *str = NULL;
           GetMemory(str);
           strcpy(str,"Hello");        //对空地址做操作
   }

2、int a = 5,则 ++(a++)的值是什么?
    答案:
        编译出错
        因为:一、(a++) 为表达式,不能对表达式自加
              二、 a++ 返回5,++5,错误

3、 class A
    {
        int i;
    };

    class B
    {
        A *p;
    public :
        B() { p = new A; }
        ~B() { delete p; }
    };

    void SayHello(B b)        //程序会崩溃
    {                        //调用SayHello时,会使用默认的copy构造函数,造成浅拷贝
        ....                //所以会对同一个空间释放两次
    }

    int main()
    {
        B b;
        SayHello(b);
        return 0;
    }

4、在 vector 中
    end()返回最后一个元素的下一个
    erase() 会使 end()移动
0 0
原创粉丝点击