第一课

编程,其实就是把自己的想法通过电脑来实现出来。但是电脑有点呆头呆脑的,它们不会主动的理解你的想法,事实上它们只会按照你给的指令一步一步地去执行。如果上面的讲述你还不是很清楚,那么接下来,很快你就能够理解的。

和计算机交流是一件很让人脑大的事,它竟然不懂得人的语言,而且它还只能够理解一种特别的数值指令,并且只能循着这些数值指令来做些事。可是让我们通过这种数值指令来和计算机交流是非常困难的,所以我们只好采取一种折中的办法来搞定它了,我们以一种人类可以理解的语言来编写代码,然后再通过计算机把这些代码翻译成它自己可以理解的数值指令就可以啦。如果这种翻译工作是在程序运行时完成的,这种语言称为解释性语言;但是如果是在运行之前完成翻译工作的,那么这种语言就是编译语言,例如,c 和 c++ 就是编译语言。所以当编写 c++ 程序时,你使用自然语言(这些代码称为源码),然后编译器把这些源码翻译成机器可以理解的语言(这称为机器码)。

在 c++ 语言中,所有的计算机指令被以块的形式组织在一起,而这些块称之为函数。下面是一个函数的例子:

Void myFunction(void)
{
}

不管有没有数据,函数都可以完成运算,并且在它们完成工作时可以选择返回或者不返回结果。上面这个称为 myFunction 的函数既不需要数据,也不需要返回结果,可以说,它什么也不做,但是以这样的方式来定义一个函数也是可以的。

<outdata> <函数名> (indata)
{
    <函数内部定义>
}

用于输入函数的数据总是包含在一对小括号中“()”,而所有有关函数定义的内容都应该存在于一对大括号中“{}”。在后面的实践中,所有的大括号“{}”和小括号“()”都应该成对出现。

通常,编译器并不关心字符中间空格的多少,所以你可以根据自己的喜好添加空格以增加代码的可读性。在这里,我们以下面的方式来组织这些字符:

void MyFunction(void){}

即使这样做,有时候空格键的使用还是会产生代码阅读性差的问题。不过不必对这些特别在意,在 c++ 中每一句代码在它的结尾处都有一个分号来标识。

为了使我们的讲解的内容更加有意义,我们将会在接下来的代码编写过程中,尽量使用与 Haiku 开发人员相似的编码风格。例如,括号中的代码在编写的时候总是要使用 tab 键创建一个统一级别的缩进。

下面是我们创建的第一个稍微有点意义的函数:

int TwoPlusTwo(void)
{
    return 2+2;
}

上面的这个函数,函数名是 TwoPlusTwo ,这个函数不需要数据的输入,但是会返回一个函数结果。函数的通常会返回一个整型数据,就是那种中间没有小数点的数字。对于我们来说,一个数字仅仅就是一个数字而已,但是对于 c++ 来讲,数据的传递是一定要与数据的类型保持一致的。

每一个程序都有一个必须的函数,这个函数被定义为:main 。它可以有很多种定义方式(其实就是我们高速计算机如何来使用 main() 函数)。但是下面我们将使用最简单的方式来进行定义:

int main(void)
{
    return n;
}

这个程序编译运行后,不会产生任何输出。但是这个程序在它结束运行时确实会返还一个 “n” 给操作系统。

那么接下来,就让我们来实际的编译这个程序,将上面的代码保存为 ReturnOne.cpp。打开终端,将工作环境切换到这个文件所在的文件夹,然后输入下面的命令:

gcc -O ReturnOne.cpp

上面的命令告诉 GCC,你将要使用 returnone.cpp 来编译一个叫作 ReturnOne 的程序。

当然函数也可以调用其他的函数,但是只有当计算机中存在它们的信息时才有效。例如,下面的程序在编译时将会产生错误:

int main(void)
{
    PushTheRedButton();
    return 1;
}

把上面的代码保存为 RedButton.cpp,然后使用下面的命令进行编译:

gcc -O RedButton RedButton.cpp

由于计算机不能够识别出 PushTheRedButton() 这个函数,所以当它发现这个函数时不知所措了。但是如果我们能偶告诉计算机该怎么做,那么它就可以顺利地实现这个程序的编译工作。以下面的的方式修改 RedButton.cpp,然后再进行编译:

void PushTheRedButton(void)
{}
int main(void)
{
    PushTheRedButton();
    return 1;
}

在上面的程序中,PushTheRedButton 基本上什么都不做,但是计算机不在乎这些。还有一种调用函数的方法是使用系统内建的库函数,我们只需要告诉编译器所需要的库函数的是什么,然后将其连接进我们的程序中即可。那么接下来我们就开始进行一些更有意义的尝试了,把下面的代码保存为 HelloWorld.cpp,然后使用 gcc -O HelloWorld HelloWorld.cpp 来进行编译。

#include <stdio.h>
int main(void)
{
    printf("Hello world!\n");
    return 1;
}

在这段代码有两处代码段是我们所没有接触到的。

首先:以 #include 为开头的代码行告诉编译器中称被为预处理器的程序在系统头文件 stido.h 中寻找所定义的函数。stdio.h 是一个文件名,在其中定义了许多标准的输入输出函数,如 printf() 。尖括号 <> 告诉预处理器,这些引用的是系统头文件。当然我们也可以定制自己的头文件,但是这不是我们现在介绍的重点。

其次:另一个我们没有涉及到的部分是 printf() 函数的圆括号中的部分。如果你在终端中运行程序的话,那么圆括号中的任何东西都将会在屏幕上显示出来。这一种类型的数据被称为string(注意:字符串中的字符。)。

问题

如果我们将字符串末尾的反斜线 “/” 以及在它之后的 “n” 移去,如下所示 “Hello,world!” 那么将会产生什么样的结果呢?

练习

编写一个程序,让它在终端中显示一个有横线和竖线组成的盒子,这个盒子如下所示:

 ----------
|          |
|          |
|          |
|          |
 ----------

思考题

如何设计一个程序,使这个程序可以打印出类似上面的两个方盒子,但是不需要进行很多的横线和竖线?