惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Engineering at Meta
Engineering at Meta
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
D
Docker
Vercel News
Vercel News
云风的 BLOG
云风的 BLOG
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
DataBreaches.Net
IT之家
IT之家
V
V2EX
人人都是产品经理
人人都是产品经理
F
Fortinet All Blogs
J
Java Code Geeks
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
雷峰网
雷峰网
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
MongoDB | Blog
MongoDB | Blog
P
Privacy International News Feed
F
Full Disclosure
P
Proofpoint News Feed
B
Blog RSS Feed
T
Tor Project blog
T
The Blog of Author Tim Ferriss
B
Blog
Webroot Blog
Webroot Blog
腾讯CDC
T
Troy Hunt's Blog
T
Tailwind CSS Blog
H
Heimdal Security Blog
AWS News Blog
AWS News Blog
G
Google Developers Blog
Spread Privacy
Spread Privacy
NISL@THU
NISL@THU
A
About on SuperTechFans
SecWiki News
SecWiki News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
I
InfoQ
M
MIT News - Artificial intelligence
大猫的无限游戏
大猫的无限游戏
美团技术团队
L
LangChain Blog

qlAD 的技术笔记

2026 年 6 月 7 日 -- 我有社交恐惧症,恐惧外面到处雷电风雨声(大学生活记录) 手把手带你实现哈希表(C/C++ 数据结构) 手把手带你实现图结构(C/C++ 数据结构) 手把手带你实现二叉树(C/C++ 数据结构) 手把手带你实现栈和队列(C/C++ 数据结构) 手把手带你实现单/双链表(C/C++ 数据结构) 手把手带你实现动态数组(C/C++ 数据结构) 2026 年 1 月 2 日 -- 我不怕冷,因为我内心炽热 【2025 年度总结】(大学生活记录) 2025 年 12 月 2 日 -- 省电模式:大一 100 天耗电日志(大学生活记录) 蓝桥杯备赛第一期 —— 枚举与模拟 2025 年 11 月 3 日 -- 用爱发电、大爱无私(大学生活记录) 使用循环嵌套输出规则图形找规律讲解(嵌套循环-图形输出) 2025 年 10 月 1 日 -- 二字开头第一年的生日记录及感悟随笔(大学生活记录) Python 初级 04 -- 目前为止 Python 中你们做题可能会遇到的问题以及七七八八 2025 年 9 月 24 日 -- 开学后的第一课及军训汇演(大学生活记录) Python 初级 03 -- 程序设计的三种结构之选择结构和循环结构 Python 初级 02 -- 基础的数据类型和输入输出 2025 年 9 月 17 日 -- 大连 2025 国际大体联足球世界杯(大学生活记录) Python 初级 01 -- 初识编程、理解计算机语言及程序运行方式 适合大一新生学习编程的前一课 -- 编程先导(编程的本质) 2025 年 9 月 12 日 -- 三天军训感受以及一些七七八八(大学生活记录) 2025 年 9 月 9 日 -- 体检、军训前的准备(大学生活记录) 适合大一新生的计算机基础知识 -- 个人认为足够版 2025 年 9 月 7 日 -- 既来之、则安之(大学生活记录) C++ 程序的内存布局 —— 代码区、全局/静态区、栈区和堆区 联想小新 pro 16 2025 开箱记录:跳过联网、office 激活、更换 win 11 专业版 R 语言中的数学函数 计算机软件著作权申请过程记录 从聚类到回归:用 Python 解析鸢尾花数据集的完整数据科学流程 条件概率、全概率与贝叶斯公式 —— 一篇文章带你死磕概率公式 高中化学物质反应规则表 —— 方程式之间也有规律可循 集合元素性质、关系、子集公式、基本运算 —— 一篇文章带你全方面死磕集合 如何为你的项目选择合适的许可证 -- 全方位指南 解释 3:1 和 9:3:3:1 的详细来源 —— 建立减数分裂与孟德尔遗传学定律之间的联系 重新设置磁盘分区以及 Btrfs 子卷(subvolume)布局的无损方案 零基础实战:用 Docker 启动 dockermailserver 绕过 25 端口封锁搭建个人邮箱服务器 基于 GitHub Actions + OSS 的自托管 APT 仓库全面指南 如何在安装 Debian 时配置 Btrfs 子卷 | 详细分步指南 一个合格的个人网站站长应该知道哪些事? CSS 基础入门教程 —— 选择器、样式声明 HTML 基础入门 —— 基本结构和语法 给博客添加一个文章数据统计的页面 Git 学习笔记(命令备忘表) Anki 牌组选项详细解释与设置 手动编译带有 KernelSU 的 OnePlus 6 内核 安卓类原生系统补全计划 —— PixelExperience(一加 OnePlus) 如何使用 use-sound 为 React 应用添加声音效果 标准化项目的 GitHub Flow 工作流 如何搭建设计自己的博客网站? 使用安知鱼主题同款的 Twikoo 评论组件 配置 GitHub Actions 实现自动化提交百度收录 第00期 | 环境搭建 & 递归 (一) | 基本数列递归 2023 年回顾 🤟 Anki:记忆神器,助你高效学习 Gentoo 学习笔记 美化你的 PixelExperience OS Markdown 语法指南 搭建 OneDrive 目录索引 为什么用 65 表示大写字母 A
逐字符讲解 C 语言 HelloWorld 程序
qlAD · 2023-12-20 · via qlAD 的技术笔记

