文档章节

C++十种方法"Hello World"

程序鸡
 程序鸡
发布于 2012/12/07 12:29
字数 1716
阅读 436
收藏 20

初学编程,无论是VB,C/C++,Java,C#大多都是从Hellow World这个程序开 始的,也是最常见的入门方法。C/C++本身有很多特性和用发,这里就用十种方法 实现Hellow World这个程序.

1. 最经典的“Hello world!”
“Hello world!”最经典的写法当然是直接用 printf 输出 “Hello world!”这几个字符了。无论用C还是 C++,写起来都非常的 简洁明了。这里把最常见的几个全部列在下面。

C/C++ 代码 复制内容到剪贴板
  1. #include <stdio.h>
  2. #include <iostream>
  3.  
  4. int main()
  5. {
  6. printf("Hello world! "); // 教科书的写法
  7. puts("Hello world!"); // 我最喜欢的
  8. puts("Hello" " " "world!"); // 拼接字符串
  9. std::cout << "Hello world!" << std::endl; // C++风格的教科书写法
  10.  
  11. return 0;
  12. }

特别需要注意的是,在C/C++里,如果两个字符串之间除空白符以外没有任何 东西,编译器会自动认为这两个字符串是连在一起的字符串。这样,如果一个字 符串过长,可以用这种方法换行来写,既不浪费性能,又美观。

2. 用宏写的“Hello world!”
在C/C++里,宏是一个神奇的东西。特别是在C语言中,宏可以帮我们做一些 “又脏又累”的活,包括拼接代码片断、隐藏繁琐的实现细节等等。 其中特别有趣的是“#”的用法,它可以“提取”参数的名 字,把它变成字符串。

请注意,这个Hello world可是完全没有出现引号哦!

C/C++ 代码 复制内容到剪贴板
  1. #include <stdio.h>
  2.  
  3. #define Say(sth) puts (#sth)
  4.  
  5. int main()
  6. {
  7. return Say(Hello world!);
  8. }

3. 断章取义的“Hello world!”
字符串是一种常量这当然毫无疑问,但是它的类型是什么,这就需要考虑一下了 。使用C++的typeid就可以这个问题的答案,而且只要是符合C或C++标准的编译器 就应该是一样的结果。比如字符串“Hello world!”,它的类型就是 char const [13]。
知道了这个,就可以写出以下的“Hello world!”:

C/C++ 代码 复制内容到剪贴板
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5. return puts ("Do not say: Hello world! "[12]);
  6. }

4. 退出时运行的“Hello world!”
大家都知道 main 函数退出意味着程序结束,可是这并不完全正确,我们完全可 以在 main 函数退出以后做很多事呢——比如说,输出“Hello world!”。这个功能依赖于C标准库中提供的函数 atexit(),调用这个函数 并注册自己的回调函数就行。需要注意,这个函数可以调用多次,最后注册的函 数最先执行。

C/C++ 代码 复制内容到剪贴板
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void say()
  5. {
  6. printf("world! ");
  7. }
  8.  
  9. void sth()
  10. {
  11. printf("Hello ");
  12. }
  13.  
  14. int main()
  15. {
  16. return atexit(say), atexit (sth);
  17. }
  18.  

5. 读取自己的“Hello world!”
C/C++的编译器提供了一些有用的内置宏,最常用的就是 __FILE__ 和 __LINE__ 了。其中,__FILE__ 代表当前的源文件的文件名,嗯,对了,如果我们让这个程 序读取自己的源文件,不就可以做一个很有意思的“Hello world!” 了么?

C/C++ 代码 复制内容到剪贴板
  1. // Hello world!
  2.  
  3. #include <iostream>
  4. #include <fstream>
  5. #include <string>
  6.  
  7. int main()
  8. {
  9. std::ifstream ifs(__FILE__);
  10. std::string say, some, word;
  11.  
  12. ifs >> say >> some >> word;
  13. std::cout << some << " " << word;
  14.  
  15. return 0;
  16. }
  17.  

