【零基础学习iOS开发】【02-C语言】02-第一个C语言程序

回到顶部

前言

前面已经唠叨了这么多理论知识,从这讲开始,就要通过接触代码来学习C语言的语法。学习任何一门语言,首先要掌握的肯定是语法。学习C语言语法的目的:就是能够利用C语言编写程序,然后运行程序跟硬件(计算机、手机等硬件设备)进行交互。由于我们的最终目的是学习iOS开发,学习iOS开发的话必须在Mac系统下,因此我就在Mac系统环境下开发C语言程序,而不是在Windows环境下。

 

接下来,就在Mac系统环境下编写第一个C语言程序,最后把程序运行起来,跟计算机做一个小小的互动

回到顶部

一、编写第一个C语言程序-Hello World

为什么称第一个程序为“Hello Wolrd”呢?其实计算机行业里面,学习任何技术的第一个程序都可以称为“Hello World”。“Hello World”的字面意思是“你好,世界”,也就是跟世界打招呼。我们第一个程序在这世界上诞生了,那肯定要跟世界打声招呼嘛,所以就称为“Hello World”。

1.用什么工具写代码

首先我们要做的肯定是写代码,在代码里面说清楚想要计算机做出怎样的操作。其实写代码就像平时写文章一样,只是在电脑上写一些文本内容,那用什么工具来写代码么?平时我们在Windows中写文章,可以用记事本、Word等文本编辑工具。在Mac中呢,我们可以安装一些文本编辑工具来写代码,比如UltraEdit(点击链接可以下载UltraEdit)。当然,在实际开发中,为了提高开发效率,一般会使用开发工具,开发工具的好处,我在前面文章中已经说过了。不过呢,开发工具屏蔽了很多操作细节和语法细节,不利于初学者直观、系统地学习一门语言。因此,在这里,我们暂时使用文本编辑工具UltraEdit来写C语言代码。

 

2.写代码

1> C程序由函数构成

写代码之前,你首先要知道:任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”。所以,你可以说C语言程序是由函数构成的。

比如你用C语言编写了一个MP3播放器程序,那么它的程序结构如下图所示:

  • 从上图可以看出:函数就是用来实现某个功能的程序段,每一个函数都有自己的功能。因此,你应该把实现某个功能所需的代码都写在函数中。比如,有个函数的功能是播放MP3,那么播放MP3的代码都应该写到这个函数中。
  • 当调用(执行)一个函数时,计算机就会按顺序执行函数中的所有代码,从而展示函数所实现的功能。
  • 一般来说,我们会将不同的功能交给不同的函数去实现。比如,将暂停播放MP3的代码写到一个函数中,将停止播放MP3的代码写到另一个函数中。因此,一个C程序中可能会有很多的函数。

 

2> C程序的入口

前面说到:一个C程序中可能会有很多的函数,这样就会有个疑问:当我们运行整个程序时,在众多函数中,计算机会先执行哪个函数呢?也就是说,一个C程序的入口在哪里?我写了几千行的代码,应该先从哪一行代码开始执行啊?是从第一行代码还是从最后一行代码开始执行啊?

其实,C程序的入口是一个名字叫做main的函数,简称main函数。(为了区分函数,每一个函数都有一个名称)也就是说,不管整个程序中有多少个函数,都是先执行main函数。不管main函数写在文件中间,还是文件末尾,也都是先执行main函数。

需要注意的是:

  • 如果一个C程序中没有main函数,那么这个程序就不具备运行的能力。连程序的入口都没有,还运行什么?
  • 一个C程序中只能有一个main函数。想象一下也知道,如果有多个main函数,究竟先执行哪一个main函数呢?这会让计算机无法选择

 

3> 编写main函数

现在已经知道,要想运行一个C程序,必须有一个main函数,接下来就在文本编辑工具中编写一个main函数。main函数的格式大致如下:

  • 第1行的int暂时不用去理解,先认为是main函数的固定写法
  • 第1行的main是函数名称,main后面的一对小括号()是函数的标志,绝对不能缺少!而且这对小括号是“英文括号()”,不是“中文括号()”!
  • 第2行开始,有一对大括号{},函数内部的代码都要写到这对大括号里面。每一个函数都有一对{},{}里面的内容可以称为“函数体”。
  • 在第3行添加了一行return 0;,暂时不用理解它的意思,先认为是main函数的固定写法。
  • 像第3行这种写在函数中的代码可以称为一条“语句”。写完一条语句后,要在尾部加上一个分号“;”,代表语句结束了

 

4> 编写输出语句

接下来在main函数中添加代码。

