当前位置:网站首页>第一个C语言程序(从Hello World开始)
第一个C语言程序(从Hello World开始)
2022-07-25 10:40:00 【鱼找水需要时间】
程序员之间有一个约定俗成的习惯,我们在学习任何编程语言时,所写的第一个程序,就是在显示屏上打印一行字符“Hello World”。
这个习惯出自哪里呢,首先回顾C语言的历史,就可以了解到这个习惯的出处。
1972年,C语言 由Dennis Ritchie及其同事在贝尔实验室创立。而后,C语言的设计者Dennis Ritchie和著名计算机科学家Brian W. Kernighan,联合编著了一本介绍C语言及其程序设计方法的权威性经典著作——《The C Programming Language》。
书中的第一个示例程序,就是在屏幕上输出一串字符“Hello World”。
至今,众多编程语言教材也沿袭了这个习惯。所以,如果你有看过Java,PHP,Go等编程语言的教材,就会发现它们的第一个示例程序也是“Hello World”。
可见大家还是非常认可这个习惯,并在自己的著作中延续了这个传统。
尽管没人能够科学地解释为什么 Hello World 如此地流行,但是,Hello World 程序的确在计算机发展历史上成为了一个具有重要意义的里程碑。
环境准备:C语言开发环境安装
示例代码:
#include <stdio.h> int main(){ printf("Hello World"); return 0; }
示例代码的效果:这个程序所实现的效果很简单,就是在屏幕上输出了一行字符"Hello World"。
1. 主函数
首先,主函数 main ,一个标准的主函数如下:
int main() // 这是主函数
{
return 0; // 主函数返回值
}
main在C语言里面表示一个主函数。
双斜杠后面的为 注释 ,一般来说,注释用于标注这段代码的用途或解释思路等。因为注释不会被当作代码进行编译,所以无论添加什么注释内容,都不会对代码的实际运行产生任何影响。
2. 什么是函数?
数学领域中的 函数 ,与编程语言中的 函数 完全不同。
在编程语言里面,你可以把函数看做一个盒子,这个盒子有如下几个特性:
- 开始执行时,函数可以被输入一些值
- 执行过程中,函数可以做一些事情
- 执行完成后,函数可以返回一些值
以上边的示例代码为例进行解释:
- 主函数什么都没有输入 (
main():输入参数为空) - 主函数打印了一行字到屏幕上(
printf("Hello World");) - 主函数返回了0(
return 0;)
其中, int 表明了函数的 返回值类型 为整数类型, int 是 integer(整数) 的缩写。这是由语言标准规定的,不可以写成别的单词。
main 是 函数名 , main 后面的括号 () 内为输入参数,目前为空。return 后跟函数的 返回值 ,为0。而0是一个整数,和函数名前面的 int 对应。
总结函数的写法公式:
函数返回值类型 函数名(函数输入参数值) { 做点什么事情 return 函数返回值; }
被花括号包括的被称为 函数体 ,注意函数体一定要被花括号包括且不可省略。花括号上面的函数名、函数参数及返回值被称作 函数头 。
3. 写一个自己的函数
需求:根据上面的函数写法的公式,写一个两个整数加法的函数。这个函数需要做到:输入两个整数,返回它们相加的结果。
这个既然这个函数是用于计算加法的,我们把函数名取名为 add 。当然自定义函数的函数名可以按照自己的喜好来写,就算写成aaaaa也行。不过,为了函数名拥有语义化,方便人阅读理解,我们一般使用英文来作为函数名。
// 这一段代码被称之为add函数的函数定义
int add(int a, int b) {
return a + b;
}
解释:定义一个返回值为int类型(整型)的函数,函数名为add,输入值为:整数a和整数b,
返回值:返回两个整数的和,两个加数都是整数,所以结果也是一个整数。
这一段代码被称之为add函数的函数定义。
4. 主函数是整个C语言程序的入口
add函数 能直接运行嘛?答案是不行的。
所有的C语言代码都有一个起始入口,而这个入口就是 主函数main 。进入了主函数以后,才能经由主函数来调用其他函数。
这也意味着,每个C语言代码,只能有且只有一个main函数。
稍作修改后的代码:
#include <stdio.h> int add(int a, int b) { return a + b; } int main() { int result; result = add(2, 3); printf("%d", result); return 0; }
当程序运行时,首先会进入 主函数main 。接着调用我们刚刚编写的 add函数 了。我们传了2个值分别是整数2和3给 add函数 。
函数的定义中规定了需要传a、b,2个参数,我们调用的时候,也必须传2个,并且类型也需要尽量一致,否则编译可能会报错。(若类型不同,编译器会尝试自动类型转换。自动类型转换失败则会编译失败。)

