admin管理员组

文章数量:1530305

第一个C语言程序

我们有两种方式从计算机获得信息:一是看屏幕上的文字、图片、视频等,二是听从喇叭发出来的声音。让喇叭发出声音目前还比较麻烦,我们先来看看如何在屏幕上显示一些文字吧。

在屏幕上显示文字非常简单,只需要一个语句,例如,下面的代码会让屏幕显示出“C语言中文网”:

puts("C语言中文网");

这里有一个生疏的词汇puts,用来让计算机在屏幕上显示文字。

更加专业的称呼:

  • "在屏幕上显示文字"叫做输出(Output);
  • 每个文字都是一个字符(Character);
  • 多个字符组合起来,就是一个字符序列,叫做字符串(String)。


puts 是 output string 的缩写,意思是”输出字符串“。

在C语言中,字符串需要用双引号" "包围起来,C语言中文网什么也不是,计算机不认识它,"C语言中文网"才是字符串。

puts 在输出字符串的时候,需要将字符串放在( )内。

在汉语和英语中,分别使用.表示一句话的结束,而在C语言中,使用;表示一个语句的结束。puts("C语言中文网")表达了完整的意思,是一个完整的语句,需要在最后加上;,表示当前语句结束了。

总结起来,上面的语句可以分为三个部分:

  • puts( )命令计算机输出字符串;
  • "C语言中文网"是要输出的内容;
  • ;表示语句结束。

C语言程序的整体框架

puts 可以在显示器上输出内容,但是仅有 puts 是不够的,程序不能运行,还需要添加其他代码,构成一个完整的框架。完整的程序如下:

#include <stdio.h>
int main()
{
    puts("C语言中文网");
    return 0;
}

第 1~3 行、第 5~6 行是固定的,所有C语言源代码都必须有这几行。你暂时不需要理解它们是什么意思,反正有这个就是了,以后会慢慢讲解。

但是请记住,今后我们写的所有类似 puts 这样的语句,都必须放在{ }之间才有效。

上面的代码,看起来枯燥无趣,不好区分各个语句,我们不妨来给它们加上颜色和行号,如下所示:

 
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     puts("C语言中文网");
  5.     return 0;
  6. }
颜色和行号是笔者自己加上去的,主要是为了让大家阅读方便,明显地区分各个语句,C语言本身没有对这些作要求,你可以随意设置各个字符的颜色,也可以没有颜色。

这就是我们的第一个C语言程序,它非常简单,带领我们进入了C语言的大门。

编程时请选择正确的输入法,严格区分中英文


图:搜狗输入法半角和全角


我们知道,在编程时要使用英文半角输入法。为了加强练习,出个选择题,请大家判断下面哪一种描述是正确的:
A) 编程的时候不用在意中英文符号的区别。
B) 在源代码的任何地方都不能出现中文汉字、字符等。
C) 感叹号没有中文和英文的区别。
D) 编程时,使用的英文引号,也有左引号和右引号的区别。
E) 中文和英文模式下的制表符(键盘tab键)输入效果一致。

答案:E 选项正确。

什么是源文件?

在开发软件的过程中,我们需要将编写好的代码(Code)保存到一个文件中,这样代码才不会丢失,才能够被编译器找到,才能最终变成可执行文件。这种用来保存代码的文件就叫做源文件(Source File)。

我们将在《 编译和链接》一节中讲解编译器的概念。

每种编程语言的源文件都有特定的后缀,以方便被编译器识别,被程序员理解。源文件后缀大都根据编程语言本身的名字来命名,例如:

  • C语言源文件的后缀是.c
  • C++语言(C Plus Plus)源文件的后缀是.cpp
  • Java 源文件的后缀是.java
  • Python 源文件的后缀是.py
  • JavaScript 源文件后置是.js


源文件其实就是纯文本文件,它的内部并没有特殊格式,能证明这一结论的典型例子是:在 Windows 下用记事本程序新建一个文本文档,并命名为demo.txt,输入一段C语言代码并保存,然后将该文件强制重命名为demo.c(后缀从.txt变成了.c),发现编译器依然能够正确识别其中的C语言代码,并顺利生成可执行文件。

源文件的后缀仅仅是为了表明该文件中保存的是某种语言的代码(例如.c文件中保存的是C语言代码),这样程序员更加容易区分,编译器也更加容易识别,它并不会导致该文件的内部格式发生改变。

