计算机常识总结

P1. Big-endian和Little-endian

查询wiki知道,“大小”的区别在于数据(以字节为单位)在内存中的排列顺序。比如存储一个int变量0x0A0B0C0D,从低地址到高地址看过来,“大端”的存储顺序比较自然一点——0x0A | 0x0B | 0x0C | 0x0D;而“小端”则是反过来的——0x0D | 0x0C | 0x0B | 0x0A。
一般intel的处理器都是“小端”的,写个代码测试下(想法其实就是测试int在内存里的首字节是高位还是低位):

#include 

int main() {
    int num = 0x0A0B0C0D;
    char first_byte = *(char*)(&num);

    if (first_byte == 0x0A)
        printf("Big endian\n");
    else if (first_byte == 0x0D)
        printf("Little endian\n");
    else
        printf("Can not judge: %d\n", int(first_byte));

    return 0;
}

哈哈,果然结果是Little endian。
字节序在网络传输的时候特别重要,因为各式各样的机器,大小端都有,统一为大端序传输(wiki说的)。至于这两种顺序的好坏,我觉得倒是都没有明显的好坏~

参考资料:
1) wiki百科
2)博客

P2. define的用法要注意

可能因为习惯用的是C++而不是C,所以平时比较少用——常量用const定义,而类型别名用typedef。不过也偶尔会写这样的代码:

#define Min(a, b) a > b ? a : b

最近看了一些面试题之后,发现这样写很不妥当,至少要用括号将a、b等给括起来,在一些意料不到的情况下,你会因为运算符的优先级等问题,导致bug,而这个bug你却很可能永远都不会找到,即推荐的写法为:

// 虽然写起来啰嗦了点,不过胜在可以避免极端的特殊情况
#define Min(a, b) ((a) > (b) ? (a) : (b))

下面是一个关于define的一个“缺点”的例子:

#define dtype int*
typedef int* ttype;

dtype a, b; // 展开后相当于:int* a; int b;
ttype c, d; // 展开后相当于:int* c; int* d;

P3. sizeof的问题

虽然用习惯了STL,很少用到sizeof,不过这是基础,应该必需清楚在心的,因为据说深入做网络编程的时候,更多的是直接跟各种内存、指针打交道(去年计网的嗅探telnet的密码的编程实验就可见一斑了)。一个demo足以说明用法了,需要注意的是,sizeof有点像一个define出来的宏,或者说它是一个运算符,而不是函数,为什么这么说呢?因为它的结果在编译时就计算出来了!而函数执行的结果,得运行时才能知道。

#include 

int main() {
    printf("bool:\t %lu\n", sizeof(bool));
    printf("char:\t %lu\n", sizeof(char));
    printf("int:\t %lu\n", sizeof(int));
    printf("LL:\t %lu\n", sizeof(long long));
    printf("size_t:\t %lu\n", sizeof(size_t));
    printf("float:\t %lu\n", sizeof(float));
    printf("double:\t %lu\n", sizeof(double));

    printf("bool*:\t %lu\n", sizeof(bool*));
    printf("char*:\t %lu\n", sizeof(char*));
    printf("int*:\t %lu\n", sizeof(int*));
    printf("LL*:\t %lu\n", sizeof(long long*));
    printf("size_t*:\t %lu\n", sizeof(size_t*));
    printf("float*:\t %lu\n", sizeof(float*));
    printf("double*:\t %lu\n", sizeof(double*));

    return 0;
}
/*
The result:
    bool:    1
    char:    1
    int:     4
    LL:  8
    size_t:  8
    float:   4
    double:  8
    bool*:   8
    char*:   8
    int*:    8
    LL*:     8
    size_t*:     8
    float*:  8
    double*:     8
*/

不过,下面这个例子则会让人迷惑得多,不是说好的编译时候就计算好了吗?怎么还可以跟随你运行时的输入而改变???

#include 

int main() {
    int a;
    scanf("%d", &a);
    const unsigned int size = a;
    int arr[size];
    printf("array size=%lu\n", sizeof(arr) / sizeof(int));

    return 0;
}

这个时候,就得去看sizeof的源码啦~[衰],不过找不到,且当做是一个宏吧,对于指针,它应该是有特殊的计算方法,编译过后的结果应该是一条表达式,而不是一个常量值(目测是这样,有知道的烦请告知我,thx)。

还有好多,待续~(2016.3.3写至P3)

你可能感兴趣的:(常识)