6. 话分两头的“Hello world!”
有了C++的类,我们就可以光明正大的在 main 函数执行之前和之后做感兴趣的事 情了。我们可以声明一个全局的类的实例,这样,在 main 函数执行之前会调用 这个类的构造函数,结束之后则会调用析构函数。

C/C++ 代码 复制内容到剪贴板
  1. #include <iostream>
  2.  
  3. class say
  4. {
  5. public:
  6. say()
  7. {
  8. std::cout << "Hell";
  9. }
  10.  
  11. ~say()
  12. {
  13. std::cout << "world!";
  14. }
  15. }hello;
  16.  
  17. int main()
  18. {
  19. std::cout << "o ";
  20. return 0;
  21. }
  22.  

7. 传入模板的“Hello world!”
C++的模板功能极为强大,可以说是C++里面最艰深、最经典、最时尚的部分。一 个“Hello world!”当然无法使用很多很高级的模板技巧,我也不想 只使用模板特化这样无阻挂齿的小技巧,嗯,那就来演示一个比较罕见的用法吧 。

C/C++ 代码 复制内容到剪贴板
  1. #include <iostream>
  2.  
  3. template <char * words>
  4. class say
  5. {
  6. public:
  7. void operator () ()
  8. {
  9. std::cout << words;
  10. }
  11. };
  12.  
  13. extern char hello[] = "Hello world!";
  14.  
  15. int main()
  16. {
  17. return say<hello>()(), 0;
  18. }
  19.  

请注意,这个 extern 是十分必要的,只有加上了 extern,这个指针才是一 个编译器间可以确定的值,也才可以参与模板运算。还有,hello 必须为数组类 型,而不能为 char*,这个道理和加 extern 是一样的。
此外,这里还演示了 functor 的用法,嗯,关于它的优点就不在这里多说了,反 正是与原生指针相比有很多好处就是了。

8. 调用私有函数的“Hello world!”
我们知道,C++类的私有函数是不能被外界访问的,比如说 main 函数里面,它绝 对不能访问类的私有函数,除非把它设为类的友元函数。不过我们还是可以用一 些比较奇怪的方法访问类的私有函数——当然,这个私有函数必须满 足一个条件:它是虚函数。
这里就涉及到一个问题,指向虚函数的虚表放在哪里?对于 VS.Net 2003 而言, 虚表是类的第一个成员,虚函数指针按照函数声明的顺序放在虚表里面。当然, 这个说法并不严谨,更细节的东西还是去看看那本“成人高钙奶粉” 吧,它会给出最权威的解答。
这里是一个很有意思的例子:

C/C++ 代码 复制内容到剪贴板
  1. #include <iostream>
  2. #include <cstddef>
  3.  
  4. class secret
  5. {
  6. private:
  7. virtual void say()
  8. {
  9. std::cout << "Hello world!";
  10. }
  11. };
  12.  
  13. int main()
  14. {
  15. secret word;
  16. (reinterpret_cast<void (*)()>(**(intptr_t**)(&word)))();
  17.  
  18. return 0;
  19. }
  20.  

9. 最暴力的“Hello world!”
最暴力的调用函数的方法是:直接修改函数的返回地址,让这个地址指向我们想 要调用的函数。这也就是缓冲区溢出漏洞的应用方法了,不过里面还涉及到很多 问题,在这里就不一一列举,想要了解的话,还是去 Google 吧。这里只演示一 个可以在 VS.Net 2003 下可以用的“Hello world!”。

C/C++ 代码 复制内容到剪贴板
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4.  
  5. void say()
  6. {
  7. puts("Hello world!");
  8. exit(0);
  9. }
  10. int main()
  11. {
  12. volatile intptr_t a = 0;
  13. volatile intptr_t * p = &a;
  14.  
  15. *(p + 2) = (intptr_t)say;
  16. *(p + 3) = (intptr_t)say;
  17.  
  18. return 0;
  19. }
  20.  