复制代码
1 #include <stdio.h>
2 
3 int main()  
4 {  
5     printf("Hello World\n");
6     return 0;
7 }
复制代码
  • 在第5行添加了一条语句printf("Hello World\n");,这条语句的作用是让计算机在屏幕上输出用双引号""括住的内容:Hello World,后面的"\n"是一个转义字符,表示回车换行,因此,输出Hello Wrold这一串内容后会自动换行。至于为什么这条语句要这样写?为什么这条语句能让计算机输出东西?这些疑问都先搁着,以后会详细解释。
  • 为了保证第5行代码的正常使用,就在main函数的前面加了一行代码#include <stdio.h>,暂时不用去深刻了解它的意思,默默加上即可,注意,这里是不用加上分号";"的
  • 当运行这个程序,就会先执行main函数,接着就会按顺序执行main函数大括号{}中的所有语句(第5行、第6行语句)
  • 需要注意的是:main函数中所有语句都必须写在第6行return 0;语句的前面,先别问为什么,以后会详细介绍

 

3.保存为C程序的源文件

代码写完了,总得保存起来吧,保存为什么格式的文件呢?每个文件都有自己的拓展名,不同的拓展名就代表着不同类型的文件,比如.mp3代表着音频文件,.txt代表着文本文件。我们前面编写的C语言代码,应该保存为一个拓展名为.c的文件,这个.c文件称为C语言程序的“源代码文件”,也称为“源文件”。

按下快捷键command + s,输入文件名(我这里叫做one.c),选择文件格式

就这样,第一个C语言程序就写完了,非常简单吧,一点压力都没有

 

回到顶部

二、编译程序

前面已经把程序写好了,迫不及待想做的事情肯定是运行程序,看看计算机会有什么反应。遗憾的是,前面编写好的one.c文件还不能够运行。上一篇文章已经说过了,计算机只能识别0和1组成的机器指令,你现在写的这些什么int、main这些英文,它是看不懂的。我们需要使用C语言编译器,将源文件翻译成只有0和1的二进制文件,这个翻译过程,我们称之为“编译”。

Mac系统上支持一款叫做gcc的编译器,gcc支持多种编程语言:C语言、C++、Objective-C、Java等。在后来,苹果公司自己开发了一款叫做clang的编译器,目标就是要超越gcc。我们这里就采用clang编译器来编译程序。要想在Mac中使用clang编译器,首先要安装一个命令行工具(Command Line Tools)

1.下载安装命令行工具

安装命令行工具的方式有2种。

1> 方式一:直接到苹果官网下载

先点击屏幕左上角的“苹果图标”,查看你的Mac系统版本

  

  • 如果你的Mac是Lion系统(版本<=10.7),请选择下载:
  • 如果你的Mac是Mountain Lion系统(版本>=10.8),请选择下载:

2> 方式二:先到苹果官网下载安装Xcode,然后打开Xcode,在Xcode中安装命令行工具

 

2.打开终端

安装完命令行工具后,就可以使用clang编译器了。那怎么使用clang呢?通过在“终端”中输入相应的clang指令来启动编译器。

默认情况下,终端所指向的路径是用户的个人主文件夹,我的主文件夹是/Users/apple,我的用户名叫apple

 

3.跳转到one.c所在的路径

为了方便操作,我们应该将终端的路径切换到one.c所在的路径,one.c存放在我的桌面,文件夹路径是/Users/apple/Desktop

输入指令:cd /Users/apple/Desktop , 然后敲回车,指令"cd"是改变路径的意思。

 

4.输入编译指令,编译one.c文件

输入指令:cc -c one.c , 然后敲回车

指令"cc -c"表示编译某个源文件,后面跟上源文件的名称或者全路径。

如果敲完编译指令后,没有显示太多的信息,说明你编译成功了。编译成功后,会在终端所在的路径下生成一个二进制文件,称为“目标文件”,拓展名为".o",文件名与源文件一致。one.c文件编译成功后就生成了one.o文件。

补充:在开发过程中,不可能将所有的代码都写在一个.c文件中,为了模块化开发,一般会将不同的功能写到不同的源文件中。如果要同时编译多个源文件,这样写:cc -c one.c two.c three.c。源文件编译之后,每个源文件都会生成对应的.o文件,比如two.c生成了two.o、three.c生成了three.o

 

5.编译器的语法检测

编译器除了能将.c源文件编译成.o目标文件之外,还有一个非常重要的功能:语法检测。跟英语一样,C语言也有自己的语法,如果你不按照C语言语法去写代码,那就无法编译成功。生成目标文件之前,编译器会先检查.c文件是否有语法错误,如果出现语法错误,会列出错误的总个数、错误原因和错误代码的行号,这时候就不会产生目标文件;必须修正相应的语法错误,重新编译成功后,才会生成目标文件。

