一.苏格拉底人生三问
你们没点错文章,这不是考研政治。
正如我标题所写,这是一篇不正经的C语言入门,我将用通俗易懂,或者脑袋中灵光一现的想法来讲解C语言。
而这篇关于C语言的常见概念,我将以苏格拉底的三个问题作为开篇
不扯远了,那么苏格拉底的人生三问是啥呢?
“我是谁?我从哪里来?我到哪里去?”
在刚开始学习C语言时,我们也要思考这三个问题。
什么是C语言
C语言是从哪来的
C语言能干啥
二.关于C语言
C语言是一种计算机语言。
人与人交流用的是自然语言,比如汉语,英语,日语,俄语......
那如果人要和计算机交流,就要用到计算机语言。
C语言就是众多计算机语言中的一种,初次之外还有C++,C#.Java......这些都是计算机语言
C语言最初是作为是作为Unix系统开发工具而发明的
但是,在C语言发明之前,其实还有一门B语言。
不过随着时间发展,人们发现B语言的局限性太多
于是,在B语言基础上诞生了C语言。
从C语言诞生至今,差不多有半个世纪了,但仍然处在计算机语言排行榜前三名。
并且众多编程语言也是在C语言的基础上进一步发展来的
当你学好了C语言后,再学其他编程语言,理解起来就会十分容易
所以学习C语言还是很有用滴。
三.有关编译器
工欲善其事必先利其器,想学好C语言,我们手边也必须要有一个称手的工具
接下来,我来介绍一下学习C语言要用到的"工具"
Ⅰ.编译和链接
C语言是一门编译型语言。
我们写出来的源代码是文本文件,计算机只会将其识别为一段字符
文本文件想要执行需要经过两个步骤:
编译器翻译和连接器链接
在经过这两个步骤后会将原来的文本文件变成二进制的可执行文件
我们所写的C语言代码存放在以.c为后缀的文件当中
要像得到一个可以运行的程序,需要通过编译和链接2个过程
那么,编译器和链接器具体是怎么起作用的呢
直接看这个图大家可能还是不太理解,这样我再打一个比方吧
不知大家在学文言文时经常会感觉读不懂
而老师们又最爱让我们来做文言文的翻译
那,如何将一篇文言文翻译成我们可以简单读懂的白话文呢
首先我们将一些古文里那些不理解的字词拆分开来,一字一句的翻译成对应的现代汉语
这一步就类似于编译器所执行的编译功能
编译器将原有的源文件(.c文件)经过处理形成对应的目标文件(.obj文件)
但这时计算机还是无法识别,因为我们只是把对应的字词翻译出来了
但可能有些无法连接成一句完整的句子
这时就要链接器出手了
多个目标文件经过链接器的处理后形成对应的可执行程序(.exe文件)
经过处理后形成的可执行文件就可以在windows电脑上运行了
Ⅱ.有关编译器
前面我们提到了,C语言是一门编译型的计算机语言
因此我们就需要依赖编译器将计算机语言变成机器能够听懂的指令
在这里我要提出一个其他博主没有提到的一个小细节
我们常听到的如VS2022,VS2019,DevC++,Clion等,严格意义上来说,他们不叫作编译器,而是称作集成开发环境。
而⽐如msvc、clang、gcc就是⼀些常⻅的编译器。
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。 |
看懂了吗。
对,我也没看懂
就拿VS2022和DevC++来举例
VS2022集成了MSVC这个编译器
DevC++集成了gcc编译器
我们可以将集成开发环境看作一个盒子,它里面装了许多工具,编译器就是其中一种
除了编译器外还有其他工具,它们之间会互相配合完成工作。
那么我上面提了那么多的集成开发环境,应该用哪个呢
我个人推荐大家使用VS2022,因为VS2022目前是一个主流的开发环境,在企业里也用的比较多
下载后就可以直接使用,非常方便
安装方法就不在这里赘言了
你都已经学会看博客了,还不会找教程吗(doge
VS2022的安装教程:https://www.bilibili.com/video/BV11R4y1s7jz/
四.第一个C语言程序
这就是一个简单的C语言程序
#include <stdio.h>
int main() {
printf("XXXX,启动!");
return 0;
}
至于我为什么不像教科书那样写Hello World
点击控制台上的绿色三角就可以让程序运行起来了
下面是程序的运行结果
五.有关main函数和库函数
①.main函数
一个C语言程序可能有一两行代码,也有可能有好几百行
但就是你写了一万遍的"xxxxx,启动"
C语言程序都是从main函数开始执行的
这里给刚开始学C语言的伙伴们提个醒
记住不要输错了,是main,并且后面还有英文格式的括号
不是mian
更不是
main函数也被称作主函数,是程序的入口
main前的int表示函数结束后返回一个整数类型的值
在main函数结尾要写上return 0;
至于这两句语句具体是什么意思
我将在后续的文章中慢慢解释
②.库函数
在上面那个程序中,我写了一句
printf("xxxx,启动");
这行代码使用了printf函数,会在屏幕上打印信息
至于什么是printf,嗯......
printf 是⼀个库函数,它的功能是在标准输出设备(⼀般指屏幕)上进⾏信息的打印。上⾯的代码是使⽤ printf 函数打印字符串。只要把想要打印的⼀串字符放 在双引号中并传递给printf函数就可以打印。 |
讲理论是最枯燥的,还是直接上代码吧
#include <stdio.h>
int main() {
printf("XXXX,启动! \n");
int O = 648;
printf("你充了%d块钱\n",O);
printf("出了一个%c\n", 'S');
printf("你这是第%lf次十连\n", 2.5);
return 0;
}
这里只是给大家展示一些printf函数的功能,可以打印不同类型的数据
至于其中的%d %c这些,现在我先不解释,留到后面再统一说
在我们使用库函数的时候,我们的程序必须包含头文件,
如printf函数就需要stdio.h这个头文件
至于什么是库函数
为了不再重复实现常⻅的代码,让程序员提升开发效率,C语⾔标准规定了⼀组函数,这些函数再由不 同的编译器⼚商根据标准进⾏实现,提供给程序员使⽤。这些函数组成了⼀个函数库,被称为标准 库,这些函数也被称为库函数。在这个基础上⼀些编译器⼚商可能会额外扩展提供部分函数(这些函 数其他编译器不⼀定⽀持)。 |
这概念太繁琐,记不住也没事。
你只要知道使用库函数时要加上对应的头文件就行
六.关键字
关于关键字有几个地方需要注意
• 关键字都有特殊的意义,是保留给C语⾔使⽤的
• 程序员⾃⼰在创建标识符的时候是不能和关键字重复的
• 关键字也是不能⾃⼰创建的。
其实这个点十分好理解,我们就将其看作一个特殊的“专有名词”就行.
当我们要用时可以随时用,但你不能凭空创造
来吧,喜欢背书的伙伴们,C语言的32个关键字来了:
auto break case char const continue default do double else enum extern
float for goto if int long register return short signed sizeof static
struct switch typedef union unsigned void volatile while
一下子记不住没关系,慢慢来,起码先保证有个大概印象就行
七.字符和ASCll码
什么是字符?
它是你在键盘上敲下的各种符号,如:y,s,q,d,@......这些符号都被称作字符。
在C语言当中字符用单引号括起来,比如'@','a','z'。
在计算机中,常用的进制包括:二进制、八进制、十进制与十六进制,
它们之间区别在于数运算时是逢几进一位。
比如二进制是逢2进一位,十进制也就是我们常用的0-9是逢10进一位。
二进制:二进制,在计算机内部,数据都是以二进制的形式存储的。
用0、1两个数字来表示数值,这就是二进制。例如,数字 0、1、10、111、100、1000001 都是有效的二进制。
八进制:八进制,采用0、1、2、3、4、5、6、7八个数字,逢八进一。
十进制:十进制,是日常生活中使用、接触最多的,采用0——9十个数字,满十进一。
十六进制:十六进制,是计算机中数据的一种表示方式,它是由0-9和A-F组成,字母不区分大小写。
随着计算机技术不断发展,为 了⽅便⼤家相互通信,不造成混乱,后来美国国家标准学会(ANSI)出台了⼀个标准ASCII编码,C 语⾔中的字符就遵循了ASCII编码的⽅式。
不要记住所有的ASCll码表中的类容,当我们有需要时查看就行
不过一些常用的数据我们需要记忆一下,放心,很简单记忆。
• 字符A~Z的ASCII码值从65~90
• 字符a~z的ASCII码值从97~122
• 对应的⼤⼩写字符(a和A)的ASCII码值的差值是32
(在记忆26个字母对应的ASCll码值时,我们只需要记住大写A和小写a,小写a的值比大写A大32
由此便可以推到出其他字母的值)
• 数字字符0~9的ASCII码值从48~57
• 换⾏ \n 的ASCII值是:10
• 在这些字符中ASCII码值从0~31这32个字符是不可打印字符,⽆法打印在屏幕上观察
#include <stdio.h>
int main()
{
int i = 0;
for (i = 32; i <= 127; i++) {
printf("%c ", i);
if (i%16==15)
{
printf("\n");
}
}
return 0;
}
这时有人可能要问了,那如何打印一个句子呢
#include <stdio.h>
int main()
{
printf("%c\n","xxxx,启动");
priintf("xxxx,启动");
return 0;
}
来,大家在自己的开发环境上敲下这段代码,看看执行后会输出什么。
是不是发现输出结果是一样的啊,别急,既然我提到这个点,那一定有要注意的东西
你再试试下面这段代码
int main()
{
char arr1[] = { 'w','z','r','y'};//在arr1数组中存放四个字符
char arr2[] = "uzinb";//在arr2数组中存放字符串
printf("%s\n", arr1);
printf("%s\n", arr2);
return 0;
}
当你的电脑出现类似的“烫烫烫”时,不要怕,这不是电脑在报高温预警
而是在打印字符数组时,在这些字符后面还打印了一些随机值
但为什么在下面这个就能正常打印呢?
真実はいつもひとつ!
啥,看不懂?
那这个呢
事实的真相就是:在字符串的末尾隐藏放着⼀个 \0 字符,这个 \0 字符是字符串的结束标志。
对于一串字符串,我们能看到的是几个字符,实际上在末尾还隐藏着一个\0的转义字符。
当使用库函数printf()来打印字符串时,计算机在遇到\0时就自动停止了。
通过上面的例子我们可以看到
arr1 字符数组在打印的时候,打印了 w、 z 、 r、y 后还打印了⼀些随机值,这就是 因为 arr1 在末尾的地⽅没有 \0 字符作为结束标志,在打印的时候没有停⽌。
但是, arr2 的打印就是完全正常的,就是因为 arr2 数组是使⽤字符串常量初始化的,
数组中有 \0作为技术标志,打印可以正常停⽌。
现在你了解了\0的作用
请在脑子运行一下这段代码。
int main()
{
char arr3[] = { 'a', 'b', 'c', '\0' };
char arr4[] = "abc";
printf("%s\n", arr3);
printf("%s\n", arr4);
printf("%s\n", "abc\0def");
return 0;
}
A.abc abc abc
B.abc烫烫烫 abc abc
C.abc\0 abc abc\0def
D.abc abc abcdef
E.我想喝奶茶了
答案揭晓:
此时我们发现三次输出的结果都相同,都是到\0时结束。
八.转义字符
能耐心看到这里的同学或者程序猿兄弟们,感谢了。
但同时请回顾一下我上面所写的代码。你发现我一直在写\n,\0。
功能你们已经大概了解了,那它们的具体含义是啥呢。
#inclue <stdio.h>
int main()
{
printf("abcdenf");
printf("abcde\nf");
return 0;
}
当我们在n前加上\时,输出的结果发生了变化
这就是转义字符的问题, \n 是⼀个转义字符表⽰换⾏的意思,我们可以简单的理解为 \ 让 n 的意思 发⽣了转变, n 本来是⼀个普通的字符,被 \ 转义为换⾏的意思。
在C语⾔中像这样的转义字符还有⼀些,具体如下:
• \? :在书写连续多个问号时使⽤,防⽌他们被解析成三字⺟词,在新的编译器上没法验证了。
• \' :⽤于表⽰字符常量'
• \" :⽤于表⽰⼀个字符串内部的双引号
• \\ :⽤于表⽰⼀个反斜杠,防⽌它被解释为⼀个转义序列符。
• \a :警报,这会使得终端发出警报声或出现闪烁,或者两者同时发⽣。
• \b :退格键,光标回退⼀个字符,但不删除字符。
• \f :换⻚符,光标移到下⼀⻚。在现代系统上,这已经反映不出来了,⾏为改成类似于
• \n :换⾏符。
• \r :回⻋符,光标移到同⼀⾏的开头。
• \t :制表符,光标移到下⼀个⽔平制表位,通常是下⼀个4/8的倍数。
• \v :垂直分隔符,光标移到下⼀个垂直制表位,通常是下⼀⾏的同⼀列。
这些也不是我记住的,都是我copy来的,像ASCll码一样,我们只需要记住常用的就行
如果大家想进一步了解可参考:
九.语句的分类
1.空语句
空语句是最简单的一条语句,单独一个分号就是一个空语句
#include <stdio.h>
int main()
{
;//空语句
return 0;
}
2.表达式语句
表达式语句就是在表达式的后边加上分号。
#include <stdio.h>
int main()
{
int x = 3;
int y = 8;
y = x + 10;
printf("%d", y);
return 0;
}
3.函数调用语句
函数调用语句就是在main函数之外先定义一个函数,在使用的时候直接调用该函数实现一定的算法操作
#include <stdio.h>
int Add(int x, int y)
{
return x+y;
}
int main()
{
printf("hehe\n");//函数调⽤语句
int ret = Add(2, 3);//函数调⽤语句
return 0;
}
4.复合语句
成对括号中的代码就构成⼀个代码块,也被称为复合语句。
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = {0};
for(i=0; i<10; i++) //for循环的循环体的⼤括号中的就是复合语句
{
arr[i] = 10-i;
printf("%d\n", arr[i]);
}
return 0;
}
5.控制语句
控制语句⽤于控制程序的执⾏流程,以实现程序的各种结构⽅式
在C语言当中支持三种结构:顺序结构,选择结构,循环结构。
至于它们的用法,等到了后面再一一详解。
十.关于注释
注释是对代码的说明,编译器它不会看你的注释,也不会编译运行.
也就是说,注释对实际代码没有影响。
注释的方法有两种:
//
/* */
其中/**/可以写在行内
比如
int fopen(char* s /* file name */, int mode);
但请注意,代码的符号是成对出现的,如果忘记了,就很容易出现错误。
注释是给程序员⾃⼰,或者其他程序员看的。
好的注释可以帮我们更好的理解代码,
正如这句弹幕,你不是何晨光,你的代码是要给别人看的
虽然有句话叫如果一个程序靠BUG跑起来,就不要动它
但加上适当的注释能帮助他人更好的理解
不过也不要过度注释,不要写没必要的注释。
如果没必要的注释太多,反而像这样起到画蛇添足的效果
当然不写注释可能会让后期阅读代码的⼈抓狂。
-----------------------------------------------------------------------------------------------------------------
呼,终于写完了,能看到这里的,感谢大家支持。
本文章内部分图片来源于网络,如有侵权请联系删除。