zoukankan      html  css  js  c++  java
  • 【基础复习】二:预处理、const与sizeof


    赋值语句

    1.i的值为?

    #include <iostream>
    using namespace std;
    int i = 1;
    int main() {
        int i = i;
    }
    

    解析:
    此时main函数内的i是优先考虑局部变量,除非使用作用域符号,否则是和外面值为1的i是无关的。
    其次,使用g++编译,g++ main.cpp -Wall就会出现提示说i是未定义值的警告,因此虽然此处的i会始终输出为0,但是实际上它是未定义值。
    传送门讲的比较清楚,要把声明、定义、初始化、赋值区分开,其中初始化又分为default initialization、 list initialization、 value initialization。第一个说内置类型的变量是未初始化的,第三个说内置类型的变量是初始化为0的,其实测试的结果更倾向为value initialization。


    2.以下代码输出的结果? ```c++ #include using namespace std;

    int main() {
    int x = 2, y, z;
    x *= (y = z = 5); cout << x << endl;
    z = 3;
    x == (y = z); cout << x << endl;
    x = (y==z); cout << x << endl;
    x = (y&z); cout << x << endl;
    x = (y&&z); cout << x << endl;
    y = 4;
    x = (y|z); cout << x << endl;
    x = (y||z); cout << x << endl;
    return 0;
    }

    **解析:**
    10   //赋值号是右结合的,赋值语句的返回值是赋值符号的左边的值
    10   //等于号是比较符号,是不会改变变量的值
    1    //判断相等的符号返回true/false,也就是1或0
    3    //按位取与运算
    1    //逻辑取与关系,两个运算变量都是0,结果才为0,否则为1
    7    //按位取或运算
    1    //逻辑取或运算
    
    
    ####i++
    1.下面两段代码输出有何不同?
    ```c++
    #include <iostream>
    using namespace std;
    
    int main() {
        int a, x;
        for (a = 0, x= 0; a <= 1 && !x++; a++) {
            a++;
        }
        cout << a << x << endl;
        return 0;
    }
    
    #include <iostream>
    using namespace std;
    
    int main() {
        int a, x;
        for (a = 0, x = 0; a <= 1 && !x++;) {
            a++;
        }
        cout << a << x << endl;
        return 0;
    }
    

    解析:
    分别是21和12,后置的自增符号相当于把自增拆出来,并放在后面一句就不多说了。


    2.下面代码的输出结果是什么? ```c #include

    int main() {
    int b = 3;
    int arr[] = {6, 7, 8, 9, 10};
    int *ptr = arr;
    *(ptr++) += 123;
    printf("%d %d ", *ptr, *(++ptr));
    }

    **解析:**
    8 8
    在打印前,数组的值为{129, 7, 8, 9, 10}, ptr指向第2个。
    由于C中的printf函数计算参数是从右到左压栈**(不同语言不同编译器的函数,参数入栈顺序是可以不同的,但是因为C支持可变参数函数,例如printf函数的参数就是不确定的,因此函数无法知道具体有多少参数,在创建被调用者的AC(activation record)时就采用了从右往左入栈参数的方式,这样第一个参数就在栈顶了,这个编译原理课的道理,这有[网上参考资料](http://blog.sina.com.cn/s/blog_54f82cc2010133mn.html),之后顺带提一下,C是不支持默认参数的**,关于编译器的新学到的知识,有两点,一点是副作用,一点是顺序点,大意就是在这个顺序点时,编译器要处理完前面所有语句带来的副作用,在这个点之后才可以进行新的语句的副作用的执行,那么,在两个顺序点之间的动作执行顺序是没有规定的哦,由不同家的编译器自己玩,科科[传送门](http://www.cnblogs.com/dolphin0520/archive/2011/04/20/2022330.html)
    最后,我们这一题,先算`*(++ptr)`,那就是第ptr指向了第三个并取值,之后再算左边也是变成取第三个值了哦,那就是8 8.
    后来经过测试(g++),发现从右往左压栈时,每次都计算了参数的值再压栈的。比如i++在i压栈后i自增,而++i是在压栈前自增再入栈。
    
    
    ####编程风格
    这个你已经很棒了,平时不要偷懒继续努力就好了啊,科科
    
    ####类型转换
    1.程序结果为?
    ```c++
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main() {
        float a = 1.0f;
        cout << (int)a << endl;
        cout << &a << endl;
        cout << (int&)a << endl;
        cout << boolalpha << ((int)a == (int&)a) << endl;
        //此时会输出什么?
    
        float b = 0.0f;
        cout << (int)b << endl;
        cout << &b << endl;
        cout << (int&)b << endl;
        cout << boolalpha << ((int)b == (int&)b) << endl;
        //此时会输出什么?
        return 0;
    }
    

    解析:
    a是一个float类型的数,float在内存中的存储方式请看传送门(0为特例,浮点数值为0时,指数和底数都为0),那么a内存中的32个字节放的是0 01111111 00000000000000000000000;一个int类型也是32个字节,int在内存中的存储方式请看传送门.
    (int)a表示将浮点数强制转换为整型,小数部分将被直接截断,结果为0;
    &a输出的是变量a在内存中的位置
    (int&)a,是用整型的解释方式来读取浮点数a的内存,结果就为 1065353216(127<<23)
    此时(int)a和(int&)a是不同的值,比较是否相等时输出false。
    而值为0的浮点数在内存中的表示,所有位上全为0.因此,此时用整型的解释方式读取内存得到的结果还是0.


    2.下面的程序结果是什么? ```c++ #include int main() { unsigned int a = 0xFFFFFFF7; unsigned char i = (unsigned char)a; char* b = (char*)&a;
    printf("%08x, %08x", i, *b);
    

    }

    **解析:**
    这里因为考虑是x86系列机器(《计算机组成原理》的相关知识啦),是小端存储(俗称“低低高高”,低字节放低地址,高字节放高地址),所以字符型i的内存是整型a的小端部分,也就是F7. 而b直接对a内存取地址并截取一个字节出来,此时得到的是小端部分F7。因为%08x是将参数以整型的16进制格式输出,不足部分左侧补符号位,i是无符号的,b是有符号的,所以输出为
    0x000000F7 和0xFFFFFFF7
    
    - 隐式类型转换
        - 在混合类型的算数表达式中,最宽的数据类型成为目标转换类型
        - 用一种类型的表达式赋值给另一种类型的对象,目标准换类型是被赋值对象的类型
        - 把一个表达式传递给一个函数,目标转换类型是形式参数的类型
        - 从一个函数返回一个表达式,目标转换类型是函数类型
    - 算数转换中的通用原则
        - 为防止精度丢失,总是提升为较宽类型
        - 小于整型的有序类型算数表达式在计算之前都转成整型
    
    ####运算符问题
    1.下面程序的结果?
    ```c++
    #include <iostream>
    using namespace std;
    
    int main() {
        unsigned char a=0xA5;
        unsigned char b=~a>>4+1;
        printf("b=%d
    ", b);
        return 0;
    }
    

    解析:
    b的值应该为((~a)>>(4+1)), 此时要进行算数运算就要涉及到一个“整数提升”的问题,也就是说a要转成int类型才能进行计算。
    那么a转成了0x000000A5, 进行取反0xFFFFFF02, 右移5位后,赋给b,则b截取了最右边的8位为11111010, 最后按照整型的类型打印,无符号位高字节补0,则可以得到:250(十进制)
    等号是最弱的会产生副作用的运算符,接着是移位,然后是四则运算,取值,单目运算等等等等


    2.用一个表达式判断一个数`x`是否是`2^N`,不可用循环语句 **解析:** `!(X&(X-1))`返回值为false说明是2的幂次方,否则不是
    3.下面代码的作用? ```c++ int f(int x, int y) { return (x&y)+((x^y)>>1) } ``` **解析:** 相同位的与 + 不同位的平均 = 两个数的平均值
    4.利用位运算实现两个整数的加法运算 **解析:** 递归的思想,[详细解释](http://blog.csdn.net/zhongjiekangping/article/details/6855864) ```c++ int Add(int a, int b) { if (b == 0) return a; int sum = a^b; int carry = (a&b)<<1; Add(sum, carry); } ```

    a、b交换与比较

    1.不使用"if"、"?:"、"switch"或其他判断语句,找出两个数中的最大值
    解释:
    方案一:利用abs函数

    int max = (abs(a-b)+(a+b))/2;
    

    方案二:判断差值的符号位
    方案三:采用bool值 ```c++ bool fun(int a, int b) { return a < b; }

    int max(int a, int b) {
    bool flag = fun(a, b);
    return flagb+(1-flag)a;
    }

    
    <br/>
    3.有两个数据,写一个交换两个数据的宏
    **解释:**
    方案一:利用异或运算(不考虑浮点数)
    `define swap(a, b) {a=a^b; b= a^b; a=a^b;}`
    <br/>
    方案二:利用加减法
    `define swap(a, b) {a=a+b; b = a-b; a = a-b;}`
    <br/>
    方案三:内存交换
    ```c++
    define swap(a, b) 
    {char tempBuf[10]; memcpy(tempBuf, &a, sizeof(a));
    memcpy(&a, &b, sizeof(b)); memcpy(&b, tempBuf, sizeof(b)); }
    

    C和C++的关系

    • c++语言支持函数重载,c语言不支持。c++通过加extern"C",调用c编译后的函数
    • ifndef/define/endif 是条件编译的一种,防止头文件重复引用、防止重定义(变量、宏或结构)
    • c是结构化的语言,重点在数据结构和算法,首先要考虑如何通过一个过程,对输入产生输出。
    • c++首先要考虑如何构造一个对象模型来解决问题。

    程序设计的其他问题

    这个就还是多刷刷题目吧,注意一些小细节就好啊,考虑问题要全面


    -from 《程序员面试宝典》

  • 相关阅读:
    MTGA天梯利用Ummored Ego进行针对核心卡列表
    三日狂欢_THDN_简介
    Unity_Dungeonize 随机生成迷宫
    Match3 Module For Game(THDN)
    UNITY->(width*height)style Inventory
    Mysql基本配置以及常见问题
    C++||变量
    c++||OOP
    c++||template
    实用的js函数
  • 原文地址:https://www.cnblogs.com/zengyh-1900/p/5227903.html
Copyright © 2011-2022 走看看