C语言教程-1_1-什么是程序

C语言概述

编程语言与算法

首先,关于C语言的历史发展,您应该去书上找到答案,而不是在这里快速浏览的一带而过。

那么,C语言是属于一门编程语言,而且是属于一种高级语言(代码是接近自然语言的表述),但同时由于其独特的指针等特性,说他是中级语言也不为过。作为编程语言,其作用自然是显而易见---用于描述算法。

我个人不愿意把算法这个东西神秘化,很多东西都能叫算法,大到一个高级的数学问题求解,小到如何做出一道菜,都可以成为“算法”。我不愿意去搬一些砖头书的标准概念---我这也算是感想笔记,简单来说,算法有三个要素:前提条件,目的,过程。

前提条件,就是完成一个算法的要求。例如做一道菜,你需要准备的食材,工具;计算a+b=c这个算法,你需要给我提供a,b这两个数。

目的,就是这个算法到底要干什么。例如我要做出一道菜;我要算出a+b的和c这个数。

过程,就是到底如何操作。例如我要切菜,煮菜,调味等等;我要把a和b做一个竖式计算。

以上都完备,且确认均正确无误,就可以成为一个完整的算法。也就是说,甚至一个windows操作系统某种程度上也可以说是一个算法---我有机器设备,能源,数据来源;我要用于计算/为用户提供服务;我有自己的底层逻辑来完成以上所有的功能。

那么,想要描述一个算法,就要用到专门的记录语言---编程语言,那么C语言就是其中的独特的一种。

C语言的特点

编程语言有一些特点:

静态(C,JAVA,C++等)/动态类型(Python,JavaScript等)语言

弱类型(VB)/强类型(C,JAVA,C++,Python)语言

编译型(C,C++,RUST)/解释型(Python/JavaScript)/介于两者之间的(JAVA)语言

面向过程(C,FORTRAN)/基于对象(JavaScript)/面向对象(Python,JAVA)/既可面向对象也可面向过程(C++)语言

其中,C语言的特性如上所述。具体都是什么意思请百度,不知道也没有关系,学到其他语言自然就能体会巨大的差异了。

C语言的强类型,静态类型我个人认为不容易出错,但是相对的缺少灵活性(尽管C本身以灵活著称)。毕竟是一门古老,极其精简的语言了。你会发现,越发复杂,支持各种高级操作的语言,其底层代码就更加复杂,而C语言如此精简,势必会显得单薄---除非是有别人写好的库,不然你都得自己重头写起。

作为一门老语言,当然只支持面向过程,同时也支持函数式编程(一定程度上模块化),学C,就不要羡慕其他语言,如果你真的羡慕,那么你干嘛要选择C呢?

C语言是如何运作的

C代码是怎么样的

我们上一个最简单,最经典的代码---Hello World!程序,作为经典的入门代码

/*
这是一段注释---这是一个hello world程序
*/
// 这是一行注释
#include <stdio.h> //包含一个头文件stdio.h,其中

int main() {// 这是一个函数,而且是C程序的入口,一切必须从这里开始执行
printf("Hello, World!\n"); // printf是一个函数,用于输出一个字符串,这里输出"Hello World!"
return 0; // 代表结束main函数,并返回一个0,这里先不用关心其作用,只要记住main函数要加上这条语句即可
}

下面将程序拆解为几块来分别进行讲解:

头文件包含#include<stdio.h>

作为描述算法的语言,与过程不可分割,一个大型算法中会包含许多小操作,这些小操作甚至也是一些子算法,整个算法分为几个不同的步骤去进行,其中一些最基本的不可或缺的操作/已经开发好的算法/处理操作就没有必要再去手动重新编写,也就是说别人已经造好了轮子,你先拿来用就行。也就是说C语言也有许多写好的“库”可以直接使用,我们想要使用它们,一般(不是绝对)都要加上库自带(提前写好的)的“导入信息”,C语言中称为头文件。实际上,头文件包含了许多函数/自定义类型等元素的声明(后面说明),想要使用某个函数,那么必须让编译器知道我导入了这个函数(事先声明好)。

主函数main()

无规矩不成方圆,一个程序必须有管事的老大,一切运算必须从main()函数开始(也就是主函数),无论执行什么函数,都必须从main()中开始调用或者由其他函数进行进一步的调用。

int main()叫做main函数的函数头,它包含了这个函数的基本信息---函数的名称,需要传递的参数,函数的返回值类型.c语言的函数和数学意义上的函数完全等价,例如f(x)=x+1,其中x为整数 这个函数就可以写为:

int f(int x){ 
// int 代表x为整型变量(保存整数),第一个int代表这个函数返回值(可以理解为f(x))为整型;
// 第二个 int 代表这个函数的参数(即x)为整型
return x+1;
}

最后,函数头后面紧跟的就是函数体,函数体里包含了这个函数的一切操作,函数体以{}作为边界.

函数内的语句

一个函数中包含的所有内容就是这个函数要执行的运算,还有一些辅助的/必要的数据(局部变量或函数参数),每一个操作叫做一条语句,语句必须由一个;来结束,一个语句可复杂可简单,一条语句由若干个表达式构成,表达式越多,越复杂冗长,这条语句就越复杂。所以,如果可以,尽可能把一个复杂的操作分成几条语句(几步分开的操作)来运算。

