`

C++ “Hello world!”的N种写法

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

int main()
{
    printf("Hello world!");                   // 教科书的写法
    puts("Hello world!");                     // 我最喜欢的
    puts("Hello" " " "world!");               // 拼接字符串
    std::cout << "Hello world!" << std::endl; // C++风格的教科书写法

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

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

#define Say(sth) puts(#sth)

int main()
{
    return Say(Hello world!);
}
请注意,这个Hello world可是完全没有出现引号哦!

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

int main()
{
    return puts(&"Do not say: Hello world!"[12]);
}

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

void say()
{
    printf("world!");
}

void sth()
{
    printf("Hello ");
}

int main()
{
    return atexit(say), atexit(sth);
}

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

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream ifs(__FILE__);
    std::string say, some, word;

    ifs >> say >> some >> word;
    std::cout << some << " " << word;

    return 0;
}

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

class say
{
public:
    say()
    {
        std::cout << "Hell";
    }

    ~say()
    {
        std::cout << "world!";
    }
}hello;

int main()
{
    std::cout << "o ";
    return 0;
}

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

template <char * words>
class say
{
public:
    void operator () ()
    {
        std::cout << words;
    }
};

extern char hello[] = "Hello world!";

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

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

class secret
{
private:
    virtual void say()
    {
        std::cout << "Hello world!";
    }
};

int main()
{
    secret word;
    (reinterpret_cast<void (*)()>(**(intptr_t**)(&word)))();

    return 0;
}

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

void say()
{
    puts("Hello world!");
    exit(0);
}

int main()
{
    volatile intptr_t a = 0;
    volatile intptr_t * p = &a;

    *(p + 2) = (intptr_t)say;
    *(p + 3) = (intptr_t)say;

    return 0;
}

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

void alien_say(char * p)
{
    while (putchar(*(p += *(p + 1) - *p)));
}

int main()
{
    return alien_say("BETHO! Altec oh liryom(a loadjudas!) dowd."), 0;
}

分享到:
评论

相关推荐

    “Hello world!”的N种写法

    C/C++语言本身有很多特性,如果能够将这些技术分解出来变成一个个的“Hello world!”,并且将这些技术点到为止,貌似也算是一件善事。 以下是十种不同的“Hello world!”写法: 1. 最经典的“Hello world!” ...

    hello world 的 N 种写法

    hello world 的 N 种写法 包含 批处理 汇编 vbs js c++ c# java boo 等近100种语言的HelloWorld

    C++ hello world 程序

    【C++ Hello World 程序】 C++是一种强大的、面向对象的编程语言,由Bjarne Stroustrup于1983年在C语言的基础上发展而来。它被广泛应用于系统软件、应用软件、游戏开发、设备驱动程序等多个领域。对于初学者来说,...

    hello world_helloworld_world_turnn6q_

    在C++中,一个简单的"Hello, World!"程序通常包含以下内容: ```cpp #include int main() { std::cout &lt;&lt; "Hello, World!" ; return 0; } ``` 这里,`#include &lt;iostream&gt;` 是预处理指令,它告诉编译器我们...

    Hello World的无用写法1(欢迎投稿!)

    c++

    c++测试程序

    C++是一种广泛应用于系统软件、应用软件、游戏开发、嵌入式系统等领域的高级编程语言。"Hello, World!"程序是编程初学者接触的第一课,它在C++中是用来演示基本的程序结构和编译流程的。这个压缩包文件"test"很可能...

    C++基础教程

    `是C++中的输出语句,`cout`是标准输出流,`操作符用于将字符串"Hello World!"输出到控制台。 - `return 0;`表示程序正常结束,返回值0通常表示程序成功执行。 6. **语句结尾**: - 每个C++语句以分号`;`结束,这...

    Hello-world:我的目标是写“你好,世界!” 用尽可能多的语言!

    而在Java中,会是一个完整的类定义:`public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }`。 2. **Mercury编程语言**: Mercury是一种逻辑/函数式...

    linux下的C++编程.pdf

    类的定义与使用:文档展示了如何定义一个简单的C++类Hello,并在main函数中创建这个类的实例和调用其成员函数Display来输出“Hello World!”。 GCC编译命令选项:文档显示了gcc和g++的一些命令行选项,如-c选项表示...

    Hello_World

    `public class HelloWorld`定义了一个公共类,`main`方法是程序的入口点,`System.out.println`用于打印输出。 3. **Python**: Python的代码非常简洁: ```python print("Hello, World!") ``` `print`函数...

    Professional C#, 3rd Edition_AppD_C# for C++ Developers.pdf

    ”程序在两种语言中的写法: ##### C++ ```cpp #include using namespace std; int main() { cout &lt;&lt; "Hello, World!" ; return 0; } ``` ##### C# ```csharp using System; class Program { static void ...

    C++ Swap函数有几种写法?

    在C++中,`swap`函数有多种不同的实现方式,每种都有其特定的适用场景和优缺点。这里我们将探讨几种常见的`swap`函数实现方法。 1. **基础的赋值交换**: 在C语言中,我们通常使用一个临时变量来交换两个变量的值...

    android中移植 c c++程序

    Android.mk 文件的格式和内容可以参考其他已有的 Android.mk 文件的写法,针对 helloworld 程序的 Android.mk 文件内容如下: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= /hello.c ...

    C++名字空间

    C++名字空间是一种用于组织标识符的方法,它提供了一种防止命名冲突的机制。随着软件项目规模的不断扩大以及多种第三方库的集成,命名冲突成为了程序员面临的一个常见问题。为了应对这一挑战,C++引入了名字空间的...

    qt基础入门经典手册(基础篇)

    - 另一种写法: ```cpp #include int main(int argc, char* argv[]) { std::cout &lt;&lt; "Hello World!" ; return 0; } ``` - **指针的概念**: - 指针用于存储变量的地址,通过指针可以访问变量。 - 示例:...

    Python 基础教程.doc

    在Python 2中,可以使用如下代码打印"Hello, World!": ```python #!/usr/bin/python print "Hello, World!" ``` 而在Python 3中,`print`被改为内置函数,写法变为: ```python #!/usr/bin/python3 print("Hello, ...

    C++/C基本编程技能

    第二种写法在满足条件的情况下性能更优,因为它避免了每次循环都需要检查条件。 ##### 五、内存管理问题 1. **GetMemory()函数问题** ```cpp void GetMemory(char *p) { p = (char *)malloc(100); } ``` ...

    C++prinmer答案

    3. **输出操作**:C++使用`std::cout`进行标准输出,例如打印"Hello, World"。输出语句可以通过`操作符连接,用于连续输出多个字符串或变量。 4. **算术运算符**:`+`是加法操作符,用于计算两个数的和;`*`是乘法...

    python3基础教程.docx

    而在Python 3.x中,由于`print`变成了内置函数,因此正确的写法是`print("Hello, World!")`。 Python的特点包括: 1. 易于学习:Python的语法简洁,关键字少,使得学习曲线较平缓。 2. 易于阅读:代码结构清晰,...

Global site tag (gtag.js) - Google Analytics