C puzzles详解【13-15题】
第十三题
int CountBits(unsigned int x){int count=0;while(x){count++;x = x&(x-1);}return count;}
知识点讲解
- 位运算
关于位运算的一些例子参考:
http://www.ugcs.caltech.edu/~wnoise/base2.html
题目讲解
x&(x-1)常见的两种应用:
1)计算x二进制形式中1的个数,每循环一次,将x二进制形式最右边的1变成0;
2)判断x是否是2的幂,若x&(x-1)==0,x为2的幂。
第十四题
Are the following two function prototypes same? int foobar(void);int foobar(); The following programs should be of some help in finding the answer: (Compile and run both the programs and see what happens) Program 1: #include <stdio.h>void foobar1(void){printf("In foobar1\n");}void foobar2(){printf("In foobar2\n");}int main(){char ch = 'a';foobar1();foobar2(33, ch);return 0;} Program 2: #include <stdio.h>void foobar1(void){printf("In foobar1\n");}void foobar2(){printf("In foobar2\n");}int main(){char ch = 'a';foobar1(33, ch);foobar2();return 0;}
知识点讲解
- foo()和foo(void)是不一样的
调用foo()时,可以传入任意个数,任意类型的参数,编译器不会关心传给foo的参数,传入的参数对foo函数的执行没有影响;
调用foo(void)时,不可传入参数,否则编译不通过;
void foo() {}是定义无参数函数的一种过时的用法,故日常编写代码时,若函数没有参数,最好写成foo(void)的形式。
题目讲解
Program 1能编译通过,运行后正常打印两个字符串;
Program 2编译不通过,提示foobar1参数过多。
第十五题
What's the output of the following program and why? #include <stdio.h>int main(){float a = 12.5;printf("%d\n", a);printf("%d\n", *(int *)&a);return 0;}
知识点讲解
- printf中的%f读取sizeof(double)个字节;
#include <stdio.h>int main() {int a = 10, b = 20, c = 30;printf("%f, %d\n", a, b, c);return 0; }
输出:0.000000, 30
调用printf时,双引号后面的所有参数从右往左依次入栈,然后将栈中的数据根据双引号中的格式从低地址向高地址依次读取并打印出来。
上述代码调用printf时,c,b,a依次入栈,%f读取sizeof(double)=8个字节,
即a,b所占的区域,转换成浮点数为0.000000,%d继续读取下面4个字节,即c所占的区域,转换为整型数为30。
- printf中传入的float型参数自动转换成double型;
#include <stdio.h>int main() {float a = 1.2;int b = 10;printf("%x, %x, %d\n", a, b);return 0; }
输出:40000000, 3ff33333, 10
调用printf时,参数a被转为double型后再传入printf,printf的前两个%x读取的是a所占的8个字节,%d读取的是b所占的4个字节。
gcc –S test.c命令可以生成汇编代码,上例的汇编代码主体如下:
main:pushl %ebpmovl %esp, %ebpandl $-16, %espsubl $32, %espmovl $0x3f99999a, %eaxmovl %eax, 28(%esp)movl $10, 24(%esp)flds 28(%esp)movl $.LC1, %eaxmovl 24(%esp), %edxmovl %edx, 12(%esp)fstpl 4(%esp)movl %eax, (%esp)call printfmovl $0, %eaxleaveret
“flds 28(%esp)”,flds将28(%esp)地址处的单精度浮点数即0x3f99999a加载到浮点寄存器,“fstpl 4(%esp)”即将浮点寄存器中的浮点数转换成double型后放到4(%esp)处。
- printf中的%c读取4个字节,printf的char型参数先转换为int再入栈;
#include <stdio.h>int main() {char a = 97;int b = 20;printf("%c, %d\n", a, b);return 0; }
输出:a, 20
上述c代码的汇编代码主体为:
main:pushl %ebpmovl %esp, %ebpandl $-16, %espsubl $32, %espmovb $97, 31(%esp)movl $20, 24(%esp)movsbl 31(%esp), %edxmovl $.LC0, %eaxmovl 24(%esp), %ecxmovl %ecx, 8(%esp)movl %edx, 4(%esp)movl %eax, (%esp)call printfmovl $0, %eaxleaveret
“movl %edx, 4(%esp)”在栈中压了4个字节。
- sizeof(‘a’)=4;
#include <stdio.h>int main() {char a = 'a';printf("%d, %d\n", sizeof(a), sizeof('a'));return 0; }
sizeof求类型的大小,sizeof(a)即sizeof(char),sizeof(‘a’)即sizeof(int),‘a’自动转换为int型。
题目讲解
“printf("%d\n", a);”,a转换为double型再入栈,%d读取double型数据的低4个字节;
“printf("%d\n", *(int *)&a);”float占4个字节,*(int *)&a将a在内存中存放值转换为整型数后再传入printf。
浮点数在内存中如何表示参考第九题讲解。
转载于:https://www.cnblogs.com/tanghuimin0713/p/3987527.html
C puzzles详解【13-15题】相关推荐
- 详解MindManager 15中文版中格式刷工具
2019独角兽企业重金招聘Python工程师标准>>> 制作MindManager思维导图时,其中很多资源来源于不同的外部资料,因为来源不同,复制粘贴的格式就可能不同. 巧妙使用Mi ...
- 14.VisualVM使用详解、15.VisualVM堆查看器使用的内存不足、19.class文件--文件结构--魔数、20.文件结构--常量池、21.文件结构访问标志(2个字节)、22.类加载机制概
14.VisualVM使用详解 15.VisualVM堆查看器使用的内存不足 16.性能调优概述 17.性能调优–案例1 18.性能调优-案例三 19.class文件–文件结构–魔数 20.文件结构– ...
- Linux-hexdump命令调试event驱动—详解(13)
2018-01-03阅读 6300 hexdump: 查看文件的内容,比如二进制文件中包含的某些字符串,通常用来调试驱动用 描述: 我们以event1为例,当我们insmod挂载了键盘驱动后,出现一个 ...
- php点击事件唤起微信聊天,vbot微信机器人微信聊天消息详解(15):点击消息
<vbot微信机器人微信聊天消息详解(15):点击消息>要点: 本文介绍了vbot微信机器人微信聊天消息详解(15):点击消息,希望对您有用.如果有疑问,可以联系我们. 点击是机器人在账号 ...
- 计算机二级excel13,计算机二级Excel篇-实操真题详解13
那就开始今天的教程吧 1.第1题,[Ctrl+C]复制,[Ctrl+V]粘贴,再右键[重命名],改成题目所要求的名字. 2.第2题,双击打开文件,找到涉及金额的单元格,按住[Shift]键往下拖,把右 ...
- 国际人工智能联合会理事会主席杨强详解JDD赛题玄机
11.11剁手结束了,就算你没剁手,女朋友.媳妇们剁了没?现在,一个机会摆在你的面前,一个改变命运的时刻就要到来,让你天天剁手都不再畏惧! 京东金融于11月6日正式启动首届"JDD-2017 ...
- 青少年编程scratch一级-熟悉编程软件(答案及详解+线上题库答题)
线上题库答题+自动评卷 https://blog.csdn.net/zhengzyx2040/article/details/118388826 scratch一级-熟悉编程软件试题 [熟悉编程软件] ...
- SaaS模式、技术与案例详解——第15章 SaaS平台的技术选型
[本章导读语] "笑嘻嘻的小猫咪,"爱丽斯问道,"请您告诉我,我应该走哪条路 呢?""那取决于您想去何方."小猫回答说. ________路 ...
- 匈牙利算法——最大匹配问题详解(附模板题)
基本概念转自 https://blog.csdn.net/dengheCSDN/article/details/77619308 匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名. ...
最新文章
- C#自定义控件四简易时钟
- 独家 | 麦肯锡教我的数据科学家的五大黄金法则
- 好的博客地址html
- 如何使用fdisk与parted对不同容量硬盘分区
- 在c语言中,可以使用动态内存分配技术定义元素个数可变的数组,C语言复制在线考题1精选.doc...
- 前端学习(1126):递归求数学题
- Nodejs 中的Get、Post
- nVelocity使用简介
- Manjaro下显卡相关的命令搜集
- 三 spring源码解析--- Bean解析接口结构分析
- 操作系统中的fork()函数对应的进程创建过程
- WinForm窗体及其控件的自适应
- Android wear 睡眠追踪,谷歌Fit应用更新 添加了新的健康中心和睡眠跟踪数据
- 求解字谜游戏问题-数据结构与算法分析-C语言描述 Mark Allen Weiss-第一章练习题
- 微信小程序引入字体图标 1
- linux 内核回调,Linux 内核通知链随笔【下】
- 爱沙尼亚LHV银行矢志不渝,设立区…
- c语言机票座位预定系统_c语言编写~~~机票座位预订系统
- Linux C 编程开发环境(工具链,编译,汇编,链接,库)基础知识与实践
- 为什么趋势(涨)都有大阳线回调