C++ 是站在C语言的肩膀上发展起来的,是在C语言的基础上进行的扩展,C++ 包含了C语言的全部内容(请猛击《C语言和C++到底有什么关系》一文了解更多),将C语言代码放在.cpp文件中不会有错,很多初学者都是这么做的,很多大学老师也是这么教的。但是,我还是强烈建议将C语言代码放在.c文件中,这样能够更加严格地遵循C语言的语法,也能够更加清晰地了解C语言和C++的区别。

C语言编译和链接详解(通俗易懂,深入本质)

件组合起来。

再次强调,编译是针对一个源文件的,有多少个源文件就需要编译多少次,就会生成多少个目标文件。

总结

不管我们编写的代码有多么简单,都必须经过「编译 --> 链接」的过程才能生成可执行文件:

  • 编译就是将我们编写的源代码“翻译”成计算机可以识别的二进制格式,它们以目标文件的形式存在;
  • 链接就是一个“打包”的过程,它将所有的目标文件以及系统组件组合成一个可执行文件。


如果不是特别强调,一般情况下我们所说的“编译器”实际上也包括了链接器,比如,你使用了哪种编译器?去哪里下载C语言编译器?我的编译器为什么报错了呢?

C语言编译器(C语言编程软件)完全攻略(包含所有平台)

嵌入式系统

而在嵌入式系统方面,可用的C语言编译器就非常丰富了,比如:

  • 用于 Keil 公司 51 系列单片机的 Keil C51 编译器;
  • 当前大红大紫的 Arduino 板搭载的开发套件,可用针对 AVR 微控制器的 AVR GCC 编译器;
  • ARM 自己出的 ADS(ARM Development Suite)、RVDS(RealView Development Suite)和当前最新的 DS-5 Studio;
  • DSP 设计商 TI(Texas Instruments)的 CCS(Code Composer Studio);
  • DSP 设计商 ADI(Analog Devices,Inc.)的 Visual DSP++ 编译器,等等。


通常,用于嵌入式系统开发的编译工具链都没有免费版本,而且一般需要通过国内代理进行购买。所以,这对于个人开发者或者嵌入式系统爱好者而言是一道不低的门槛。

不过 Arduino 的开发套件是可免费下载使用的,并且用它做开发板连接调试也十分简单。Arduino 所采用的C编译器是基于 GCC 的。

还有像树莓派(Raspberry Pi)这种迷你电脑可以直接使用 GCC 和 Clang 编译器。此外,还有像 nVidia 公司推出的 Jetson TK 系列开发板也可直接使用 GCC 和 Clang 编译器。树莓派与 Jetson TK 都默认安装了 Linux 操作系统。

在嵌入式领域,一般比较低端的单片机,比如 8 位的 MCU 所对应的C编译器可能只支持 C90 标准,有些甚至连 C90 标准的很多特性都不支持。因为它们一方面内存小,ROM 的容量也小;另一方面,本身处理器机能就十分有限,有些甚至无法支持函数指针,因为处理器本身不包含通过寄存器做间接过程调用的指令。

而像 32 位处理器或 DSP,一般都至少能支持 C99 标准,它们本身的性能也十分强大。而像 ARM 出的 RVDS 编译器甚至可用 GNU 语法扩展。

下图展示了上述C语言编译器的分类。

 什么是IDE(集成开发环境)?

实际开发中,除了编译器是必须的工具,我们往往还需要很多其他辅助软件,例如:

  • 编辑器:用来编写代码,并且给代码着色,以方便阅读;
  • 代码提示器:输入部分代码,即可提示全部代码,加速代码的编写过程;
  • 调试器:观察程序的每一个运行步骤,发现程序的逻辑错误;
  • 项目管理工具:对程序涉及到的所有资源进行管理,包括源文件、图片、视频、第三方库等;
  • 漂亮的界面:各种按钮、面板、菜单、窗口等控件整齐排布,操作更方便。


这些工具通常被打包在一起,统一发布和安装,例如 Visual Studio、Dev C++、Xcode、Visual C++ 6.0、C-Free、Code::Blocks 等,它们统称为集成开发环境(IDE,Integrated Development Environment)。

集成开发环境就是一系列开发工具的组合套装。这就好比台式机,一个台式机的核心部件是主机,有了主机就能独立工作了,但是我们在购买台式机时,往往还要附带上显示器、键盘、鼠标、U盘、摄像头等外围设备,因为只有主机太不方便了,必须有外设才能玩的爽。

集成开发环境也是这个道理,只有编译器不方便,所以还要增加其他的辅助工具。在实际开发中,我一般也是使用集成开发环境,而不是单独地使用编译器。