cover

C 语言往往是我们接触到的第一门语言,而 HelloWorld 往往又是我们第一次运行的代码,但是你真的了解 C 语言的 HelloWorld 吗?

#include <stdio.h>
// 我的第一个 C 语言程序
int main(int argc, char *argv[])
{
		printf("Hello, World! \n");
		return 0;
}

有的可能不写 return 0

有的可能会将返回参数从 int 写成 void

有的可能不写参数 ~~int argc, char *argv[]~~

以上是一个最标准的 C 语言 HelloWorld 代码,写法上的差异放在最后讲解

一、# 预处理

#预处理标示符,顾名思义是在编译之前执行的事情

以下为常见的预处理命令

指令描述
#define定义宏
#include包含一个源代码文件
#undef取消已定义的宏
#ifdef如果宏已经定义,则返回真
#ifndef如果宏没有定义,则返回真
#if如果给定条件为真,则编译下面代码
#else#if 的替代方案
#elif如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif结束一个 #if……#else 条件编译块
#error当遇到标准错误时,输出错误消息
#pragma使用标准化方法,向编译器发布特殊的命令到编译器中

1、#include

include 包含,#include 是一个预处理命令,用来 引入头文件,效果是直接把头文件的内容复制在代码上方,可减少代码量

2、.h 头文件

以 .h 为拓展名的是 C 语言的头文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享。

有两种类型的头文件:程序员编写的头文件和编译器自带的头文件。

要在程序中使用头文件,需要使用 C 预处理指令  #include  来引用它。

引用头文件的语法有以下两种

3、stdio.h 文件

  • std:代表符合 standard 标准
  • i:代表 input 输入
  • o:代表 output 输出

因此,stdio.h 是 C 语言标准库中的一个头文件,提供了标准输入输出的函数声明。

这个头文件是由 C 语言标准规定的,因此是编译器自带的标准头文件之一。

编译器自带的头文件放在 /usr/include/ 目录下

可以看到 printf 函数被定义在这个文件中

只有包含了 stdio.h 头文件才能使用 printf 函数


二、main() 函数

在 C 语言中,main 函数是程序的入口点,也是程序执行的起始位置。每个 C 程序都必须包含一个 main 函数。当程序运行时,操作系统调用 main 函数来启动程序的执行。

main 函数的基本形式如下:

int main(void)
{
// 代码块
    return 0; // 可选的返回值,表示程序成功结束
}