接下来我把代码故意写错,第3行把int写成了intt,第5行语句少了一个分号";"

复制代码
1 #include <stdio.h>
2 
3 intt main()
4 {  
5     printf("Hello World\n")
6     return 0;
7 }
复制代码

重新保存源文件,在终端中重新编译一下

它说得非常明显:有2个错误,第1个错误是在one.c的第3行,第2个错误是在one.c的第5行。这些错误信息(error)是一定要修改的,只要有一个错误信息存在,就不可能编译成功。以后还有可能会遇到一些“警告信息(warning)”,警告信息可以忽略,不影响编译。

 

回到顶部

三、链接程序

1.什么是链接

源文件编译成功后,会生成一个.o目标文件,这就是一个二进制文件,但是,还是不能运行。目标文件不能运行的主要原因有2个:

1> 在开发过程中,不可能将所有的代码都写在一个.c文件中,为了模块化开发,一般会将不同的功能写到不同的源文件中。源文件编译之后,每个源文件都有对应的.o文件,比如two.c生成了two.o、three.c生成了three.o,这些.o文件都不能单独运行,它们之间都有密不可分的关系,需要将所有相关联的.o目标文件组合在一起。

2> 除开组合所有的目标文件之后,还需要将C语言的函数库包含进来,才能生成可执行文件。

将所有相关联的.o目标文件、以及C语言函数库组合在一起生成可执行文件的过程,我们称为“链接”。

 

2.链接目标文件

在终端中输入指令:cc one.o , 然后敲回车。如果要同时链接多个目标文件,这样写:cc one.o two.o three.o

链接成功后,会生成一个可执行文件,默认的名称叫做“a.out”。由于我们是在mac系统下生成了可执行文件,mac系统是基于UNIX系统的,所以这个文件只能在UNIX系统中运行。如果是在Windows环境下,生成的可执行文件拓展名为".exe"。

  

 

3.更改可执行文件的名称

如果想更改可执行文件的名称,可以输入指令:cc -o one one.o,-o后面跟上可执行文件的名称,因此可执行文件的名称就变成了one

 

4.连续执行编译、链接

其实也可以在终端中直接输入:cc one.c , 会按顺序执行编译、链接两个操作。

这条命令产生一个名为"a.out"的可执行程序。中间会产生一个名为one.o的目标文件,但它在链接完成后会被删除。

如果想修改可执行文件的名称,跟前面是一样的,指令为:cc -o abc one.c , 可执行文件的名称为abc

 

回到顶部

四、运行程序

经过前面几个步骤后,终于生成了可执行文件,接下来就可以运行这个程序了。运行程序有2种方式:

1.在终端中输入指令运行程序

在终端中输入:./a.out,敲回车就可以运行这个程序。这里a.out是可执行文件的名称。

敲完指令后,你会发现屏幕上输出了一句“Hello World”。就这样,我们成功跟计算机来了一点小小的互动,它替我们输出了一句文字。

 

2.双击可执行文件

直接双击a.out文件,选择用终端来运行程序

运行成功后

 

回到顶部

五、总结

经过一番折腾,终于将第一个C程序运行成功了,总共有4个步骤:编写程序 -> 编译 -> 链接 -> 运行

需要注意的是:

  • 中间某个环节出错了,那么就不会有后面的操作。比如编译出错了,那么就不可能有链接这个环节。
  • 如果你对源代码进行了修改,那么需要重新编译、链接之后再运行程序,这样才能看到最新的效果。

 

回到顶部

六、学习建议

1.学编程并不是学英文

写完这个Hello World程序后,可能很多人会去查单词,看看int什么意思、看看那stdio、return又是什么意思。其实,这是非常没必要的做法,我们学的是编程,并不是学英文,没有必要一个一个词语地去扣。再说,这些词语对计算机来说并不是什么英文单词,仅仅是个符号、是代码!!!计算机只能识别0和1,因此还要将这些代码编译成0和1之后才能被计算机所执行。计算机并不是有道词典,它不可能认识什么英文单词。很多代码都是固定写法,并没有太多的所谓英文含义。

 

2.程序的可读性

这个Hello World程序的功能很少,只有一丁点内容,我们就占用了好几行行代码。有人可能会问:这些代码一定要换行么?第5行prinf语句的前面一定要要缩进几个空格么?

其实,你完全可以不缩进