10. 外星人说的“Hello world!”
好了,这个“Hello world!”是最匪夷所思的一个了!不过它并没有 涉及任何复杂的C/C++语言特性,只是看起来有点酷。你能看懂外星人在说什么不 ?

C/C++ 代码 复制内容到剪贴板
  1. #include <stdio.h>
  2.  
  3. void alien_say (char * p)
  4. {
  5. while (putchar (*(p += *(p + 1) - *p)));
  6. }
  7.  
  8. int main()
  9. {
  10. return alien_say ("BETHO! Altec oh liryom(a loadjudas!) dowd."), 0;
  11. }

© 著作权归作者所有

共有 人打赏支持
程序鸡

程序鸡

粉丝 3
博文 13
码字总数 12927
作品 0
成都
程序员
私信 提问
加载中

评论(3)

hangvo
hangvo
真的学习了。。。
l
loveShirly
~zZ
子达如何
子达如何
够蛋疼的,哈哈
string、string.h和ctring学习小结

string 和 string.h (和cstring等价)头文件的区别 为什么下面这段代码 #include void main() { string aaa= "abcsd d"; printf("looking for abc from abcdecd %s/n", (strcmp(aaa,"abc")) ......

长平狐
2013/01/06
640
0
利用Boost::Python实现C++调用python接口

Boost.Python能将C++的结构体暴露给Python使用。但是在运用Boost.Python时,却遇到一个难题, 1、在C++定义一个新的结构体struct A 2、将此结构体暴露给Python解释器 3、如今在工程中生成结构...

Start-up
2012/11/09
0
0
intel c++ 编译器编译失败

本人操作系统:Ubuntu 13.04 64位 Intel c++ 编译器版本:Intel(R) C Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.1.3.192 Build 20130607 在尝试编译c++......

breeze_bit
2013/08/20
1K
0
Visual Studio 11:使用 C++ 开发一个最简单的 Metro 应用

Visual Studio 11 消费者预览版支持使用 C++ 创建 Metro 风格的应用程序,这对广大本地应用开发者来说是一个大消息。这里我们来创建一个非常简单的 Metro 应用。 启动 Visual Studio 并通过 ...

曾沙
2012/11/27
618
0
webcppd v1.0.8 发布,升级为 httpevent

httpevent c++ and lua web framework 缘起 httpevent是webcppd的继承者。 由于webcppd内核采用的是Poco内置的多线程服务器,虽然性能不错,但是依然存在不小的提升空间。 httpevent不仅包含...

所以呢
2017/03/06
538
2

没有更多内容

加载失败,请刷新页面

加载更多

新技术不断涌现,下一代云计算的突破口在哪里?

这是一个IT技术飞速发展的时代,在硬件基础设施的不断升级以及虚拟化网络等技术的日益成熟下,云厂商也正面临着各种新技术带来的巨大挑战。从数据中心的基础建设到云平台的系统构建再到产品底...

UCloudTech
13分钟前
1
0
走进阿里云物联网

课程介绍: 阿里云IoT,致力于实现万物互联的美好世界,为生态合作伙伴提供基于云边端一体化、人工智能、安全的物联网基础平台和内容服务能力平台,通过该平台高效连接、管理设备的同时,开放...

mcy0425
20分钟前
1
0
Kylin2.5.0环境搭建及操作记录

Apache Kylin是一个开源的分布式分析引擎,提供Hadoop/Spark之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay Inc. 开发并贡献至开源社区。它能在亚秒内查询巨大的H...

PeakFang-BOK
29分钟前
2
0
SpringBoot整合es

文档对像 @Document(indexName = "bigdata",type = "tag")public class User { @Idprivate String openid; private List<String> tags;public String getOpenid() ......

魔法王者安琪拉
33分钟前
1
0
windows下让 jar 在后台运行的办法

windows下 运行 java jar 不出现 命令行 窗口 新建一个披处理 run.bat,内容如下 @echo off start javaw -jar xx.jar exit 双击运行即可。...

glen_xu
42分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部