问题: 主函数是被谁调用的?主函数的返回值必须是 int 吗?
回答: 主函数在程序开始的时候被自动调用,不需要在程序内主动调用主函数。而主函数的返回值会返回给调用这个程序的程序。
C语言标准中规定主函数有返回值且必须是 int 。如果程序正常结束,一般将返回值设置为0。
5. 要调用函数,必须先知道函数
编译器会从代码开始,按照从上往下的顺序阅读代码。
编译器首先看到了一个函数的定义,描述了一个叫 add 的函数。接着,在 main 中需要使用 add ,由于编译器已经知道了 add 的定义,因此编译器可以正常编译通过。(ps:先定义,后使用)
如果将函数的定义和函数调用顺序反过来会怎样呢?
首先,编译器看到了 add 这个名称,编译器会很疑惑, add 是什么呢?编译器无法理解 add 究竟是什么。因此,编译器将报错,并停止编译。

6. 什么是变量?
在 add函数 计算完毕之后,需要有一个东西来接受 add 返回回来的值。所以,我们在 add 前面声明了一个 int整型 的 变量 。
什么是变量呢?你可以把它看做一个空箱子,里面可以装任何其他的和它类型一致的值。
result 只是我们给它起的一个名字,当然,可以任意起名。比如叫he,叫xiangzi,都可以(ps:起名要有语义性)。
我们把 add返回回来的5,装进了 result 。因此, result 里面装着的值是5了。
= 等号,在C语言中是 赋值运算符,它有把右边的值装进左边变量的功能了。和函数一样,这里的等号和数学里面的等号,也是有很大不同的,它并不是相等的意思。
赋值运算符:将符号右边的值,装进左边的变量的一种运算符。
上边写的示例就是add函数 接受2,3为输入,返回5,被赋值号 = 赋值给 result 的流程。
那能不能这样写呢?去掉 int result; 这一条。
int main() {
result = add(2, 3);
printf("%d", result);
return 0;
}
答案是不行的,变量必须先声明后使用。
编译器看到 result 这个名称,但是从未见过 result 的定义时,肯定也会疑惑它究竟是个什么类型的变量,甚至它有可能不是变量而是一个函数。这样,编译器只能遗憾地给出一个编译错误的提示,并结束编译了。
int result;必须像上面这样,声明有一个变量,名字叫
result,类型是int。接下来,编辑器就能记下result为一个int类型的变量。在后面的代码中,即可愉快地使用这个result变量了。
7.标识符
在前面的代码中,由我们自己命名,用于指代某一个实体的名称,例如:add,result,函数的参数a,b都是一个 标识符 。
标识符由我们自己命名的一个特殊标识,用于表示一个变量、函数或其他实体的名称。
例如:前面我们的自定义函数取名为add是为了清晰地表明函数意图。而将变量命名为result,也是为了表明变量内保存的是函数返回的结果。
并且,要让编译器能够识别标识符,必须进行声明或定义。例如,add被定义成了一个函数,result, a,b被声明成了一个整数类型变量。如果编译器遇到未经定义或声明的标识符,将会无法理解这个标识符具体是一个什么实体的名称而报错。
在C语言中,标识符的可以按照你的喜好自己随意命名,但是必须遵循以下规则:
标识符可以用小写字母、大写字母、数字和下划线来命名。但是,标识符的第一个字符必须是字母或下划线,而不是数字。并且,标识符区分大小写。
8. 关键词
问题:int是一个 标识符 吗?
答案:不是。首先int并不是我们随意命名的,其次int并不是任何实体的名称。
int是C语言中的一个 关键词 。
关键词 是在语言标准中规定的,并且在代码中有特殊意义和用途。因此,关键词不能作为一个标识符来使用。
C语言中的关键词如下表所示。
| auto | _Bool* | break | case |
| char | _Complex* | const | continue |
| default | restrict* | do | double |
| else | enum | extern | float |
| for | goto | if | _Imaginary* |
| inline* | int | long | register |
| return | short | signed | sizeof |
| static | struct | switch | typedef |
| union | unsigned | void | volatile |
| while |
9. 什么是字面常量?
问题:那么,像2,3,这种数值,需不需要声明呢?
回答:不需要,他们是 常量 ,无法被更改。并且一旦被写出来,就已经知道它们是整型int类型的常量了。
同样的, 字符串字面常量 也不需要被声明,例如:"Hello World"。被双引号包裹的,我们认为它是一个字符串,以区别于数值。
变量我们可以通过赋值来更改,常量不能更改,所以不能对它进行赋值。
2 = 3; // 错误
"Hello" = "World"; // 错误
10. printf函数
#include <stdio.h>
int main(){
printf("Hello World");
return 0;
}
和 add 一样, printf 也是一个函数,但是这个并不是一个自定义函数,而是一个系统自带的函数。
我们把字符串字面常量 "Hello World" 传给了 printf函数 。运行代码时,我们在屏幕上看到了这行字
符。显然, printf函数 的作用就是将字符串输出到控制台上了。
printf 由单词 print(打印) 和单词 format(格式) 的首字母f组成,意为 格式化打印。
在早期,计算机的输出主要是靠连接打印机将字符打印在纸张上。而如今,计算机的输出大部分都在屏幕上实现。但是print这个词却被保留了下来。有时候我们会沿用打印这种说法,而实际上,我们是在屏幕上的控制台中输出字符。
printf函数更多用法
int main() {
int result;
result = add(2, 3);
printf("%d", result);
return 0;
}
比较两段代码,我们写 Hello World 时只传了1个参数给 printf ,但为什么在 add函数 后却能传2个给它呢?函数定义的参数个数和类型需要和函数调用时候的保持一致吗?
printf 是一个很特别的函数,它是一个 变参函数 ,所以可以接受可变数量和类型的输入参数。这里我们无需太过关心怎样写一个可变参数函数,暂时只需要使用它即可。
通过如下示例,我们可以简单了解 printf函数 的更多用法。
用于打印一个整数:printf(“%d”, 整型int);
printf("%d", 12345);
用于打印两个整数:printf(“%d\n%d\n”, 整型int1, 整型int2);
// \n表示换行,就是从下一行开始再继续打印 printf("A=%d\nB=%d\n", 123, 456);
总结一下 printf 的公式
printf(“XXX占位1 XXX 占位2 XXX占位3”, 替换1, 替换2, 替换3);
printf 的第一个参数必须是 字符串 ,这里我们传入了一个字符串字面常量(被双引号包裹)。其中,占位用 %转换操作 表示。例如:整型int的占位符为 %d 。后面的替换参数,会依次替换前面的占位。 printf是一个变长参数函数,只要第一个字符串参数占位符写对了,后面可以加任意多的替换参数。

