C语言是什么?

种用于人类与计算机交流的计算机语言

2.C语言的历史和辉煌

C语言最初是作为Unix系统的开发工具而发明出来,其先前有汇编语言,B语言;
1988年,美国国家标准协会(ANSI)正式将C语言标准化,直至今日,C语言仍然在广泛的使用。

3.编译和链接

C语言是一门编译型的语言,其源代码都是文本文件,本身无法执行,
必须通过编译器翻译和链接器的链接生成可执行的二进制文件才能执行。


Windows 与 Linux 下 C 编译工具链对比:MSVC MinGW GCC
本文系统梳理Windows平台下的 MSVC和MinGW与Linux平台下的GCC的区别。

工具链全称 / 背景所属生态主要平台
MSVCMicrosoft Visual C++ Compiler微软官方Windows
MinGWMinimalist GNU for WindowsGNU 开源社区Windows
GCCGNU Compiler CollectionGNU/Linux 开源生态Linux

MinGW本质上是在Windows运行的GCC,将Linux/的 GCC 工具链移植到Windows,并提供对Windows API的访问能力

三者都经历 预处理 → 编译 → 汇编 → 链接 四个阶段,但工具和输出格式存在差异:

步骤MSVC (Windows)MinGW (Windows)GCC (Linux)
编译器前端cl.exegcc.exegcc
汇编器内嵌于 cl.exeas(GNU as)as
链接器link.exeld(GNU ld)ld
目标文件格式COFF(.objCOFF(使用 .o 扩展名)ELF(.o
可执行文件格式PE(.exePE(.exeELF(通常无扩展名)
静态库.lib.a.a
动态库.dll + .lib(导入库).dll + .dll.a 或 .lib.so

要注意MSVC和MinGW都生成.dll,但他们不能混用,它们使用不同的运行时库(CRT)和 ABI(应用二进制接口)混合链接会导致崩溃。

工具链运行时库是否需要额外安装?部署便利性
MSVCMSVCRT(如 msvcr140.dllvcruntime140.dll需安装对应版本的 Visual C++ Redistributable较麻烦(需分发运行时)
MinGWmsvcrt.dll(Windows 系统自带)或静态链接通常无需额外安装(尤其静态链接时)更轻量、独立
GCC (Linux)glibc(系统自带)一般已存在依赖系统版本
方面MSVCMinGWGCC (Linux)
IDE 支持深度集成 Visual Studio(调试强大)Code::Blocks、Qt Creator、VS CodeVim/Emacs + GDB,或 VS Code、CLion
调试器cdb / Visual Studio Debuggergdbgdb
构建系统MSBuild、CMake(支持)Make、CMakeMake、CMake、Meson 等
标准支持C++20/23 支持较好(随 VS 更新)依赖 GCC 版本(如 MinGW-w64 GCC 13)最新标准支持快(开源社区活跃)
跨平台性仅 Windows可跨平台原生跨平台

编译单个文件


# MSVC-在 Developer Command Prompt 中
cl hello.c
# MinGW
gcc hello.c -o hello.exe
# Linux GCC
gcc hello.c -o hello

笔者使用的编译器为MinGw&GCC,环境为VScode or Debian 12.0

4.源文件,头文件介绍

C语言把.c为后缀的文件称为源文件,把.h为后缀的文件称为头文件。

第一个C语言程序

#include <stdio.h>
int main(void)
{
printf("hello world!\n");
return 0;
}
5.main函数

main函数是程序的入口,因此被称为主函数,无论这个C语言程序有多少行代码,均从main函数开始执行。
int表示main在执行结束时需要返回一个整型类型的值,这与结尾的return 0相互呼应。

即使一个项目有多个.c文件,也只可以有一个main函数

6.printf和库函数

上面第一个C语言程序中包含了一个代码:


printf("hello world!\n");

此处使用了printf函数,实现在屏幕上打印的功能。
printf是一个库函数,printf也可以打印其他类型的数据:


int n = 100;
printf("%d\n",n); //打印整型
printf("%c\n",'q'); //打印字符串
printf("%lf\n",3.14); //打印双精度浮点行

这里的%d %c是占位符,会被后面对应的值替换,此处只做初步了解。

在使用库函数的时候,必须包含其对应的头文件,比如printf函数需要包含stdio.h这个头文件

使用库函数的方法是添加:


#include <stdio.h>
为什么需要库函数呢?

为了不在重复实现常用的代码,C语言标准规定了一组函数用于提升开发效率,由不同的编译器厂商根据标准实现,这些函数库叫做标准库,有一些厂商会自行添加函数,为了代码的移植性和跨平台开发,我们应该主动使用标准库中的函数

7.C语言中的关键字

在C语言有一些符号名称被保留下来,诸如:int,if,return,goto等等

  • 关键字具有特殊含义
  • 人为创建标识符的时候不能与关键字重复
  • 关键字也不可以被创建

C语言中最通用普遍的关键字一共有32个:


1.auto break case char const continue default do double else enum
extern
2.float for goto if int long register return short signed sizeof
static
3.struct switch typedef union unsigned void volatile while

C99中加入了_Bool_Complex_Imaginaryinlinerestrict
C11中加入了_Alignas,_Alignof,_Atomic,_Static_assert,_Noreturn,_Thread_local,generic

8.字符和ASCII编码

诸如:&,!,n,p,%,@等,这样的符号叫做字符,在C中,这些字符使用单引号括起来的,像这样:'X'
在计算机中所有的数据都是以二进制存储的,这些字符在内存中如何用二进制存储?美国国家标准学会(ANSI)指定了标准ASCII编码,C中的字符就遵循ASCII编码的方式。
 

firefox_KGDEfnpF03


我们只需要能够查阅表格即可,,但为了一些场景使用方便,我们最好记住一些特殊的数字:

  • 字符A-Z的码值在65-90
  • 字符a-z的码值在97-122
  • 大小写字符A-Z,a-z的码值差值是32
  • 数字字符0~9的码值在48-57
  • 换行\n的码值为10
  • 0~31码值对应的字符不可被打印

打印单个字符可以用占位符%c指定其格式:


#include <stdio.h>
int main(void)
{
printf("%c\n",'X');
printf("%c\n",88);
return 0;
}

在屏幕上输出所有的可打印字符:


#include <stdio.h>
int main(void)
{
int i = 0;
for (i = 32; i <= 127;i++)
{
printf("%c ",i);
if (i % 16 == 15)
printf("\n");
}
return 0 ;
}

这样会在终端上输出所有的可打印字符。当然,不能少了编译的过程。

9.字符串和隐藏的\0

我们已经知道了字符这个概念,如果是很多字符连接起来叫做什么?
在C语言中表示字符串使用:
"abcdefg",使用双引号括起来的字符叫做字符串,像一串“烧烤”


打印字符串可以用占位符%s指定其格式,也可以直接打印字符串:


#include <stdio.h>
int main(void)
{
printf("%s\n","abcdefg");
printf("abcdefg");
return0;
}

在字符串中,其实隐藏了一个\0字符,这个\0放置在字符串的末尾,\0是字符串结束的标志。

例如字符串"abcdefg",显示出来7个字符,但在末尾还有一个隐藏的\0,使用printf()函数打印字符串或者使用serlen()函数计算字符串长度的时候,遇到\0就停止,因此\0是字符串的结束标志


在C语言中也可以把一个字符串放在字符数组里来验证\0的作用:


#include <stdio.h>
int main(void)
{
char arr1[] = {'a','b','c'};
char arr2[] = {"abc"};
printf("%s\n",arr1);
printf("%s\n",arr2);
return 0;
}

在进行调试的过程中可以观察到arr1arr2中内容的差异,arr1中只有a,b,c。而arr2中则有a,b,c,\0。由于笔者暂时还不会在Linux中调试,因此脑补一下吧(滑跪--)


如果运行这段代码,可能会产生这样的现象:


abc烫烫烫烫烫烫?n?
abc

这是因为没有\0,仍然向后读取内存中的内容,具体什么内容?那就是未知数了。

arr2数组因为使用了字符串常量初始化,因此一切正常。
若在arr1中单独加入\0,则一切也会正常
由此可见\0的作用

10.转义字符

在上文中使用了\0,\n,这些也是字符,但他们是一组特殊的字符,成为转义字符,用来转变原来字符的意思。


在屏幕中打印出n,很显然:


#include <stdio.h>
int main(void)
{
printf("abcdnefg");
return 0;
}

会输出:


abcdnefg

如果在n之前加入\,则:


#include <stdio.h>
int main(void)
{
printf("abcd\nefg");
return 0;
}

会输出:


abcd
efg

显然两次输出的结果差异很大
\n这个转义字符表示换行


在C语言中的转义字符还有:

  • \a:响铃(Bell),产生 audible 或 visible 警告(如终端 beep)
  • \b:退格(Backspace),光标回退一格
  • \f:换页(Form feed),用于打印机或终端清屏(在某些终端等效于清屏)
  • \n:换行(Newline),将光标移到下一行开头
  • \r:回车(Carriage return),将光标移至当前行开头(不换行)
  • \t:水平制表符(Horizontal tab),通常跳到下一个 8 字符/4 字符对齐位置
  • \v:垂直制表符(Vertical tab),在现代终端中较少使用
  • \\:反斜杠字符本身(用于表示字面量 \
  • \':单引号字符(用于字符常量中,如 '\'
  • \":双引号字符(用于字符串中包含引号,如 "He said \"Hi\""
  • \?:问号字符(用于避免与三字符组 trigraphs 冲突,现已很少用)
  • \0:空字符(Null character),ASCII 值为 0,常用于字符串结尾
  • \ooo:1~3 位八进制数表示的字符(如 \141 表示 'a')
  • \xhh:1~2 位十六进制数表示的字符(如 \x61 表示 'a')

用代码可以演示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值