例如printf("Hello, World!\n");这条语句就是执行了一个输出字符串的操作,其中只包含了一个表达式---函数调用表达式---调用了printf()这个函数.

注意:大部分入门教程绝对不会提到"函数调用表达式"这个概念,请以我的说法为准!从来没有"函数调用语句"这个东西!

C语言的大部分语句是由表达式构成的!

再例如return 0;这条语句就是执行了一个函数返回的操作,任何函数,一旦执行到return语句,即意味着这个函数的执行立即结束,后面的代码无论多少都不会再继续执行,直接返回.return后面跟着的那个值也是一个表达式,可以放置任意和函数类型符合的,可以求值的表达式,此处main函数默认返回一个0,0就是一个值为0的常量表达式.

总结

我们可以发现,一般情况下,一个完整c程序必须或应该包含以下几个部分:

1.使用#include<>命令进行头文件的包含,不同的头文件内包含了我们这个程序可能用到的各种函数等的信息

例如我们用于输出的printf()函数就在stdio.h这个头文件内

2.一个必须存在的函数,他是一切的开始---int main()函数

一个最规范正确(没有参数时)的main函数的格式应该是这样:

int main(void){ // 代表main函数的返回值为int类型,同时没有任何参数
//其他语句
return 0;
}

我们最多可以把那个括号中的void省略,因为main中的void是在新标准中推荐添加的,我们基于C99版本进行学习即可.

你还可能看到这样的写法,我们暂时用不到,但他们是没有问题的:

//这样的:
#include <stdio.h>
int main(int argc,char *argv[],char *envp[]){
//其他语句
return 0;
} 
//或者是这样的:
int main(int argc,char *argv[],char **envp){
//其他语句
return 0;
} 
//甚至是这样的:
int main(int argc,char *argv[],char *envp[]){
//其他语句
return 0;
}

上面这3种都没有问题,但是我们暂时用不到,特别是第3种.

另外,一切教导你这样写main函数的教材或书,请你扔掉它:

main(){
//main前面没有int
//其他语句
//没有return 0;
}

3.其他过程,也就是其他的辅助函数,用于将功能独立出来

4.一些注释,用于标注这个程序是用来干什么的,或者某一段代码是干什么的

注意:一定要养成写注释的习惯,特别是程序越发复杂,更应该编写注释来以备日后回看,方便改进和维护.

警惕"烂书"教你的错误写法

之所以让你"扔书",是想让你知道什么是该学的规范写法,什么是业余的写法:

1.只有旧标准才允许main前不加返回类型(也就是那个int).

2.此外,如果你发现有这么写的void main(),请毫不犹豫地把这本书扔掉,因为不加返回类型勉强可以说是对的,只不过是旧写法,但是唯独void main(),从来没有任何标准中写过这种写法是正确的.不信你可以在现在(2023年)找大众的编译器来编译,99%会报错.

image-20230924183653567image-20230924183730275

从这两张图可以看出至少main()没有报错.实际上,main()的写法没有报错是为了对老程序的兼容性---毕竟前面所述,这是一种旧的写法,而不是完全错误的写法.我们学习,就要写int main(),或者你想加void也行.

C代码是如何成为计算机程序的

学习C语言,或者说学习编程,就是和计算机打交道,多少要了解一些计算机的原理,否则,你学的C语言永远是花架子,找不到精髓.

我认为:一个计算机程序=算法+数据结构,同时他们也有交叉,一个完备的算法应该考虑到对应的数据结构;一种特定的数据结构应该为一个或一系列算法服务.

C代码,说到底还是一个文本文档,他只是记录了一个程序的逻辑,并不是一个可用的程序,那么作为一种编译型语言,想要把C源文件转换为可执行程序,就需要使用到专门的工具---C编译器(一切编译型语言都有自己的编译器,例如RUST有RUST自己的编译器),我们最常见的就是3种:GCC编译器,MSVC编译器,Clang编译器,我个人使用GCC来进行c代码的编译,他们大同小异,初学阶段无需考虑其差异,任何IDE都有对应的编译器可供使用.

这里的C源文件就是例如hello.c这样的以.c为后缀的文本文档,实际上它和.txt没有任何区别.他并不是二进制的文件.C编译器做的工作就是"编译",同时这个"编译"实际上包含了许多操作:"预处理"->"编译"->"汇编"->"链接",最终链接完成后才是最终的可执行文件,这里的知识点暂时没什么用,可以自行了解.你只需知道,源文件经过编译后才能成为真正的二进制程序用于运行.

一旦成为计算机程序,就和语言无关了,因为二进制程序是和系统架构严格相关的,RUST编译出来的程序,C++编译出来的程序,C编译出来的程序,都是给同一个系统使用的,也就是说,不管内部细节的话,某种程度上他们已经是和语言无关了.

我们学了C语言是要干什么

了解了C语言的过程,我们作为C这门技术的使用者,我们的职责就是:

设计算法(或者由其他人设计好,例如数学家等)->构思程序->使用C语言进行程序的编写->进行调试测试->确认无误后生成正式的程序->将程序用于实际的生产作业来发挥作用->维护并改进.

最关键的就是程序编写和调试测试.


---WAHAHA,2023.9.19



上一篇:写在前面

下一篇:C语言教程-1_2-关键概念

posted @ 2024-01-24 17:21  WA-HAHA  阅读(36)  评论(0)    收藏  举报