开始linux C编程之旅

1 开始编程

       编程不应该是枯燥的,而是有趣、有创造性的活动。所以,在学习编程的过程中,不应该死扣语法规则,以及各种诡异的语法代码,其实,那些诡异的语法代码都是给编译器看,甚至是钻编译器的漏洞。

       在实际的开发中,不应该写晦涩、难懂的代码,而且是禁止写这样的代码;提倡写简洁、清晰明了的代码。毕竟大型的项目,不是个人独秀的表演,而是一个团队合作的结果。

       例如Linux内核软件,是世界上许多优秀软件系统工程师的合作结果,如果写了晦涩的代码,肯定是不允许。linux 内核中的DTS设备树的出现,就是抽象、屏蔽了繁杂重复的芯片配置代码,最终,通过DTS配置文件来代替。所以,优秀的软件系统,也应该是模块化程度高,代码模块之间耦合度低的系统。

       OK,思路扯远了,总之,我们学习编程的过程应该是快乐、有趣的。最终,通过学习了Linux环境下的C语言编程,可以使用C语言开发有意义的软件系统。

       在学习的过程中,不要死扣语法,遇到有疑问的语法和问题,直接编写测试例子来验证。例如,我们疑问double类型的变量占据多少个字节?碰到这个问题的时候,我们就直接编写一个测试例子。

#include <stdio.h>            //包含头文件, 为了使用printf()函数;

 

int main()                           //定义程序的主函数, 就是程序的入口地址;

{                                        //主函数的开始标记;

 

       int size = sizeof(double);          //获取 double 类型定义变量的容量;

       printf("size = %d\n", size);       //输出 size 变量的内容;

 

       return 0;               //返回结束状态;

}                                        //主函数的结束标记;

 

       编译运行,输出的结果是:

gcc test.c -o out

mylinux@ubuntu:~/test$ ./out

size = 8

       此时,我们就知道double类型的变量占据8个字节的容量。而且是自己通过测试例子来验证,理解更加深刻。通过编写测试例子来思路和验证遇到的疑问,是我们学习知识的一种有效途径。

       毕竟我们学习是为了理解、获取到知识,而不是去死记硬背书本的知识;有时候书本和资料有误,自己去测试、验证的知识点才的正确的。最重要的是自己去测试验证过的问题才理解深刻。无论黑猫、白猫,抓到老鼠就是好猫;能够把问题讲清楚,讲明白;让大家学习到知识就是我们的宗旨。也是我们要学习的一种学习方法。

2 第一个例子获取系统时间

       通过前面的学习准备,我们在VMware中搭建了一个Ubuntu系统,并且介绍了编程过程中需要用到的一个工具软件和计算机系统知识。那么,现在我们就可以开始学习Linux C语言编程了。

       现在我们来写第一个程序,要求实现一个比较有趣的功能,就是输出当前Ubuntu系统的时间。例如,你和朋友约好今天晚上11点去干点坏事,但是,不知道现在几点了,那么,可以执行自己写的程序,查看当前的Ubuntu系统提供时间,以免误了你去干坏事。

       打开Ubuntu系统,使用用户名和密码登陆系统之后,同时按下Ctrl+Alt+T按钮,就弹出一个终端,如下图3-1所示。

图3-1

       这个终端就是我们工作的地方。OK,开始写程序,首先,我们新建一个工作目录,专门存放代码。例如你们把自己喜欢的电影,下载到某个目录一样。在终端中执行如下命令:

mkdir src

       此时,新建有一个文件夹,名称是src;然后,再执行下面的命令,进入该文件夹。

cd src/

       进入 src 文件夹之后,我们需要新建一个文件,存放编写的C代码。注意:存放C代码的文件,后缀是.c结尾,这样编译器就可以识别它是一个正确的C源码文件,然后,才可以编译源码。

       新建一个 test.c 文件,用于存放源码,执行如下的命令。

gedit test.c &

       操作的步骤如下图:

       此时,通过gedit命令,打开一个test.c文件,在末尾以“&”结尾,表示在后台运行gedit软件工具,不阻碍继续使用当前的终端。使用 gedit 命令打开test.c文件之后,弹出如下图3-3对话框。

图3-3

       此时,使用gedit工具打开一个test.c文件,然后,在文件中,输入如下的代码:

#include <stdio.h>            //包含头文件, 为了使用printf()函数;

#include <stdlib.h>           //包含头文件, 为了使用system()函数;

int main()                           //定义程序的主函数, 就是程序的入口地址;

{                                               //主函数的开始标记;

       printf("Now time =\n");    //输出提示;

       system("date");                  //输出系统时间;

       return 0;                             //返回结束状态;

}                                               //主函数的结束标记;

       注意,在程序中使用两个反斜杠“//”来做“注释”。在一行代码中,两个反斜杠“//”后面接着的数据表示注释数据,编译器不会编译这些数据。

       那么,在讲解编程代码例子的时候,作者会尽量给出完整的注释,这样有助于读者理解代码。但是,读者自己在测试、验证代码的时候,可以不用把注释也敲打如代码中。测试例子如下图3-4。

