mirror of
https://github.com/hairrrrr/C-CrashCourse.git
synced 2026-05-04 14:34:50 +08:00
3 - 4
This commit is contained in:
430
C Crash Course/02 Basic Conception/text/01.md
Normal file
430
C Crash Course/02 Basic Conception/text/01.md
Normal file
@@ -0,0 +1,430 @@
|
|||||||
|
## C语言基本概念
|
||||||
|
|
||||||
|
*Syntactic sugar causes cancer of the semi-colons.*[^0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
> 码字不易,对你有帮助 **点赞/转发/关注** 支持一下作者
|
||||||
|
> 微信搜公众号:**不会编程的程序圆**
|
||||||
|
> **看更多干货,获取第一时间更新**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### :earth_asia:思维导图
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### :globe_with_meridians:目录
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
[TOC]
|
||||||
|
|
||||||
|
### :email:写在前面
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
如果只是写个人学习总结的博客很容易,简单写一些感悟然后贴上代码走人就可以了,甚至不用校审。但是我命名本系列为【C语言必知必会】帮助你从入门到精通 C语言,那势必要“事无巨细”一些:既要考虑到没有基础的初学者,又不能止于基础。所以本教程适合各类人群学习,只要你看就一定会有帮助。
|
||||||
|
|
||||||
|
本教程是本人纯手打并排版,校审由我与我的搭档汤圆君一起完成的。你们看这一篇文章我要写好几个小时。如果文章对你有帮助,请不要“白嫖”。支持一下作者,作者会发更多干货好文。
|
||||||
|
|
||||||
|
特别鸣谢:汤圆君(公众号:【Cc听香水榭】 长期更新高质量英语教学)关注她表示对她工作的认可吧!
|
||||||
|
|
||||||
|
### :books:教学
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### 第一个C程序
|
||||||
|
|
||||||
|
**main.c**
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
|
||||||
|
printf("Hello,World\n");//a simple C program
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
将上述程序写在你的编译器里。
|
||||||
|
|
||||||
|
然后给文件命名,并以`.c`作为扩展名,例如`main.c`。
|
||||||
|
|
||||||
|
现在,编译并运行该程序。如果一切正常,输出的应该是:
|
||||||
|
|
||||||
|
```c
|
||||||
|
Hello,World
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
恭喜你,你已经是一名C程序员了!:laughing:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*Hello,World 是伟大的。它像着一个呱呱坠地的婴儿对世界的问好,它憧憬着美好的世界,一切事物都是新鲜的。*
|
||||||
|
|
||||||
|
——不会编程的程序圆
|
||||||
|
|
||||||
|
现在,让我们看看这个程序到底是什么意思。
|
||||||
|
|
||||||
|
### 正式开始之前
|
||||||
|
|
||||||
|
#### 编译和链接
|
||||||
|
|
||||||
|
C程序编译链接的过程:(知道即可)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 集成开发环境
|
||||||
|
|
||||||
|
> 集成开发环境(integrated development enviroment,IDE):集成开发环境是一个软件包,我们可以在其中编辑,编译,链接,执行和调试程序。
|
||||||
|
|
||||||
|
IDE推荐:
|
||||||
|
|
||||||
|
CodeBlock(本教学中的简单的程序会用这个软件来完成)
|
||||||
|
|
||||||
|
VS2019(编写需要调试的程序用它来完成)
|
||||||
|
|
||||||
|
### 简单程序的一般形式
|
||||||
|
|
||||||
|
#### 1. 指令
|
||||||
|
|
||||||
|
示例程序第一行`#include<stdio.h>`就是一条指令。
|
||||||
|
|
||||||
|
在程序**编译之前**,C编译器的**预处理器**(preprocessor)会首先对源代码进行一些准备工作,即预处理(preprocessing)。
|
||||||
|
|
||||||
|
> **指令(directive):**我们把 预处理器 执行的命令称为 预处理器指令(preprocessor directive),简称指令。
|
||||||
|
>
|
||||||
|
> 指令的结尾不需要添加分号
|
||||||
|
|
||||||
|
`#include<stdio.h>`的作用相当于把 **头文件** `stdio.h` 中的所有内容都输入到该行所在的位置。
|
||||||
|
|
||||||
|
实际上,这是一种**复制+粘贴**的操作。
|
||||||
|
|
||||||
|
**include 文件提供了一种方便的途径共享许多程序共有的信息**。
|
||||||
|
|
||||||
|
`stdio.h`文件中包含了供编译器使用的输入和输出函数(如 `printf()`)信息。
|
||||||
|
|
||||||
|
该文件名的含义为**标准输入/输出**头文件(stadard input&output .header)
|
||||||
|
|
||||||
|
> **头文件(header):**在C程序顶部的信息集合。
|
||||||
|
|
||||||
|
每个头文件都包含一些标准库的内容。
|
||||||
|
|
||||||
|
示例程序引入stdio.h头文件的原因:C语言不同于其他编程语言,它没有内置的“读/写”命令。输入/输出功能由标准库中的函数实现。[^1]
|
||||||
|
|
||||||
|
**每次用到库函数,必须用#include指令包含相关的头文件。**省略必要的头文件可能不会对某一个特定程序造成影响,但是最好不要这样做。
|
||||||
|
|
||||||
|
[^1]: 为何不内置输入/输出? 原因之一是并非所有程序都会用到I/O(输入输出)包 。简洁高效表现了C语言的哲学。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 2.函数
|
||||||
|
|
||||||
|
`int main(void)`
|
||||||
|
|
||||||
|
> **函数:**类似于其他编程语言的“过程”或“子例程”,它们是用来构建程序的构建块。
|
||||||
|
|
||||||
|
事实上,C语言就是函数的集合。
|
||||||
|
|
||||||
|
函数分两大类:第一种是程序员自己编写的函数;另一类则是C作为语言实现的一部分提供的函数,即**库函数**(library function)。因为它们属于一个由编译器提供的函数“库”。
|
||||||
|
|
||||||
|
**main函数**:C程序都是从`main()`函数“开始”执行。`main()`函数是程序的唯一入口。**可以理解为程序是从main函数开始运行到main函数结尾结束。**
|
||||||
|
|
||||||
|
**返回类型**:`int`是main函数的 返回类型。这表明 main函数返回的值是整型。
|
||||||
|
|
||||||
|
*返回给哪里?返回给操作系统,我们后面再来讲解*
|
||||||
|
|
||||||
|
**参数**:`()`内包含的信息为函数的参数。示例中的`void`表示该例中没有传入任何参数。
|
||||||
|
|
||||||
|
> **请注意**
|
||||||
|
>
|
||||||
|
> 有背景颜色的地方都是重要的知识,但是在这里不管你是初学者/学了一段时间了,我都建议你遵守以下规范:
|
||||||
|
>
|
||||||
|
> **main函数到底应该怎么写?**我在这里不详细展开说。
|
||||||
|
>
|
||||||
|
> **正确的形式**:`int main(int argc, char* argv[])`
|
||||||
|
>
|
||||||
|
> **可以接受的形式:**`int main(void)`
|
||||||
|
>
|
||||||
|
> **错误的写法**:`int main()` 谭老师书中的写法。跟我学,不要用这种写法
|
||||||
|
>
|
||||||
|
> **脑瘫的写法**:`void main()` `void main(void)`所有C语言的标准都未认可这种写法,你在赣神魔?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`return 0`
|
||||||
|
|
||||||
|
**返回值**:前面我们讲到了*返回类型*,那么就应该有个返回值。示例中 `return `就代表返回,`0`是这个main函数的返回值。
|
||||||
|
|
||||||
|
> **main函数中return的作用**:
|
||||||
|
>
|
||||||
|
> 1.**使main函数终止**。mian函数在这里结束。
|
||||||
|
>
|
||||||
|
> 2.main函数返回值是0,**表示程序正常终止**。
|
||||||
|
|
||||||
|
**所以,`return 0`在main函数中是不可省略的**
|
||||||
|
|
||||||
|
虽然即使你不写,可能也可以通过编译,但是不写是不对的。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 3.语句
|
||||||
|
|
||||||
|
> 语句是程序运行时执行的命令
|
||||||
|
>
|
||||||
|
> 语句是带顺序执行的 C 程序段。任何函数体都是一条复合语句,继而为语句或声明的序列
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```c
|
||||||
|
int main(void)
|
||||||
|
{ // 复合语句的开始
|
||||||
|
int n = 1; // 声明(非语句)
|
||||||
|
n = n+1; // 表达式语句
|
||||||
|
printf("n = %d\n", n); // 表达式语句
|
||||||
|
return 0; // 返回语句
|
||||||
|
} // 复合语句之结尾,函数体之结尾
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**C语言中的六种语句**
|
||||||
|
|
||||||
|
1. **标号语句**
|
||||||
|
|
||||||
|
1) [goto](https://zh.cppreference.com/w/c/language/goto) 语句的目标。 (*标识符* **:** *语句*)
|
||||||
|
|
||||||
|
2) [switch](https://zh.cppreference.com/w/c/language/switch) 语句的 `case` 标号。(**case** *常量表达式* **:** *语句*)
|
||||||
|
|
||||||
|
3) [switch](https://zh.cppreference.com/w/c/language/switch) 语句的默认标号。 (**default** **:** *语句*)
|
||||||
|
|
||||||
|
2. **复合语句**
|
||||||
|
|
||||||
|
复合语句,或称**块**,是**花括号**所包围的语句与声明的序列。
|
||||||
|
|
||||||
|
`{声明(可选)| 语句 }`
|
||||||
|
|
||||||
|
3. **表达式语句**
|
||||||
|
|
||||||
|
典型的 C 程序中大多数语句是表达式语句,例如赋值或函数调用。
|
||||||
|
|
||||||
|
无表达式的表达式语句被称作*空语句*。它通常用于提供空循环体给 [for](https://zh.cppreference.com/w/c/language/for) 或 [while](https://zh.cppreference.com/w/c/language/while) 循环。
|
||||||
|
|
||||||
|
4. **选择语句**
|
||||||
|
|
||||||
|
选择语句根据表达式的值,选择数条语句之一执行。
|
||||||
|
|
||||||
|
1) [if](https://zh.cppreference.com/w/c/language/if) 语句
|
||||||
|
|
||||||
|
2) [if](https://zh.cppreference.com/w/c/language/if) 语句带 `else` 子句
|
||||||
|
|
||||||
|
3) [switch](https://zh.cppreference.com/w/c/language/switch) 语句
|
||||||
|
|
||||||
|
5. **迭代语句**
|
||||||
|
|
||||||
|
迭代语句重复执行一条语句。
|
||||||
|
|
||||||
|
1) [while](https://zh.cppreference.com/w/c/language/while) 循环
|
||||||
|
|
||||||
|
2) [do-while](https://zh.cppreference.com/w/c/language/do) 循环
|
||||||
|
|
||||||
|
3) [for](https://zh.cppreference.com/w/c/language/for) 循环
|
||||||
|
|
||||||
|
6. **跳转语句**
|
||||||
|
|
||||||
|
跳转语句无条件地转移控制流。
|
||||||
|
|
||||||
|
1) [break](https://zh.cppreference.com/w/c/language/break) 语句
|
||||||
|
|
||||||
|
2) [continue](https://zh.cppreference.com/w/c/language/continue) 语句
|
||||||
|
|
||||||
|
3) [return](https://zh.cppreference.com/w/c/language/return) 语句带可选的表达式
|
||||||
|
|
||||||
|
4) [goto](https://zh.cppreference.com/w/c/language/goto) 语句
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**为什么需要分号?**
|
||||||
|
|
||||||
|
由于语句可以连续占用多行,有时很难确定它结束的位置,因此需要用分号来向编译器表示语句结束的位置。但预处理指令通常只用占一行,因此**不需要**分号结尾
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 4.打印字符串 printf() 函数
|
||||||
|
|
||||||
|
`printf("Hello,World\n");`
|
||||||
|
|
||||||
|
`printf()`是一个功能十分强大的函数。*后面我们会进一步介绍*
|
||||||
|
|
||||||
|
示例中我们只是用printf函数打印了出了一条**字符串字面量(string literal)** —— 用一对双引号引起来的一系列字符。
|
||||||
|
|
||||||
|
**字符串**,顾名思义就是一串字符。
|
||||||
|
|
||||||
|
printf函数不会自动换行到下一行打印,它只会在它最开始那一行一直打印直到程序迫使它换行。
|
||||||
|
|
||||||
|
`\n`表示printf函数打印完成后跳转到下一行
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
请看如下程序,思考它的效果与示例中有何不同?
|
||||||
|
|
||||||
|
```c
|
||||||
|
printf("Hello,");
|
||||||
|
printf("World\n");
|
||||||
|
```
|
||||||
|
|
||||||
|
答案[^2](点击或到文章尾查看)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
如果想输出下面的结果,请考虑一下,应该如何写程序呢?
|
||||||
|
|
||||||
|
```c
|
||||||
|
Hello,
|
||||||
|
World
|
||||||
|
```
|
||||||
|
|
||||||
|
答案:
|
||||||
|
|
||||||
|
```c
|
||||||
|
printf("Hello,\n");
|
||||||
|
printf("World\n");
|
||||||
|
```
|
||||||
|
|
||||||
|
对于这个问题,第二个printf函数的 \n 可以省略。简单来说,printf函数会在 \n 出现的地方换行。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 5.注释
|
||||||
|
|
||||||
|
`//a simple C program`
|
||||||
|
|
||||||
|
> 写注释可以让自己和别人更容易明白你写的程序。
|
||||||
|
>
|
||||||
|
> C语言注释的好处是:可以写在任何地方。注释的部分会被编译器忽略。
|
||||||
|
|
||||||
|
我们试想一件事你昨天吃了什么饭,记性好是吧?上周五吃的什么饭?如果连上周 一天三顿的饭都不能记住,何况你自己查看你很久之前写的代码呢?
|
||||||
|
|
||||||
|
##### 两种注释符号
|
||||||
|
|
||||||
|
第一种:`/* */`
|
||||||
|
|
||||||
|
单行注释
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* 关注微信公众号:不会编程的程序圆 */
|
||||||
|
/* 看更多干货,获取第一时间更新 */
|
||||||
|
/* 码字不易,对你有帮助 点赞/转发/关注,鼓励一下作者 */
|
||||||
|
```
|
||||||
|
|
||||||
|
多行注释
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* 关注微信公众号:不会编程的程序圆
|
||||||
|
看更多干货,获取第一时间更新
|
||||||
|
码字不易,对你有帮助 点赞/转发/关注,鼓励一下作者 */
|
||||||
|
```
|
||||||
|
|
||||||
|
但是,上面这一种注释方式可能难以阅读,因为人不不容易发现注释结束的位置。
|
||||||
|
|
||||||
|
改进:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/*关注微信公众号:不会编程的程序圆
|
||||||
|
看更多干货,获取第一时间更新
|
||||||
|
码字不易,对你有帮助 点赞/转发/关注,鼓励一下作者
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
更好的方法:将注释部分围起来
|
||||||
|
|
||||||
|
```c
|
||||||
|
/*************************************************
|
||||||
|
* 关注微信公众号:不会编程的程序圆 *
|
||||||
|
* 看更多干货,获取第一时间更新 *
|
||||||
|
* 码字不易,对你有帮助 点赞/转发/关注,鼓励一下作者 *
|
||||||
|
*************************************************/
|
||||||
|
```
|
||||||
|
|
||||||
|
当然如果你嫌麻烦,也可以简化一下:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/*
|
||||||
|
* 关注微信公众号:不会编程的程序圆
|
||||||
|
* 看更多干货,获取第一时间更新
|
||||||
|
* 码字不易,对你有帮助 点赞/转发/关注,鼓励一下作者
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
简短的注释可以放在同一行
|
||||||
|
|
||||||
|
```c
|
||||||
|
printf("Hello World\n");/* 不会编程的程序圆 */
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
但是,如果你忘记了终止注释可能会导致你的编译器跳过程序的一部分,请思考下列:
|
||||||
|
|
||||||
|
```c
|
||||||
|
printf("不会"); /* 关注我的公众号呦~
|
||||||
|
printf("编程");
|
||||||
|
printf("的"); /* 更多鼓励,更多干货!*/
|
||||||
|
printf("程序圆");
|
||||||
|
```
|
||||||
|
|
||||||
|
你可以在自己的编译器上自己敲一下,看看会输出什么。
|
||||||
|
|
||||||
|
由于第一条注释忘记输入结束标志,导致编译器将直到找到结束标志之前的程序都当成了注释!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
第二种:`//`
|
||||||
|
|
||||||
|
C99提供的新的注释方式。
|
||||||
|
|
||||||
|
```C
|
||||||
|
//关注微信公众号:不会编程的程序圆
|
||||||
|
//看更多干货,获取第一时间更新
|
||||||
|
//码字不易,对你有帮助 点赞/转发/关注,鼓励一下作者
|
||||||
|
```
|
||||||
|
|
||||||
|
> 新的注释风格有两大优点:
|
||||||
|
>
|
||||||
|
> 1. 这种注释会在行末自动终结,所以不用担心会出现未终止的注释意外吞噬部分程序的情况
|
||||||
|
> 2. 每行前都有 // ,所以多行的注释更加醒目
|
||||||
|
|
||||||
|
综上所述,建议采用 `//` 这种注释方式
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[^0]: *语法糖导致分号癌。摘自《epigrams-on-programming》*
|
||||||
|
[^2]: 相同。
|
||||||
|
|
||||||
|
*参考资料:《C Primer Plus》《C语言程序设计:现代方法》 网上资料:cppreference.com*
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
> 本文GitHub已更新,文中代码都可以在上面对应的目录下找到,欢迎 star !
|
||||||
|
> https://github.com/hairrrrr/C-CrashCourse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
以上就是本次的内容。
|
||||||
|
|
||||||
|
如果文章有错误欢迎指正和补充,感谢!
|
||||||
|
|
||||||
|
最后,如果你还有什么问题或者想知道到的,可以在评论区告诉我呦,我在后面的文章可以加上。
|
||||||
|
|
||||||
|
**关注我**,看更多干货!
|
||||||
|
|
||||||
|
我是程序圆,我们下次再见。
|
||||||
Reference in New Issue
Block a user