- 浏览: 3049313 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
这或许是很少见的用法,但我现在终于接受了一个事实:面试里出现的题目经常是极其恶心的代码,在实际工作中或许永远也见不到的那种.这是上个星期五土豆同学去参加的一个笔试里碰到的题,在这里记下来留作纪念.
问题: 下面的foo()的作用是什么?
foo()的内容尽量保持"原样"呈现.没错,那default标签后有对诡异的大括号,迷惑力极高.我一开始也中招了.
这题的意义是,C/C++的switch statement中,case/default标签无论出现在哪里都没关系,都能按照switch语义根据条件跳转到对应标签后执行.简单点说,在这题里的default后的那对大括号加不加是等价的,所以那个while循环不会被执行,而这个switch的意义就是把b中0到len % 8 - 1的内容复制到a中...
你中招了么? ^ ^
同样的情况在Java中就不会出现,因为Java中的switch statement不允许跨case的block,上面的default后的大括号就是非法的了.这段代码在Java中的等价物是:
不要被诡异的缩进迷惑了,实际上我应该把case label全部对齐到跟default在同一缩进上,只是为了保持"迷惑力"才写成现在这样...
关于Java的语句语法,可以参考语言规范: http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#35518
C#中的switch statement则更加严格,在Java的基础上外加不允许fall-through cases,所以上面的switch问题无法在C#中再现.
D的switch statement的行为与C/C++类似,不详细说了.
问题: 下面的foo()的作用是什么?
#include <stdio.h> #include <malloc.h> void foo(char* a, char* b, int len) { switch (len & 0x7) { default: { while (len > 7) { len -= 8; *a++ = *b++; } case 7: *a++ = *b++; case 6: *a++ = *b++; case 5: *a++ = *b++; case 4: *a++ = *b++; case 3: *a++ = *b++; case 2: *a++ = *b++; case 1: *a++ = *b++; } } } void main(void) { int i; int len = 26; char* a = (char*)malloc(100); char* b = "abcdefghijklmnopqrstuvwxyz\0"; for (i = 0; i < 100; i++) { a[i] = '\0'; } foo(a, b, len); /* a = "ab\0"; */ printf("%s\n%s", a, b); }
foo()的内容尽量保持"原样"呈现.没错,那default标签后有对诡异的大括号,迷惑力极高.我一开始也中招了.
这题的意义是,C/C++的switch statement中,case/default标签无论出现在哪里都没关系,都能按照switch语义根据条件跳转到对应标签后执行.简单点说,在这题里的default后的那对大括号加不加是等价的,所以那个while循环不会被执行,而这个switch的意义就是把b中0到len % 8 - 1的内容复制到a中...
你中招了么? ^ ^
同样的情况在Java中就不会出现,因为Java中的switch statement不允许跨case的block,上面的default后的大括号就是非法的了.这段代码在Java中的等价物是:
public class Test { public static void main(String[] args) { int i; int len = 26; char[] a = new char[100]; char[] b = "abcdefghijklmnopqrstuvwxyz".toCharArray(); for (i = 0; i < 100; i++) { a[i] = ' '; } foo(a, b, len); // a = "ab\0"; // length = len % 8 System.out.printf("%s\n%s", new String(a), new String(b)); } static void foo(char[] a, char[] b, int len) { int cursor = 0; switch (len & 0x7) { default: //{ while (len > 7) { len -= 8; a[cursor] = b[cursor]; cursor++; } case 7: a[cursor] = b[cursor]; cursor++; case 6: a[cursor] = b[cursor]; cursor++; case 5: a[cursor] = b[cursor]; cursor++; case 4: a[cursor] = b[cursor]; cursor++; case 3: a[cursor] = b[cursor]; cursor++; case 2: a[cursor] = b[cursor]; cursor++; case 1: a[cursor] = b[cursor]; cursor++; //} } } }
不要被诡异的缩进迷惑了,实际上我应该把case label全部对齐到跟default在同一缩进上,只是为了保持"迷惑力"才写成现在这样...
关于Java的语句语法,可以参考语言规范: http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#35518
C#中的switch statement则更加严格,在Java的基础上外加不允许fall-through cases,所以上面的switch问题无法在C#中再现.
D的switch statement的行为与C/C++类似,不详细说了.
void foo(char* a, char* b, int len) { switch (len & 0x7) { default: { while (len > 7) { len -= 8; *a++ = *b++; } case 7: *a++ = *b++; case 6: *a++ = *b++; case 5: *a++ = *b++; case 4: *a++ = *b++; case 3: *a++ = *b++; case 2: *a++ = *b++; case 1: *a++ = *b++; } } } void main(char[][] args) { int i; int len = 26; char[100] a; char[26] b = "abcdefghijklmnopqrstuvwxyz"; foreach (ref char c; a) { c = '\0'; } foo(&a[0], &b[0], len); printf("%.*s\n%.*s", a, b); }
评论
3 楼
zhczjx
2016-08-31
Mark一下 找了好久终于找到算法或者说这种写法的名字 Duff's Device。达夫设备
2 楼
RednaxelaFX
2007-10-25
啊,确实。8的倍数比较特别,我把这情况给漏了。8的倍数的时候,是7 + ( n / 8 )...多谢提醒 ^ ^
不过后来土豆告诉我,他把题记错了。这题实际上是这样的:
而这实际上不过是很常见的一种while循环展开而已。更出名的一种变体是这样的:
(摘自Java Language Specification, 3rd Edition)
不过后来土豆告诉我,他把题记错了。这题实际上是这样的:
#include <stdio.h> #include <malloc.h> void foo(char* a, char* b, int len) { switch (len & 0x7) { default: while (len > 7) { len -= 8; *a++ = *b++; case 7: *a++ = *b++; case 6: *a++ = *b++; case 5: *a++ = *b++; case 4: *a++ = *b++; case 3: *a++ = *b++; case 2: *a++ = *b++; case 1: *a++ = *b++; } } } void main(void) { int i; int len = 0; char* a = (char*)malloc(100); char* b = "abcdefghijklmnopqrstuvwxyz\0"; for (i = 0; i < 100; i++) { a[i] = '\0'; } foo(a, b, len); printf("%s\n%s", a, b); }
而这实际上不过是很常见的一种while循环展开而已。更出名的一种变体是这样的:
int q = ( n + 7 ) / 8; switch ( n % 8 ) { case 0: do { foo( ); // Great C hack, Tom, case 7: foo( ); // but it's not valid here. case 6: foo( ); case 5: foo( ); case 4: foo( ); case 3: foo( ); case 2: foo( ); case 1: foo( ); } while (--q > 0); }
(摘自Java Language Specification, 3rd Edition)
1 楼
afanti2005
2007-10-24
你输入一个能被8 len 的数试试
发表评论
-
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
基于LLVM实现VM的JIT的一些痛点
2014-01-07 17:25 0同事Philip Reames Sanjoy Das http ... -
tailcall notes
2013-12-27 07:42 0http://blogs.msdn.com/b/clrcode ... -
《自制编程语言》的一些笔记
2013-11-24 00:20 0http://kmaebashi.com/programmer ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22396(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局 (0): 拿在手上的是什么
2013-11-04 18:22 21495(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
Function.prototype.bind
2013-09-24 18:07 0polyfill http://stackoverflow. ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ... -
struct做参数不能从寄存器传?
2013-08-28 23:33 0test test test struct Foo { i ... -
也谈类型: 数据, 类型, 标签
2013-08-18 01:59 0numeric tower http://en.wikiped ... -
SDCC 2012上做的JVM分享
2012-10-17 16:35 32649刚把在SDCC 2012做的JVM分享的演示稿上传了。 演示 ... -
运行时支持系统的“重量”
2012-10-12 16:08 0运行时支持系统的“重量” 好久没写博客了,可写的话题已经堆积 ... -
class?metaclass?meta-what?
2011-04-05 19:43 0http://en.wikipedia.org/wiki/Me ... -
“代码模式”与抽象
2010-10-28 15:21 0嗯,我是说“代码模式”,不是“设计模式”;这里指的是在给定的场 ... -
lvalue与rvalue
2010-09-03 00:40 0http://en.wikipedia.org/wiki/Va ... -
动态链接的“依据”
2010-02-09 09:54 0动态链接,意味着在生成的“东西”里留有符号信息,等到运行时再r ...
相关推荐
【Linux C语言面试题】是针对C语言编程和Linux系统操作的面试准备资料,涵盖了从基础知识到高级概念的多个方面。这些题目旨在测试面试者对C语言的理解深度、编程技巧以及在Linux环境下解决问题的能力。以下是一些...
C 语言面试题总汇 本文档将详细介绍 C 语言面试题总汇,涵盖了 C 语言的各种知识点,包括静态变量、指针、引用、实时系统、堆栈溢出、虚函数、冒泡排序、网络协议、IP 地址等。 1. static 变量的用途: static ...
嵌入式C语言面试题汇总 本文档总结了嵌入式C语言面试中的常见问题,包括基本概念、程序代码评价、编程题等。以下是本文档的详细知识点总结: 一、基本概念 1. 静态关键字的作用:静态关键字有三个明显的作用:在...
C语言面试题大汇总中涵盖了许多重要的C语言概念和技术,这些知识点是面试中常见的问题,对于理解和掌握C语言至关重要。以下是其中一些关键知识点的详细解释: 1. **`static`关键字**: - `static`用于限制变量的...
C语言是计算机编程的基础,是许多现代软件和...通过这个“面试题合集.zip”,你可以系统地复习和提升C语言的理论知识和实践技能,为你的程序员面试做好充分准备。记得不仅要理解答案,还要能灵活运用到实际编程中去。
### C语言面试题知识点详解 #### 一、`static` 关键字的用途 1. **改变变量的连接方式(改成内部连接)** - `static`关键字用于变量时,可以使变量具有内部链接属性,这意味着变量只能在声明它的源文件中访问。...
C语言的基础知识包括变量、数据类型、运算符、流程控制(如if语句、switch语句、循环结构)、函数、指针、数组、结构体等。理解这些概念及其用法是C语言学习的第一步。例如,指针是C语言的一大特色,它允许直接操作...
本资料集"程序员面试题大集合"专注于C语言的笔试题,旨在帮助求职者在企业面试和笔试中脱颖而出。 首先,我们要理解C语言的基础知识。C语言是一种结构化编程语言,它提供了丰富的控制语句,如if-else、switch-case...
C语言是计算机编程的基础,尤其在面试中,掌握C语言的基本知识是至关...掌握这些基本概念对于理解和解答C语言面试题至关重要。通过深入理解并实践这些知识点,可以提高面试时的表现,为未来的职业发展奠定坚实基础。
本文档主要围绕C语言面试题展开,涵盖了字符串、字符数组、strcpy函数、strlen函数、static变量、auto变量、switch语句等多个知识点,旨在帮助读者巩固C语言基础知识,提高编程能力。 一、字符串和字符数组 在...
3. 流程控制:如if语句、switch语句、for循环、while循环等,是程序逻辑构建的关键。 4. 函数:函数是C语言中的重要模块,理解函数的定义、调用、参数传递及返回值,以及函数指针的概念。 二、指针与内存管理 1. ...
根据提供的文件信息,我们可以整理出一系列与C语言相关的面试题及知识点。下面将对这些知识点进行详细的阐述: ### 1. 静态变量(Static Variables) - **定义**: C语言中的静态变量是指在其作用域内保持其值不变...
1. **Switch语句与Case穿透**:在C语言中,如果没有显式使用`break`语句,控制流会继续执行下一个`case`块,直到遇到`break`或`switch`语句的结尾。因此,当`a`等于1时,`b`会被赋值为30,然后继续执行下一条语句,...
以下是一些C语言相关的面试题,旨在测试和提升你的C语言知识。 1. **基本概念** - 什么是C语言?C语言是由Dennis Ritchie在贝尔实验室开发的,它是一种面向过程的、低级的、结构化的编程语言。 - C语言的特点有...
《C程序员语言面试100题》是针对C语言编程技术的一份综合性的面试题集,涵盖了华为、中兴、阿里、腾讯等知名企业的常见笔试和面试问题。这份资料旨在帮助程序员深入理解和熟练掌握C语言的基础知识,以及在实际开发中...
文件"C语言面试题(1).doc"可能是文档形式的面试题集合,可能涵盖了C语言的基础知识,例如变量、数据类型、运算符、控制结构(如if语句、switch语句、循环)、函数、指针、数组、字符串、内存管理等方面的问题。...
C语言面试题总汇附答案 本资源提供了详细的C语言面试题,涵盖了C语言的基础知识、数据结构、算法、网络协议等方面。通过学习这些题目,能够帮助读者更好地理解C语言的概念和应用。 一、变量和存储域 * static变量...
这份“C语言面试题大汇总”PDF文档,虽然可能不是最全面的资源,但无疑能为面试者提供有价值的参考。 一、C语言基础 1. 数据类型:了解C语言中的基本数据类型,如int、char、float、double等,以及它们的存储大小...