复制代码
1 #include <stdio.h>
2 
3 int main()  
4 {  
5 printf("Hello World\n");
6 return 0;
7 }
复制代码

也可以将所有的代码都写成一行(第1行代码比较特殊,必须独立一行)

1 #include <stdio.h>
2 int main()  {printf("Hello World\n");return 0;}

这样写虽然没有问题,但是代码可读性非常地差,想象一下也知道:整个文件中就一行代码,如果这个程序很大的话,肯定很多代码,这样的代码是有多恶心啊!别人 可能根本看不太懂你写的是什么东西,甚至你自己都看不太懂。在工作中,我们难免会遇到难题,经常要求助于他人,但是别人要在看得懂我们代码的基础上,才能 帮我们解决问题啊。因此,代码的可读性很重要!一定要养成良好的编程习惯。

 

3.初学者不要过于寻根问底

当你对一门新技术还不是很了解的时候,你首先要做的事情是学会怎么使用它,先把它成功用起来,并不是从头到尾看清楚所有的源代码、把每一行代码中的每个词语都摸清楚什么意思,完全没有这个必要。等你有一定的技术基础了,这门技术用得很熟了,而且时间和能力允许的话,才有必要去寻根问底地解读所有的源代码。所以,第一个C程序的代码中很多不懂的地方,暂时不用去纠结,学到后面了,你就会不自觉地就知道它们是什么意思了。

 

回到顶部

七、clang指令汇总

这些指令不用去死记,大致有个了解,用到时再来查资料即可

1.编译单个c源文件,并产生一个目标文件

cc -c one.c
这条命令产生一个名为one.o的目标文件

 

2.编译多个c源文件,并为每个文件产生一个目标文件

cc -c one.c two.c three.c
这条命令产生3个目标文件:one.o、two.o、three.o

 

3.链接单个目标文件

cc one.o
这条命令产生一个名为a.out的可执行文件

 

4.链接多个目标文件

cc one.o two.o three.o
这条命令产生一个名为a.out的可执行文件

 

5.编译并链接一个c源文件

cc one.c
这条命令产生一个名为a.out的可执行文件。中间会产生一个名为one.o的目标文件,但它在链接过程完成后会被删除。

 

6.编译并链接多个c源文件

cc one.c two.c three.c
这条命令产生一个名为a.out的可执行文件。当编译的源文件超过一个时,目标文件便不会被删除。这就允许你对程序进行修改后,只对那些进行过改动的源文件进行重新编译。

 

7.编译一个c源文件,并把它和现存的目标文件链接在一起

cc one.o two.o three.c
这条命令产生一个名为a.out的可执行文件

 

8.上面那些可以产生可执行文件的指令均可以加上“-o name”这个选项,产生的可执行文件就叫做name

比如 cc -o abc one.c
这条指令会产生一个名为abc的可执行文件

 

9.执行可执行文件

./a.out
这条指令可以执行一个名为a.out的可执行文件

转载于:https://www.cnblogs.com/fgcs/p/4744534.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544333.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安卓平板体验Java开发,还能白嫖一年阿里无影云,真香!(内含白嫖方法,人人可领)...

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;阿里无影云早有耳闻&#xff0c;前两天看朋友发体验照片&#xff0c;可能是程序员天生爱折腾的特性又发挥作用了&#xff0c…

Linux命令(三)

echo&#xff1a;输出信息echo ”abc”echo “字符串” |passwd --stdin USERNAME :利用管道修改用户密码输出重定向&#xff1a;>覆盖输出&#xff08;会覆盖原文件中的内容&#xff09;>>追加输出 &#xff08;原有内容会被保留&#xff09;Set –c &#xff1a…

strictmath_Java StrictMath scalb()方法与示例

strictmathStrictMath类scalb()方法 (StrictMath Class scalb() method) Syntax: 句法&#xff1a; public static double scalb(double do , int sf);public static float scalb(float fl , int sf);scalb(double do , int sf) method is used to return do* 2 raised to the…

你知道group by的工作原理和优化思路吗?

前言 日常开发中&#xff0c;我们经常会使用到group by。亲爱的小伙伴&#xff0c;你是否知道group by的工作原理呢&#xff1f;group by和having有什么区别呢&#xff1f;group by的优化思路是怎样的呢&#xff1f;使用group by有哪些需要注意的问题呢&#xff1f;本文将跟大家…

strictmath_Java StrictMath hypot()方法与示例

strictmathStrictMath类hypot()方法 (StrictMath Class hypot() method) hypot() method is available in java.lang package. hypot()方法在java.lang包中可用。 hypot() method is used to return the square root of sqrt(sq(d1)sq(d2)) without any intermediate operation…