图3-4

       此时,我们在test.c文件中编写了程序的代码,但是,看起来还是缺少点什么!!!那就是“行号”,有时候编译代码出现异常,编译器会提示在哪一行出现问题,那么,我们需要定位到指定行数的代码,查找问题。

       那么,我们可以配置gedit软件显示行号,步骤是:选择菜单Edit  --> Preferences,然后,在弹出的对话框中,找到“Line Numbers”属性,把下面的“Display line numbers”复选框给勾选上,如下图:

       配置完之后,在代码中就显示了行号,效果如下图:

       编写完源码之后,按下Ctrl+s按键,保存编写的代码。然后,开始编译代码,编译代码格式是:

gcc xxx.c -o yyy

       使用gcc命令进行编译,在gcc命令后面,接空格,空格后面接xxx.c是需要编译的源码文件,然后接空格,空格后面接“-o”选项,表示编译出可执行程序;然后接空格,在空格后面接 yyy 表示编译出可执行程序的名称。

       例如,在终端输入如下的命令:

gcc test.c -o exe

       就是使用 gcc 命令编译 test.c 源码,产生 exe 可执行程序。最后,在当前终端输入 ./exe 来执行程序,测试的如下图3-5所示。

图3-5

       使用gcc编译产生了exe可执行程序,在执行exe程序的时候,在终端输入“./”表示执行当前目录下的程序,然后,接着exe,为“./exe”,表示执行当前目录下的exe程序。

       最终,执行 ./exe 程序,输出系统的当前时间,如下:

Now time =

Wed Jun 27 02:31:36 PDT 2018

       我们可以连续执行多次,每次看到时间都有变化,测试如下:

mylinux@ubuntu:~/src$ ./exe

Now time =

Wed Jun 27 02:37:07 PDT 2018

mylinux@ubuntu:~/src$

mylinux@ubuntu:~/src$ ./exe

Now time =

Wed Jun 27 02:37:08 PDT 2018

mylinux@ubuntu:~/src$ ./exe

Now time =

Wed Jun 27 02:37:10 PDT 2018

mylinux@ubuntu:~/src$ ./exe

Now time =

Wed Jun 27 02:37:11 PDT 2018

mylinux@ubuntu:~/src$ ./exe

Now time =

Wed Jun 27 02:37:12 PDT 2018

       可以看到,每次执行,都获取Ubuntu系统的当前时间,秒数显示的内容是有变化的。OK,有了这个获取时间的工具,再也不用担心耽误你去赶坏事的时间了。

3 分析程序

       我们学习了怎么样创建一个C源码文件(后缀是.c的文件,例如test.c),然后,编译程序,得到可执行的程序,最终执行程序。

       现在,我们来分析C源码文件中的C程序,就是所谓的“代码”。这个C程序的代码如下:

#include <stdio.h>            //包含头文件, 为了使用printf()函数;

#include <stdlib.h>           //包含头文件, 为了使用system()函数;

int main()                           //定义程序的主函数, 就是程序的入口地址;

{                                               //主函数的开始标记;

       printf("Now time =\n");    //输出提示;

       system("date");                  //输出系统时间;

       return 0;                             //返回结束状态;

}                                               //主函数的结束标记;

       现在我们来分析一个C程序主要有3部分组成:

(1) 包含头文件,引用系统提供的接口函数;

(2) 程序的主函数,即程序的入口地址,程序从哪个地方开始执行;

(3) 程序语句,实现程序功能的具体指令;如果把程序比作一栋大楼,那么,程序语句就是组成大楼的钢筋水泥;

3.1 包含头文件

       举个例子,如果大家要起一栋大楼,会用到铁铲、推车之类的工具。这些工具会存放在某个指定的地方,一般称为“仓库”。同样,程序中使用到了printf()这样的函数,这些函数如同铁铲之类的工具,存放在C语言的“仓库”中。那么,在C语言中,这些仓库我们可以称为“头文件”。

       C语言中定义的头文件,就是以.h为结尾的文件。例如 stdio.h、stdlib.h文件,就是系统提供的头文件。如同C语言提供的“仓库”,里面存放了许多有用的铁铲、推车等工具,使用这些工具,我们就可以开发出一个程序。

       要在代码中引用指定的头文件,格式如下:

#include <xxx.h>

       其中 xxx 的头文件的名称。这个格式是固定的,前面必须是 #include 关键字,然后使用尖括号“< >”,中间是引用的 .h 头文件。

       所以,我们知道了头文件的作用,就是一个仓库,存放很多编码使用的工具。我们必须使用仓库中的工具,才可以进行编码。随着学习的深入,我们可以定义自己的仓库,存放自己定义的函数模块。就是定义自己的.h头文件,然后,声明引出自己定义的函数,让其他模块使用。

3.2 程序的入口

       读书的时候,每一个学校都有一个校门口,要合法、正规地进入学校,就只能够通过校门口进入。当然也可以通过翻墙等行为进出学校,但是都不是学校所允许的。同样的道理,每一个程序要能够操作系统上正常运行,都必须提供一个入口,让操作系统通过这个入口,加载程序中的数据,然后,运行程序。

       C语言中定义了程序入口,就是main函数。在我们的测试例子中,有:

int main()                           //定义程序的主函数, 就是程序的入口地址;

{                                               //主函数的开始标记;

       printf("Now time =\n");    //输出提示;

       system("date");                  //输出系统时间;

       return 0;                             //返回结束状态;

}                                               //主函数的结束标记;

       这就是定义了main函数,这个main函数的定义是:

(1) 函数的返回值类型是 int类型,就是返回一个int类型的数据;

(2) 函数名的名称必须是main关键词;

(3) 函数名main后面接一个小括号(),括号里是空,表示不携带参数;

(4) 在小括号()后面接一个大括号{ },这个大括号{ }中的代码就是main函数要执行的代码;

(5) 执行代码的最后,通过 return 关键字返回0数值,就是为了符合main函数开始定义时,要求返回int类型的变量。

       在这里,我们讲解了main函数的定义,主要是说明main函数是程序的入口地址,如同一个学校的校门口一样,要通过校门口,才可以进入学校。同样,main函数提供了程序的入口地址,所以,我们要写的程序代码,就是在main函数中编写,main函数被操作系统调用之后,我们写的程序代码也就被操作系统调用执行。

       所以,在main函数中,我们就编写了需要执行的代码。       操作系统把程序加载到内存之后,找到main函数这个入口,然后,就一条一条地执行我们编写的代码。

3.3 函数体的代码

       程序的入口是从main函数开始,所以,我们要实现的代码也就是在main函数的函数体中编写。main函数的定义格式是:

int main()                           //定义程序的主函数, 就是程序的入口地址;

{

}                                               //主函数的结束标记;

       那么,函数体就是在大括号{ }中的代码。在测试例子中,函数体中的代码是:

printf("Now time =\n");    //输出提示;

system("date");                  //输出系统时间;

return 0;                             //返回结束状态;

       这些代码的作用是:

(1) printf函数输出 "Now time=\n" 字符串中的数据,后面的"\n"表示回车换行;

(2) system函数执行参数"date"指定的动作,获取系统时间输出;

(3) return 关键字返回一个值,表示退出main函数的运行;

       注意:每一行代码必须以引号“;”结束。除了遇到如下几种特殊情况:

(1) 使用#include包含头文件,不需要引号结束;

(2) 函数的声明,在小括号()后面,不需要引号结束;

(3) 函数体的大括号{}后面,不需要引号结束;

       那么,当我们学习了变量,运算符,表达式,输入/输出函数等知识之后,就可以自由编写函数体中的代码,实现更加复杂的功能。我们可以把想要计算机实现的功能通过C语言来描述,然后,编译成可执行程序来运行。

 

3.4 程序的注释

       我们先来看看一个测试例子:

#include <stdio.h>            //包含头文件, 为了使用printf()函数;

int main()                           //定义程序的主函数, 就是程序的入口地址;

{                                               //主函数的开始标记;

       /*注释

       可以注释 多行

       代码*/

       printf("test abc!\n");

       return 0;                      //返回结束状态;

}

       测试运行结果如下:

mylinux@ubuntu:~/src/test$ gcc test.c -o exe

mylinux@ubuntu:~/src/test$ ./exe

test abc!

       在这个测试例子中,我们主要讲解C语言的“注释”。在代码中添加注释很有必要,例如,我们需要描述某一段关键的代码,描述某一个函数模块的时候,就需要在代码中添加注释,那么,当一个项目有多个开发人员在共同开发时,大家可以通过代码的注释来快速了解代码的构造和设计。

       C语言提供了两种中注释方法:

(1) 单行注释

       在一行中,以两个反斜杠“//”开始,后面接着的数据就是注释。注释的数据不会被编译器编译,所以,注释里面写的东西可以中文或其他字符,不要求是C语言写的代码。注意:“//”注释符只能够在单一行中使用,不能够跨越多行。例如上面的例子中,有:

int main()                           //定义程序的主函数, 就是程序的入口地址;

       这是合法的,因为注释符“//”后面接的数据都是在一行中。

(2) 多行注释

       “多行注释”也称为“块注释”,就是可以注释多行代码块。多行注释是以“/*”开始,以“*/”结束。例如上面例子中的代码有:

/*注释

可以注释 多行

代码*/

printf("test abc!\n");

       就是通过 /*  */ 来注释多行。注意,多行注释符 /* */ 不能够嵌套,不能够编写 /* abc /*123*/www*/ 这样的嵌套注释,嵌套注释是不允许的。

       多行注释的规则是:从第一个 /* 符号开始,遇到第一个 */ 符号结束。所以,对于 /* abc /*123*/www*/ 这样的嵌套注释,只是注释了 /* abc /*123*/ 数据,剩下的 www*/没有配对,所以,是不合法的。

更多的交流可以加QQ:1523520001,微信:13926572996,备注:linux编程;
学习、分享更多的linux C/C++ 编程知识。

猜你喜欢

转载自blog.csdn.net/feng19870412/article/details/89203470