一个小笔记(6):常见小疑问

Q1:前置++与后置++的疑问?
int q = 10;
int a, b;
a = q++;
b = ++q;

a的值为10,b的值为12

【a = q++】
理解:先把q赋值给a,再把q自加1
实质:赋值符号的优先级低于后置++的优先级,所以并不是把q赋值给a后再将q加1。q++相当于调用了一个函数,会返回一个值,之后再将q自加1,返回的值赋值给a
【b = ++q】
将q自加1之后赋值给b

Q2:if(a + b > c) 和 if(c - a < b) 是否等价?
不等价,可能出现溢出问题

int a = 2000000000;
int b = 2000000000;
int c = 1000000000;
if(a + b > c)        // 结果为false,出现溢出
{}

Q3:异或运算符?
使用异或运算符交换2个数
void swap(int *a, int *b)
{
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
}

结论:
a = 0或者1、b = 0或者1
如果 a ^ b = k

a = b ^ k
b = a ^ k

异或运算符常用于简单的加密与解密

Q4:内存?
小字节序:数据在内存中,高位存放在高地址,低位存放在低地址
大字节序:数据在内存中,高位存放在低地址,低位存放在高地址



x86 CPU为小字节序,用于个人电脑
PPC CPU为大字节序,用于服务器

例1:
void fun()
{
    char Buf[4] = { 0 };
    int *p;
    p = (int *)Buf;
    *p = 0x11223344;
    printf("%x, %x, %x, %x\n", Buf[0], Buf[1], Buf[2], Buf[3]);
}

会输出什么?
输出:44,33,22,11


例2:
IP地址的表示?
union UN_IP
{
    unsigned int ip;
    unsigned char ucSec[4];
};

void fun()
{
    UN_IP unIP = { 0 };
    unIP.ucSec[0] = 192;
    unIP.ucSec[1] = 168;
    unIP.ucSec[2] = 1;
    unIP.ucSec[3] = 12;

    printf("%0x\n", unIP.ip);
}

会输出什么?
输出:c01a8c0
为什么?
按每2位分为1个16进制数可以得到4个16进制数:c   01   a8   c0
将16进制数换算成10进制数可以得到:12   1   168   192

Q5:int类型?
int类型的最大值:0x 7FFF FFFF
int类型的最小值:0x 7FFF FFFF + 1 = 0x 8000 0000

Q6:sizeof和strlen? 
例1:
char Buf[] = "Hello world";
printf("Buf    size: %d    len: %d\n", sizeof(Buf), strlen(Buf));        

会输出什么?   size:12 len:11
char Buf[] = "Hello world"  等价于  char Buf[12] = "Hello world\0"

例2:
char *pBuf = (char *)malloc(10);
printf("%d\n", strlen(pBuf));
free(pBuf);

会输出什么?   24(随机数值)
为什么是随机数值?strlen计数从pBuf地址开始,直到碰到'\0'为止。申请内存之后并没有进行赋值,地址数值未确定,'\0'也未确定,strlen计算的值为随机值

例3:
char Buf[5] = { 0 };
printf("Buf    size: %d    len: %d\n", sizeof(Buf), strle(Buf);
会输出什么?  size: 5   len: 0

例4:
char Buf[] = "Hello world";
char *p = Buf;
printf("Buf    size: %d    len: %d\n", sizeof(Buf), strlen(Buf));
printf("p       size: %d    len: %d\n", sizeof(p), strlen(p));

会输出什么?
Buf    size: 12   len: 11
p       size: 4     len: 11

为什么输出不一样,p为什么输出4?
使用sizeof来计算指针的大小时,指的是计算出指针所占内存的大小,在32位平台,指针占用4字节内存,所以是4

为什么在32位平台中,指针占4字节内存?
因为指针所在的内存地址,它存储的值实际上就是某个地址的地址值,这就是指针
地址值都是4个字节的,所以指针需要4个字节的内存空间来存放这个地址值


例5:
char Buf[] = "Hello world";
char *p = Buf;
printf("Buf    size: %d    len: %d\n", sizeof(Buf + 1), strlen(Buf + 1));

会输出什么?
Buf    size: 4   len: 10
为什么size是4?
Buf是字符串的首地址,在Buf+1时,Buf将是一个指针,进行指针运算来指向相应地址
在32位平台,只要是指针,sizeof得到的值就是4

例6:
sizeof(联合体)
值是多少?
取决于占用内存最大的那个类型

sizeof(结构体)
值是多少?
所有变量的占用内存之和


结论
sizeof:字符串定义多长,数值就有多长
strlen:碰到'\0'则结束计数

Q7:宏定义?
宏定义的本质是什么?替换

例1:
#define  ADD(a,b)  a + b
这样有问题吗?
有问题
int a = 10;
int b = 2;
int c = ADD(a,b) * 2;        
将ADD(a,b)替换之后: int c = a + b * 2;

例2:
#define  ADD(a,b)  (a + b)
这样有问题吗?
有问题
int a = 10;
int b = 2;
int c = ADD(a & 0xff, b & 0xff) * 2;
将ADD(a & 0xff, b & 0xff)替换之后:int c = (a & 0xf + b & 0xff) * 2
怎么改?
#define  ADD(a,b)  ((a) + (b))

例3:
#define  MUL(a,b)  (a)*(a)
这样有问题吗?
有问题
同例1
怎么改?
#define  MUL(a,b)  ((a) * (a))

posted @ 2016-07-13 17:34  Sky_天空  阅读(157)  评论(0编辑  收藏  举报