关Jquery判断input type=checkbox元素是否被选中的判断

2019独角兽企业重金招聘Python工程师标准>>> 在用到复选框的时候&#xff0c;想在js中判断chekbox是否被选中 <input name"isPermit" id"isPermit" type"checkbox"> 百度了很多的判断方法 1、 if($("#isPermit").att…

Redis夺命十二问,你能扛到第几问?

Redis是面试中绕不过的槛&#xff0c;只要在简历中写了用过Redis&#xff0c;肯定逃不过。今天我们就来模拟一下面试官在Redis这个话题上是如何一步一步深入&#xff0c;全面考察候选人对于Redis的掌握情况。小张&#xff1a;面试官&#xff0c;你好。我是来参加面试的。面试官…

Java Scanner nextLine()方法与示例

扫描仪类nextLine()方法 (Scanner Class nextLine() method) nextLine() method is available in java.util package. nextLine()方法在java.util包中可用。 nextLine() method is used to get the skipped line. nextLine()方法用于获取跳过的行。 nextLine() method is a non…

bzoj 1192

http://www.lydsy.com/JudgeOnline/problem.php?id1192 好像学过一个东西&#xff1a; [0..2^(N1)-1]内的数都的都可以由2^0,2^1,...,2^N这N1个数中若干个相加得到。 #include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #incl…

Spring Boot Admin 报警提醒和登录验证功能实现!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;Spring Boot Admin&#xff08;SBA&#xff09;是一个开源的社区项目&#xff0c;用于管理和监控 Spring Boot 应用程序&…

Java Hashtable rehash()方法与示例

哈希表类rehash()方法 (Hashtable Class rehash() method) rehash() method is available in java.util package. rehash()方法在java.util包中可用。 rehash() method is used to extend the capacity and it is invoked implicitly if the number of keys limit exceeds hash…

企业Shell面试题18:单词及字母去重排序案例

1、按单词出现频率降序排序&#xff01; 2、按字母出现频率降序排序&#xff01; the squid project provides a number of resources to assist users design,implement and support squid installations. Please browse the documentation and support sections for more inf…

5种高大上的yml读取方式,你知道几种?

我们今天就来点实战&#xff0c;总结一下除了烂大街的Value和ConfigurationProperties外&#xff0c;还有哪些读取yml配置文件的方法&#xff1f;1、Environment在Spring中有一个类Environment&#xff0c;它可以被认为是当前应用程序正在运行的环境&#xff0c;它继承了Proper…

Java Hashtable equals()方法与示例

哈希表类equals()方法 (Hashtable Class equals() method) equals() method is available in java.util package. equals()方法在java.util包中可用。 equals() method is used to check whether equality of this Hashtable with the given Object or not. equals()方法用于检…

为什么ConcurrentHashMap不允许插入null值?

作者&#xff1a;磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;在 Java 语言中&#xff0c;ConcurrentHashMap 和 Hashtable 这些线程安全的集合是不允许 key 或 value 插…

.NET APlayer播放器 demo

工作需要,想开发一款播放器,当无意间浏览到APlayer的时候大爱啊,有木有迅速投入精力,在APlayer论坛看大牛们的作品及经验,看SDK中提供的chm电子书最后看了博客园中周见智的文章(灰常好!最终作品也用的他的demo改进)先来晒一下最终的效果图片。 效果截图&#xff1a;1.初始界面。…

Java Formatter format()方法及示例

Formatter类format()方法 (Formatter Class format() method) Syntax: 句法&#xff1a; public Formatter format(Locale lo, String frmt, Object... args);public Formatter format(String frmt, Object... args);format() method is available in java.util package. form…

Spring Cloud Alibaba Nacos 服务注册与发现功能实现!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;Nacos 是 Spring Cloud Alibaba 中一个重要的组成部分&#xff0c;它提供了两个重要的功能&#xff1a;服务注册与发现和统一…

Java类class cast()方法及示例

类class cast()方法 (Class class cast() method) cast() method is available in java.lang package. 在java.lang包中提供了cast()方法 。 cast() method casts this Object to the class or an interface denoted by this Class object. cast()方法将此Object强制转换为该Cl…

加分进了字节,MySQL真yyds!

Java研发工程师必备技能非MySQL莫属&#xff0c;虽说易学好上手&#xff0c;但应对大厂面试&#xff0c;最容易遭遇滑铁卢、功败垂成的也是它。上手简单&#xff0c;玩转难&#xff0c;才是这款开源数据库叱咤业界多年的真实写照。MySQL 8.0正式版的到来&#xff0c;在性能和速…