通俗的称呼

有时候为了称呼方便,或者初学者没有严格区分概念,也会将C语言集成开发环境称作“C语言编译器”或者“C语言编程软件”。这里大家不要认为是一种错误,就把它当做“乡间俗语”吧。

什么是工程/项目?

一个真正的程序(也可以说软件)往往包含多项功能,每一项功能都需要几十行甚至几千行、几万行的代码来实现,如果我们将这些代码都放到一个源文件中,那将会让人崩溃,不但源文件打开速度极慢,代码的编写和维护也将变得非常困难。

在实际开发中,程序员都是将这些代码分门别类地放到多个源文件中。除了这些成千上万行的代码,一个程序往往还要包含图片、视频、音频、控件、库(也可以说框架)等其它资源,它们也都是一个一个地文件。

为了有效地管理这些种类繁杂、数目众多的文件,我们有理由把它们都放到一个目录(文件夹)下,并且这个目录下只存放与当前程序有关的资源。实际上 IDE 也是这么做的,它会为每一个程序都创建一个专门的目录,将用到的所有文件都集中到这个目录下,并对它们进行便捷的管理,比如重命名、删除文件、编辑文件等。

这个为当前程序配备的专用文件夹,在 IDE 中也有一个专门的称呼,叫做“Project”,翻译过来就是“工程”或者“项目”。在 Visual C++ 6.0 下,这叫做一个“工程”,而在 Visual Studio 下,这又叫做一个“项目”,它们只是单词“Project”的不同翻译而已,实际上是一个概念。

工程类型/项目类型

“程序”是一个比较宽泛的称呼,它可以细分为很多种类,例如:

  • 有的程序不带界面,完全是“黑屏”的,只能输入一些字符或者命令,称为控制台程序(Console Application),例如 Windows 下的 cmd.exe,Linux 或 Mac OS 下的终端(Terminal)。
  • 有的程序带界面,看起来很漂亮,能够使用鼠标点击,称为GUI程序(Graphical User Interface Program),例如 QQ、迅雷、Chrome 等。
  • 有的程序不单独出现,而是作为其它程序的一个组成部分,普通用户很难接触到它们,例如静态库、动态库等。


不同的程序对应不同的工程类型(项目类型),使用 IDE 时必须选择正确的工程类型才能创建出我们想要的程序。换句话说,IDE 包含了多种工程类型,不同的工程类型会创建出不同的程序。

不同的工程类型本质上是对 IDE 中各个参数的不同设置;我们也可以创建一个空白的工程类型,然后自己去设置各种参数(不过一般不这样做)。

控制台程序对应的工程类型为“Win32控制台程序(Win32 Console Application)”,GUI 程序对应的工程类型为“Win32程序(Win32 Application)”。

控制台程序是 DOS 时代的产物了,它没有复杂的功能,没有漂亮的界面,只能看到一些文字,虽然枯燥无趣,也不实用,但是它非常简单,不受界面的干扰,所以适合入门,我强烈建议初学者从控制台程序学起。等大家对编程掌握的比较熟练了,能编写上百行的代码了,再慢慢过渡到 GUI 程序。

哪款C语言编译器(IDE)适合初学者?

Code::Blocks 是一款开源、跨平台、免费的 C/C++ IDE,它和 Dev C++ 非常类似,小巧灵活,易于安装和卸载,不过它的界面要比 Dev C++ 复杂一些,不如 Dev C++ 来得清爽。

5) Turbo C

Turbo C 是一款古老的、DOS 年代的C语言开发工具,程序员只能使用键盘来操作 Turbo C,不能使用鼠标,所以非常不方便。但是 Turbo C 集成了一套图形库,可以在控制台程序中画图,看起来非常炫酷,所以至今仍然有人在使用。

6) C-Free

C-Free 是一款国产的 Windows 下的C/C++ IDE,最新版本是 5.0,整个软件才 14M,非常轻巧,安装也简单,界面也比 Dev C++ 漂亮。C-Free 的缺点也是调试功能弱。可惜的是,C-Free 已经多年不更新了,组件都老了,只能在 XP、Win7 下运行,在 Win8、Win10 下可能会存在兼容性问题。