这里有一些关键点:

  1. 函数签名: main 函数的返回类型通常是整数类型,一般是 int。返回值可以用来指示程序的执行状态,一般约定 返回 0 表示程序成功结束,而其他值则表示错误或异常情况。

  2. 参数: main 函数可以接受两个参数,用于处理命令行参数。

    int main(int argc, char *argv[])
    {
        // 代码块
        return 0;
    }
    

    或者可以使用不带参数的形式:

    int main(void){
        // 代码块
        return 0;
    }
    

    注意,如果直接使用 int main() 在标准 C 中也是合法的,但有些编译器可能对参数的形式有一些要求。

    因此,如果你的编译器对带参数的 main 有特殊要求,可以选择使用 int main(void) 形式来明确表示不接受参数。

  3. 代码块: main 函数的主体包含了程序的实际执行代码。这是程序的主要逻辑所在。

  4. 返回值: return 0; 是可选的,但通常在 main 函数中使用,0 是程序正常的状态码,表示程序成功结束。其他非零的返回值通常用于指示程序异常结束或错误状态。

整个程序的执行流程是从 main 函数开始,然后按照代码中的逻辑依次执行,直至 main 函数的末尾。


三、本例中包含的 C 令牌(Token)

C 程序由各种令牌组成,令牌可以是关键字、标识符、常量、字符串值,或者是一个符号。例如,下面的 C 语句包括五个令牌:

printf("Hello, World! \n");
  1. printf:这是一个标识符(Identifier),表示调用的函数名。
  2. (:这是一个左圆括号,表示函数调用的开始。
  3. "Hello, World! \n":这是一个字符串常量,表示要被打印输出的字符串。
  4. ):这是一个右圆括号,表示函数调用的结束。
  5. ;:这是一个分号,表示语句的结束。

每个令牌在 C 语言中都有特定的含义和用途。这些令牌共同构成了一条 C 语句的结构。在上述例子中,printf 是一个函数调用语句,包含了一个字符串常量作为参数,然后以分号结束这条语句。

1、标识符

C 标识符 是用来标识 变量、函数,或任何其他用户自定义 项目的名称。一个标识符以字母 A-Z 或 a-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)。

C 标识符内不允许出现标点字符,比如 @、$ 和 %。C 是 区分大小写 的编程语言。因此,在 C 中,Manpower  和  manpower  是两个不同的标识符。下面列出几个有效的标识符:

mohd zara abc move_name a_123myname50 _temp j a23b9 retVal

2、分号

在 C 程序中,分号是 语句结束符。也就是说,每个语句必须以分号结束。它表明一个逻辑实体的结束。

例如,下面是两个不同的语句:

printf("Hello, World! \n");
return 0;

在没有分号的情况下,编译器将无法正确解析代码结构,因此分号是 C 语言中必不可少的语法元素。

3、注释

注释是用来提高代码可读性和维护性的工具,可以用于添加说明、临时禁用代码等。在编译时,注释的内容会被完全忽略。

在 C 语言中,有两种主要的注释形式,分别是单行注释和多行注释。

  • 单行注释

    使用 // 进行单行注释。在 // 出现的位置,其后的内容都被视为注释,直到该行结束。

    // 这是单行注释,这一行的内容都是注释
    int main()
    {
        // 这是 main 函数
        printf("Hello, world!\n"); 	// 这是打印语句
        return 0; // 返回 0 表示程序正常结束
    }
    
  • 多行注释

    使用 /* 开始注释块,使用 */ 结束注释块。注释块中的所有内容都被视为注释。

    /*这是多行注释*/
    int main()
    {
        /*
        这是 main 函数
        这是另一个注释块
        */
        printf("Hello, world!\n");	/* 这是打印语句 */
        return 0; /* 返回 0 表示程序正常结束 */
    }
    

多行注释不能嵌套使用,例如 /_ /_ 这是注释 _/ _/ 是不合法的。


四、转义字符