11. #include命令
printf函数 并不是我们定义的函数,而是系统自带的函数。这个函数被写在文件 stdio.h 中,我们要使用 printf 就必须先让编译器理解 printf 。
假定 printf 的函数定义写在文件 stdio.h 中,用 #include 命令,可以将文件 stdio.h 的代码复制到我们的代码中。
ps:stdio.h里面并未定义printf函数,但是它里面有printf函数的函数声明。初学者可以理解为stdio.h里面,写了printf的函数定义。
边栏推荐
- 倍增Floyd「建议收藏」
- Esp32c3 based on the example tutorial of esp32 Rainmaker development under Arduino framework
- 黑客入门教程(非常详细)从零基础入门到精通,看完这一篇就够了。
- 【高并发】通过源码深度分析线程池中Worker线程的执行流程
- Learn NLP with Transformer (Chapter 2)
- SQL injection less17 (error injection + subquery)
- Let sports happen naturally, and fire creates a new lifestyle
- 新能源销冠宏光MINIEV,有着怎样的产品力?
- DICOM medical image viewing and browsing function based on cornerstone.js
- Learn Luzhi PHP -- tp5.0 uses Chinese as an alias and reports "unsupported data expression"
猜你喜欢

What kind of product power does Hongguang miniev, the top seller of new energy, have?

如何判断静态代码质量分析工具的性能?这五大因素必须考虑

Smart cloud IOT platform STM32 esp8266-01s simple wireless light control

MySQL | GROUP_CONCAT函数,将某一列的值用逗号拼接

Learn NLP with Transformer (Chapter 8)

Esp32c3 based on the example tutorial of esp32 Rainmaker development under Arduino framework

NowCoderTOP12-16——持续更新ing

一篇看懂:IDEA 使用scala 编写wordcount程序 并生成jar包 实测

Reptile foundation I

Hcip experiment (01)
随机推荐
MySQL | GROUP_ The concat function concatenates the values of a column with commas
JS 将伪数组转换成数组
web移动端:touchmove实现局部滚动
MLX90640 红外热成像仪测温模块开发笔记(五)
BGP federal experiment
HCIA experiment (08)
[dynamic planning] 70. Climbing stairs
Smart cloud IOT platform STM32 esp8266-01s simple wireless light control
只知道预制体是用来生成物体的?看我如何使用Unity生成UI预制体
常见WEB攻击与防御
Hcip experiment (02)
为什么重写equals()方法必须要重写hashCode()方法
How to judge the performance of static code quality analysis tools? These five factors must be considered
Esp32c3 based on the example tutorial of esp32 Rainmaker development under Arduino framework
NowCoderTOP7-11——持续更新ing
数据库设计-简化字典表[通俗易懂]
shell-第六章练习
将字符串转换为数字
Some errors of tensorflow calling multiple GPUs
Only know that the preform is used to generate objects? See how I use unity to generate UI prefabs