下面我们给出了各种 IDE(含不同版本)的下载地址、安装方法以及使用教程,并以红色字体附带了建议。

  • VS2022 [力荐]
    • ​S2022下载地址和安装教程(图解)
    • 使用VS2022编写C语言程序
  • VS2019 [荐]
    • ​S2019下载地址和安装教程(图解)
    • 使用VS2019编写C语言程序
  • VS2017
    • VS2017下载地址和安装教程(图解)
    • 使用VS2017编写C语言程序
  • VS2015
    • VS2015下载地址和安装教程(图解)
    • 使用VS2015编写C语言程序
  • Dev C++ [荐]
    • Dev C++下载地址和安装教程(图解)
    • 使用Dev C++编写C语言程序
  • VC6.0 [不建议]
    • VC6.0(VC++6.0)下载地址和安装教程(图解)
    • 使用VC6.0(VC++6.0)编写C语言程序
  • Code::Blocks
    • Code::Blocks下载地址和安装教程(图解)
    • Code::Blocks汉化教程(附带汉化包)
    • 使用Code::Blocks编写C语言程序
  • Turbo C [不建议]
    • Turbo C 2.0下载地址和安装教程(图解)
    • 使用Turbo C 2.0编写C语言程序
  • C-Free [不建议]
    • C-Free 5.0下载地址和激活教程(图解)
    • 使用C-Free编写C语言程序

Linux 下如何选择 IDE?

Linux 下可以不使用 IDE,只使用 GCC 编译器和一个文本编辑器(例如 Gedit)即可,这样对初学者理解C语言程序的生成过程非常有帮助,请参考:Linux GCC简明教程(使用GCC编写C语言程序)

当然,如果你希望使用 IDE,那么可以选择 CodeLite、Code::Blocks、Anjuta、Eclipse、NetBeans 等。

Mac OS 下如何选择 IDE?

Mac OS 下推荐使用 Apple 官方开发的 Xcode,在 APP Store 即可下载,具体请参见:Xcode简明教程(使用Xcode编写C语言程序)

另外,Visual Studio 也推出了 Mac 版本,已经习惯了 Visual Studio 的用户可以高兴一把了。

C语言程序的错误和警告


 


图7:C-Free 5.0 的错误提示


可以看出,C-Free 的错误提示信息比较少,不方便程序员纠错。VC 和 VS 的错误信息类似,只是中英文的差别。

下图分析了 VC 6.0 的错误信息:


图8:错误信息说明


翻译:源文件 E:\cDemo\hello.c 第5行发生了语法错误,错误代码是 C2143,原因是 'return' 前面丢失了 ';'。

我敢保证,你写的代码肯定会发生错误,一定要有分析错误的能力,这是一个合格的程序员必备的技能。

分析第一个C语言程序

    前面我们给出了一段最简单的C语言代码,并演示了如何在不同的平台下进行编译,这节我们来分析一下这段代码,让读者有个整体的认识。代码如下:
 
  1. #include <stdio.h>
  2. int main()
  3. {
  4. puts("C语言中文网");
  5. return 0;
  6. }

函数的概念

关于库的概念,我们已在《 不要这样学习C语言,这是一个坑》中进行了详细介绍。

除了库函数,我们还可以编写自己的函数,拓展程序的功能。自己编写的函数称为自定义函数。自定义函数和库函数在编写和使用方式上完全相同,只是由不同的机构来编写。

示例中第2~6行代码就是我们自己编写的一个函数。main 是函数的名字,( ) 表明这是函数定义,{ } 之间的代码是函数要实现的功能。

函数可以接收待处理的数据,同样可以将处理结果告诉我们;使用return可以告知处理结果。示例中第5行代码表明,main 函数的处理结果是整数 0。return 可以翻译为“返回”,所以函数的处理结果被称为返回值(Return Value)。

第2行代码中,int 是 integer 的简写,意为“整数”。它告诉我们,函数的返回值是整数。

需要注意的是,示例中的自定义函数必须命名为 main。C语言规定,一个程序必须有且只有一个 main 函数。main 被称为主函数,是程序的入口函数,程序运行时从 main 函数开始,直到 main 函数结束(遇到 return 或者执行到函数末尾时,函数才结束)。

也就是说,没有 main 函数程序将不知道从哪里开始执行,运行时会报错。

综上所述:第2~6行代码定义了主函数 main,它的返回值是整数 0,程序将从这里开始执行。main 函数的返回值在程序运行结束时由系统接收。

关于自定义函数的更多内容,我们将在《 C语言函数》一章中详细讲解,这里不再展开讨论。

有的教材中将 main 函数写作:

void main()
{
    // Some Code...
}

这在 VC6.0 下能够通过编译,但在 C-Free、GCC 中却会报错,因为这不是标准的 main 函数的写法,大家不要被误导,最好按照示例中的格式来写。

