关于+—~有意思的一段C代码

关于+ - ~有意思的一段C代码

问题是钟哥几天前在automation的群里面抛出来的。

code:

#include <stdio.h>

int main(int argc,char* argv[])
{
        int a = 7;
        int b = 1;

        printf("before process,a = %d,b = %d\n",a,b);

        b  =  +~ +~ +~ +~ + ~~a;

        printf("after process,a = %d,b = %d\n",a,b);

        return 0;
} 

请问这段代码能过编译吗?

如果能过,ab最后的值是多少?

当然,我给出了解释的时候就会变得“这又什么意思咯,原来如此。。。”

既然到了把问题记录到blog的份上,代码肯定能过编译的,不然故事就没法继续编了。。。哈哈

一般的+用法都是 varible1+varible2; 是所作为双目operator。这里居然和+~混着用。一眼看去,貌似很乱,居然还能过编译

这里没有很“权威的说法”,C标准并没管这事,得出的结论是测试性的

+被用作单目操作符,表示数的正负。

也就是说+a 表示不改变a原来的符号,如果是个负数就是负数,是个正数就是正数。

如果是-a就是取a的相反数

  b  = +~ +~ +~ +~ + ~~a;

这里的~也就是普通的取反,这里+几乎不起作用,因为不改变a的值,~取反(bit inverse )6次,于是这里相当于b = a;

最后ab的值也分别是7 7

[email protected]:~/Desktop$ ./a.out

before process,a = 7,b = 1

after process,a = 7,b = 7

我们对代码稍作修改,继续对问题进行探讨

把+部分改成-,其他的不变,一步步的分析operator对a值的操作

#include <stdio.h>

int main(int argc,char* argv[])
{
        int a = 7;
        int b = 1;

        printf("before process,a = %d,b = %d\n",a,b);

        b  =  -~ -~ -~ +~ + ~~a;

        printf("after process,a = %d,b = %d\n",a,b);

        return 0;
}  

首先~~a对a取反两次,得到的值还是7,接着遇到第一个+,值不变,接着遇到~,此时bit inverse,a 由 0x00000007(假设32bit的机器)变成0xfffffff8 ,  接着遇到第二个+,值不变,接着遇到~,变回原来的0x00000007接着遇到-,变成-7,机器表示为0xfffffff9,再遇到~,取反,得到0x00000006,遇到-,即变-6,机器码为0xfffffffa,再遇到最后一个~,变成0x00000005,接着遇到最后的-,得到-5,赋值给b。

It was done!

[email protected]:~/Desktop$ ./a.out

before process,a = 7,b = 1

after process,a = 7,b = -5

Ok,看起来还比较有意思+~-

关于+—~有意思的一段C代码

时间: 2024-08-04 21:47:33

关于+—~有意思的一段C代码的相关文章

有意思的一段代码

有意思的一段代码: 1 %%% Message passing utility. 2 %%% User interface: 3 %%% logon(Name) 4 %%% One user at a time can log in from each Erlang node in the 5 %%% system messenger: and choose a suitable Name. If the Name 6 %%% is already logged in at another no

BSS段、数据段、代码段、堆与栈

BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域. BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域. 数据段属于静态内存分配. 代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区 域.这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读

Supermap iClient 空间查询关联外表表查询多表字段示例代码

原创文章,转载请注明出处!http://blog.csdn.net/songhfu 空间查询关联属性表,并查询空间表和关联表字段示例代码如下: /* * 关联测试成功代码 * */ var joinItem=new SuperMap.REST.JoinItem({ foreignTableName: "V_ENABLEVIEW_LAND", joinFilter: "BBS_PARCEL.CADASTRALNO = V_ENABLEVIEW_LAND.CADASTRALNO

程序中的bss段,data段,代码段,堆,栈

程序中的bss段,data段,代码段(.text),堆(heap),栈(stack) .bss段:程序中未初始化的和已经初始化为0的全局变量和已经初始化为0的静态局部变量(static) .data段:程序中已经初始化的非零的全局变量和已经初始化的非零的静态局部变量(static) 代码段:用来存放代码的地方(.text段),不可修改,存放在只读区域内. 堆:程序员自己申请的内存区域,也就是用malloc()函数申请的内存区域,用free()函数来释放的区域. 栈:存放局部变量的区域,函数中的局

因一段JavaScript代码引发的闲扯

前两天,一朋友给我发了一段JavaScript代码: function f1(){ var n=999; nAdd=function(){ n+=1 }; function f2(){ alert(n); } return f2; } var result1=f1(); var result2=f1(); result1(); // 999 result2();//999 nAdd(); result1(); // 是999而不是1000,这是为何呢? result2();//1000 问题的原

可执行程序包括BSS段、数据段、代码段

可执行程序包括BSS段.数据段.代码段(也称文本段). 一.BSS BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域.特点是:可读写的,在程序执行之前BSS段会自动清0.所以,未初始的全局变量在程序执行之前已经成0了. 注意和数据段的区别,BSS存放的是未初始化的全局变量和静态变量,数据段存放的是初始化后的全局变量和静态变量. UNIX下可使用size命令查看可执行文件的段大小信息.如size a.out. 二.数据段 在采

一段C++代码想到的问题

今天在学习<Unix环境高级编程>,第七章进程环境给出了一个进程的内存分布示意图,从下往上依次为“正文段->初始化数据->未初始化数据(默认初始化为0)->堆(从低地址到高地址)->栈(从高地址到低地址)->命令行参数和环境变量”.其中的正文段也叫代码段,是可共享的,只读的. 这个时候我就想到上次做的腾讯的一个题目,其实很简单,大概意思如下所示代码所示.大概意思是,先创建了一个类的对象a,再将a内存清0,然后直接调用两个的一个是虚函数一个是非虚函数,看看能否正确访

自己写的一段重试代码

public class TestRetry { public static void main(String[] args) { retry(5); } private static void retry(int maxCount) { int count = 0; boolean result = false; do { count++; System.out.println("count="+count); /* if(count==2) { result = true; }*/

(转)Linux下数据段的区别(数据段、代码段、堆栈段、BSS段)

进程(执行的程序)会占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途 不一而不尽相同,有些内存是事先静态分配和统一回收的,而有些却是按需要动态分配和回收的.对任何一个普通进程来讲,它都会涉及到5种不同的数据段. Linux进程的五个段 下面我们来简单归纳一下进程对应的内存空间中所包含的5种不同的数据区都是干什么的. BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BS