在 C 语言中,转义字符是一种特殊的字符序列,用于表示一些无法直接输入或打印的字符。转义字符以反斜杠(\)开头,后跟一个或多个字符。

转义字符的初衷是用于 ASCII 编码,所以它的取值范围有限:

  • 八进制形式的转义字符最多后跟三个数字,也即\ddd,最大取值是\177
  • 十六进制形式的转义字符最多后跟两个数字,也即\xdd,最大取值是\x7f

超出范围的转义字符的行为是未定义的,有的编译器会将编码值直接输出,有的编译器会报错。

不过,直接使用 ASCII 码记忆不方便,也不容易理解,所以,针对常用的控制字符,C 语言又定义了简写方式,完整的列表如下:

转义字符意义ASCII 码值(十进制)
\a响铃(BEL)007
\b退格(BS) ,将当前位置移到前一列008
\f换页(FF),将当前位置移到下页开头012
\n换行(LF) ,将当前位置移到下一行开头010
\r回车(CR) ,将当前位置移到本行开头013
\t水平制表(HT)009
\v垂直制表(VT)011
'单引号039
"双引号034
\反斜杠092

例如,本例中提到的 "Hello, World! \n" 中的 \n 表示换行符,使得在输出字符串后会在控制台中换行显示。


五、总结

  1. 包含头文件: #include <stdio.h> 表示引入标准输入输出库的头文件,其中包含了 printf 函数的声明。
  2. 注释: // 我的第一个 C 语言程序 是一个单行注释,用于提供对程序的简要描述。
  3. main 函数: int main(int argc, char *argv[]) 是程序的入口点。argc 表示命令行参数的数量,argv 是一个指向字符串数组的指针,存储了实际的命令行参数。
  4. printf 函数: printf("Hello, World! \n"); 是一个输出语句,它将字符串 “Hello, World!” 和一个换行符打印到标准输出设备(通常是控制台)。
  5. 返回值: return 0; 表示 main 函数成功执行并正常结束,返回值为 0。在 C 语言中,返回值为 0 通常表示程序成功执行。

这个程序的主要目的是输出 “Hello, World!” 到控制台,这是一个传统的、用于学习编程语言的入门示例。


六、争论写法上的差异问题

  • int main 还是 void main ?

    标准规定 main 函数返回一个整数值,通常用于指示程序的执行状态。返回值为 0 通常表示程序正常结束,而其他非零值则表示程序异常结束或错误状态。

    因此,正确的形式是:

    int main()
    {
        // 你的代码
        return 0;
    }
    

    不推荐使用 void main(),因为根据 C 语言标准,main 函数应该返回一个整数值。虽然有些编译器可能会接受 void main(),但这并不是标准的写法,可能导致不同编译器之间的兼容性问题。

  • 该不该写 main 函数的那两个参数?

    在 C 语言中,main 函数的标准形式是带有参数,即 int main(int argc, char *argv[])

    然而,如果你选择不写这两个参数,编译器通常也会接受。

    // 如本例中完全可以不写两个参数
    #include <stdio.h>
    int main()
    {
        printf("Hello, World!\n");
        return 0;
    }
    

    这个程序是合法的,并且在很多编译器中会正常工作。

    在这个特定的例子中,省略了 argcargv 参数,因为这个简单的程序没有使用命令行参数。

    在实际应用中,是否使用带参数的 main 函数取决于你的程序是否需要处理命令行输入。如果不需要,可以使用不带参数的形式。

  • 不写 return 0 会怎么样?

    按照约定,返回值为 0 表示程序正常结束,而其他非零值通常表示程序发生了错误或异常情况。如果省略 return 语句,编译器通常会 默认返回 0,但一些编译器可能会给出警告,因为这样的代码可能会让人误解程序的执行状态。

    在这个例子中,虽然缺少了 return 0;,但许多编译器仍然会默认认为程序正常结束,返回值为 0。然而,为了养成良好的编程习惯,强烈建议在 main 函数中使用 return 语句,以提高代码的清晰性和可读性。


原视频如下