头文件的概念

还有最后一个问题,示例中第1行的#include <stdio.h>是什么意思呢?

C语言开发者们编写了很多常用函数,并分门别类的放在了不同的文件,这些文件就称为头文件(header file)。每个头文件中都包含了若干个功能类似的函数,调用某个函数时,要引入对应的头文件,否则编译器找不到函数。

实际上,头文件往往只包含函数的说明,也就是告诉我们函数怎么用,而函数本身保存在其他文件中,在链接时才会找到。对于初学者,可以暂时理解为头文件中包含了若干函数。

引入头文件使用#include命令,并将文件名放在< >中,#include 和 < > 之间可以有空格,也可以没有。

头文件以.h为后缀,而C语言代码文件以.c为后缀,它们都是文本文件,没有本质上的区别,#include 命令的作用也仅仅是将头文件中的文本复制到当前文件,然后和当前文件一起编译。你可以尝试将头文件中的内容复制到当前文件,那样也可以不引入头文件。

.h中代码的语法规则和.c中是一样的,你也可以#include <xxx.c>,这是完全正确的。不过实际开发中没有人会这样做,这样看起来非常不专业,也不规范。

较早的C语言标准库包含了15个头文件,stdio.h 和 stdlib.h 是最常用的两个:

  • stdio 是 standard input output 的缩写,stdio.h 被称为“标准输入输出文件”,包含的函数大都和输入输出有关,puts() 就是其中之一。
  • stdlib 是 standard library 的缩写,stdlib.h 被称为“标准库文件”,包含的函数比较杂乱,多是一些通用工具型函数,system() 就是其中之一。

最后的总结

初学编程,有很多基本概念需要了解,本节就涉及到很多,建议大家把上面的内容多读几遍,必将有所收获。

本节开头的示例是一个C语言程序的基本结构,我们不妨整理一下思路,从整体上再分析一遍:
1) 第1行引入头文件 stdio.h,这是编程中最常用的一个头文件。头文件不是必须要引入的,我们用到了 puts 函数,所以才引入 stdio.h。例如下面的代码完全正确:

 
  1. int main()
  2. {
  3. return 0;
  4. }

我们没有调用任何函数,所以不必引入头文件。

2) 第2行开始定义主函数 main。main 是程序的入口函数,一个C程序必须有 main 函数,而且只能有一个。

3) 第4行调用 puts 函数向显示器输出字符串。

4) 第5行是 main 函数的返回值。程序运行正确一般返回 0。

C语言代码中的空白符

空格、制表符、换行符等统称为空白符(space character),它们只用来占位,并没有实际的内容,也显示不出具体的字符。

制表符分为水平制表符和垂直制表符,它们的 ASCII 编码值分别是 9 和 11。
  • 垂直制表符在现代计算机中基本不再使用了,也没法在键盘上直接输入,它已经被换行符取代了。
  • 水平制表符相当于四个空格,对于大部分编辑器,按下 Tab 键默认就是输入一个水平制表符;如果你进行了个性化设置,按下 Tab 键也可能会输入四个或者两个空格。

对于编译器,有的空白符会被忽略,有的却不能。请看下面几种 puts 的写法:

#include<stdio.h>
int main()
{
    puts("C语言");
    puts("中文网");
   
    puts
    ("C语言中文网");
   
    puts
    (
    "C语言中文网"
    )
    ;
   
    puts   ("C语言中文网");

    puts    (    "C语言中文网"    )    ;

    return 0;
}

运行结果:
 



看到输出结果,说明代码没有错误,以上几种 puts 的用法是正确的。puts()之间、" "()之间可以有任意的空白符,它们会被编译器忽略,编译器不认为它们是代码的一部分,它们的存在只是在编辑器中呈现一定的格式,让程序员阅读方便。

需要注意的是,由" "包围起来的字符串中的空白符不会被忽略,它们会被原样输出到控制台上;并且字符串中间不能换行,否则会产生编译错误。请看下面的代码:

#include<stdio.h>
int main()
{
    puts("C语  言 中文网");
    puts("C语言
    中文网");
    return 0;
}

第 5~6 行代码是错误的,字符串必须在一行内结束,不能换行。把这两行代码删除,运行结果为:


 



程序员要善于利用空白符:缩进(制表符)和换行可以让代码结构更加清晰,空格可以让代码看起来不那么拥挤。专业的程序员同样追求专业的代码格式,大家在以后的学习中可以慢慢体会

本文标签: 语言第二章入门教程教程详细