《 C 语言的一些“骚操作”及其深层理解》之关于变量互换与sizeof
扫描二维码
随时随地手机看文章
关于变量互换
初学C语言的时候,有一个小编程题我们应该都记得,就是变量互换。
int a,b;
int temp;
temp=a;
a=b;
b=temp;
变量a与b的值互换,在这过程中一定需要一个中间变量temp作为中转。不用这个中间变量能不能实现?请看下面的代码:
int a,b;
a=a+b;
b=a-b;
a=a-b;
可以说上面代码有点小巧妙,那么下面的代码就真正是巧妙了:
int a,b;
a=a^b;
b=a^b;
a=a^b;
异或运算有一个性质叫自反性,这个可以实现很多巧妙的操作,大家可以深入研究一下。(异或位运算比上面的加减法更严谨,因为加减法是可能会溢出的)
关于sizeof
C语言中的sizeof我们应该是非常熟悉的,它的作用就是用来计算一个变量或类型所占用的字节数。
sizeof(int) //如果是32位CPU平台,值为4,即4个字节
int a; sizeof(a) //同上
sizeof(struct ...) //计算某结构体的大小
这个很简单,我们再来看下面的代码:
char *pc="abc";
sizeof(pc) //指针的sizeof等于多少?
sizeof(*pc) //指针指向的单元的sizeof等于多少?
pc用来指向char类型的变量。pc本身是一个指针类型,在32位平台上sizeof(pc)的值为4,即指针类型占用4个字节(与CPU平台有关)。*pc是pc所指向的变量,所以sizeof(*pc)的值为1。
好,还能理解吧,那我们再来看:
char a1[]="abcd";
sizeof(a1) //数组的sizeof等于多少?
void fun(char a1[]) //形参a1的sizeof等于多少?
{
//....
}
第一个sizeof(a1)等于5,因为它是一个数组(最后还有一个字符串结束符’\0’)。第二个sizeof(a1)等于4,形参中的a1不再是一个数组,而是一个指针。
好,下面的实例估计很多人没见到过:
struct {} a,b,c;
sizeof(a) //空结构体的sizeof等于多少?
空结构体类型变量的大小是多少?这个问题似乎有些奇葩,没什么实用性。空结构体有什么用?
这个问题可以揭示一些比较深层的问题,我们平时注意不到。空结构体的大小是1,即占用1个字节。当我们的程序还仅仅是一个框架的时候,一些结构体还只是一个空壳,只是拿一个struct的定义在那占位置而已,此时就涉及到空结构体问题了。通常编译器会给空结构体分配1个字节的内存空间。为什么?如果不分配空间,那程序中的多个同类型结构体变量如何区分呢?比如a、b、c这三个变量,它们必须要被分配到不同的地址上去,各占1个字节的空间。
另外,因为sizeof有一个(),所以很多人想当然的把它当成一个函数。但其实它表达的是一个常数(运算符),它的值在程序编译期间就确定了。比如sizeof(i++),其中i为int类型,那么它的值就是4(32位平台)。