【C语言趣味教程】代码注释:小孩子才做选择,我全都要

【C语言趣味教程】(4) 变量:代码注释 | 变量的声明 | 初始化与赋值 | 作用域与生命周期 | 局部变量与全局变量

🔗 《C语言趣味教程》👈 猛戳订阅!!!

​**------ 热门专栏《维生素C语言》的重制版 ------**

  • 💭 写在前面: 这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人一贯的幽默式写作风格,当然,在有趣的同时也同样会保证文章的质量,旨在能够产出 "有趣的干货" !本系列教程不管是零基础还是有基础的读者都可以阅读,可以先看看目录! 标题前带星号 (*) 的部分不建议初学者阅读,因为内容难免会超出当前章节的知识点,面向的是对 C 语言有一定基础或已经学过一遍的读者,初学者可自行选择跳过带星号的标题内容,等到后期再回过头来学习。值得一提的是,本专栏 强烈建议使用网页端阅读! 享受极度舒适的排版!你也可以展开目录,看看有没有你感兴趣的部分!希望需要学 C 语言的朋友可以耐下心来读一读。最后,可以订阅一下专栏防止找不到。

" 有趣的写作风格,还有特制的表情包,而且还干货满满!太下饭了!"

------ 沃兹基硕德

📜 本章目录:

[Ⅰ. 代码注释(Comment)](#Ⅰ. 代码注释(Comment))

[0x00 引入:注释的作用](#0x00 引入:注释的作用)

[0x01 块注释 /* */](#0x01 块注释 /* */)

[0x02 行注释 //](#0x02 行注释 //)

[0x03 保持注释的美观性](#0x03 保持注释的美观性)

[Ⅱ. 变量(Variable)](#Ⅱ. 变量(Variable))

[0x00 变量的声明](#0x00 变量的声明)

[0x01 多变量声明](#0x01 多变量声明)

[0x02 变量的初始化](#0x02 变量的初始化)

[0x03 多变量声明的初始化](#0x03 多变量声明的初始化)

[0x04 变量的赋值](#0x04 变量的赋值)

[0x05 变量重定义引发的报错](#0x05 变量重定义引发的报错)

[Ⅲ. 作用域(Scope)](#Ⅲ. 作用域(Scope))

[0x00 引入:变量的作用域](#0x00 引入:变量的作用域)

[0x01 全局变量和局部变量](#0x01 全局变量和局部变量)

[0x02 局部变量优先原则](#0x02 局部变量优先原则)

[0x03 利用大括号限制变量作用域](#0x03 利用大括号限制变量作用域)

[0x04 生命周期](#0x04 生命周期)


Ⅰ. 代码注释(Comment)

0x00 引入:注释的作用

"程序员最讨厌两种人:一种是不写注释的人,一种是让我写注释的人。"

相信大家对注释早已有所耳闻,对于注释,C 语言有两种注释风格,我们下面会逐个讲解。

但在这之前,我们先来了解了解注释的作用,注释就是用于解释代码的文字的。

注释通常用于版本、版权声明,函数接口说明,重要的的代码行或段落提示。

它的存在能够有效提高代码的阅读性,注释不仅仅是给别人看的,也是给自己看的!

特别是写项目的时候。不写注释,几天后可能自己都不知道自己写了什么......

0x01 块注释 /* */

块注释是 C 语言风格的注释,是一对 "斜杠星号"。

内容判定范围为从 /* 开始 到 */ 结束,是成对判定的。

cpp 复制代码
/* 注释内容 */

它可以注释一行内容,也可以注释多行内容:

cpp 复制代码
#include <stdio.h>

int main(void) 
{
	printf("你好!");   /* 打印你好 */

	return 0;
}

/*
	这是一套 C 语言趣味教学专栏,
	目前正在火热连载中,
	欢迎猛戳订阅!本专栏保证篇篇精品,
	继续保持本人一贯的幽默式写作风格,
	当然,在有趣的同时也同样会保证文章的质量,
	旨在能够产出 "有趣的干货" !
*/  int a;

最后的 int a 自然不在注释范围内,判定范围为从 /* 开始 到 */ 结束:

📌 注意: 块注释不能嵌套注释:warning C4138: 在注释外找到"*/" error C2059: 语法错误:"/

0x02 行注释 //

行注释是 C++ 风格的注释,是两个斜杠。

内容判定范围从 // 开始到本行结束:

cpp 复制代码
// 注释内容

行注释是非常方便快捷的,只需要在语句后面随手加两个斜杠就行:

cpp 复制代码
#include <stdio.h>

int main(void) 
{
	printf("你好!");   // 打印你好

	return 0;
}

行注释是支持嵌套注释的,比如我们想把这里的 printf 这行注释掉:

cpp 复制代码
#include <stdio.h>

int main(void) 
{
	// printf("你好!");   // 打印你好

	return 0;
}

❓ 那到底哪种注释风格好呢?

行注释和块注释 这两种注释风格并无好坏之分,可以混合使用。

在需要写大量说明的地方使用块注释(比如写函数功能),行内代码可以用行注释,方便快捷。

程序块注释常采用 /* */ ,行注释一般采用 //,举个例子:

cpp 复制代码
/*  启动一个新的线程,运行一个从FILENAME加载的用户程序。
 *  FILENAME中加载的用户程序。 这个新的线程可以在
 *  process_execute()返回之前被安排(甚至可以退出)
 *  在process_execute()返回之前。 返回新进程的
 *  线程ID,如果不能创建线程,则返回TID_ERROR。
 */
tid_t process_execute (
	const char *file_name     /* FILENAME 加载的程序 */
	)
{
	tid_t tid;                      // 记录线程ID 
	struct file *FILE = NULL;       // 创建file指针,用于 filesys_open 
	char* palloc_file_name = NULL;  // FILENAME 
	char* strtok_tmp;               // 临时存储FILENAME 
	char* ptr;                      // 用于字符串分割函数 

/*  这里创建一个FILE_NAME的副本,是为了阻止调用者与load()发生线程竞争。
 *  tips: 同一个进程中的线程能够共享进程中的绝大多数资源,当它们进行随意的竞争时,
 *  就会导致共享的资源被破坏、脏数据、不完整、不一致等问题。
 */
    // 创建一个FILENAME的副本,从用户或内核内存池中获取页 
	char* fn_copy = palloc_get_page (0);    
  	if (fn_copy == NULL) {                // 如果是空页,就返回线程ID错误信息
		return TID_ERROR;
	}

0x03 保持注释的美观性

在使用行注释时,我们一般习惯在 // 后面加一个空格,因为这样可能会更加美观:

在使用块注释写大量内容时,可以在每行都加上星号:

当然,这些归根结底都是按照个人习惯来。

就像小学学方程写未知数 时,老师并不会强制要求你怎么写。

Ⅱ. 变量(Variable)

  • 在讲解整型的章节中,我们已经对变量有一个简单的介绍了。本章我们将详细介绍变量,并且引入常量的知识点。

0x00 变量的声明

变量 (variable),顾名思义就是 "可以变的量"。

我们说过,C 语言的变量是由明确类型的,创建一个变量需要明确该变量的类型。

变量的声明方式有两种,第一种就是我们在前几章介绍的,通过 类型 + 变量名 定义一个变量:

cpp 复制代码
数据类型 变量名;

**💬 代码演示:**定义变量

cpp 复制代码
#include <stdio.h>
 
int main()
{
    int age;
    float height;
    double weight;
 
    return 0;
}

这种方式一行只定义一个变量,是最常见且推荐的变量声明方式。

0x01 多变量声明

C 语言还支持 多变量声明 ,即一行同时定义多个变量,类型 + 变量1, 变量2...

cpp 复制代码
变量类型 变量1, 变量2, 变量3... ;

多变量声明时,变量和变量之间用逗号 ; 分隔。

使用多变量声明就意味着这一行要定义的变量的类型是相同的。

换句话来说,如果我们定义变量的类型都相同,我们就可以使用多变量声明一次定义多个变量。

**💬 代码演示:**使用多变量声明定义变量

cpp 复制代码
#include <stdio.h>

int main()
{
    int a, b, c, d;  // 同时定义变量 abcd

    return 0;
}

多变量声明还有更多的细节,我们稍后讲解完变量的初始化后再做探讨。

0x02 变量的初始化

变量 初始化 (initialization),就是在定义变量的同时给变量设置一个初始值,我们称为 "赋初值"。

cpp 复制代码
数据类型 变量名 = 初始值;

建议在定义变量时给变量设置初始值,虽然不赋值也是允许的,但是我们不建议这么做!

cpp 复制代码
int a = 0;   // 设置初始值
int b;       // 不推荐

比如我们定义整型变量 a,我们在定义的时候就随手给它设为 0,这就完成了赋初值的工作。

**❓ 思考:**如果不设置初始值会怎么样?

如果定义变量没有初始化,那么变量有可能赋值,有可能没赋值。

如果定义的变量是局部变量,那么 编译器可能会给没赋值的初始变量赋一个 "随机值"。

不仅如此,如果你强行 printf 打印 a,会引来报错:error C4700: 使用了未初始化的局部变量"a"

**💬 代码演示:**打印未初始化的变量

cpp 复制代码
#include <stdio.h>

int main()
{
    int a;
    printf("%d\n", a);

    return 0;
}

🚩 运行结果:error

所以我们需要培养一个好的编程习惯,在定义变量的同时,就给变量初始化。

并且我们 "习惯" 给变量初始值设为 0,下面给一些例子:

cpp 复制代码
int a = 0;
char c = 0;
float f = 0.0;
double d = 0.0;

0x03 多变量声明的初始化

我们先来看下面的初始化,这是常规的初始化方法,创建变量 i, j, k 并初始化为 0。

cpp 复制代码
int i = 0;
int j = 0;
int k = 0;

现在 i, j, k 变量的值都为 0 了,我们刚才说了,C 语言支持多变量类型。

如果我们想达到相同的效果,多变量声明的初始化方式如下:

cpp 复制代码
int i = 0, j = 0, k = 0;

这样,我们的 i, j, k 的值在定义的同时就初始化为 0 了。

**📌 注意:**我们来看下面这种初始化方式

cpp 复制代码
int main(void)
{
    int i, j, k = 0;

    return 0;
}

🚩 运行结果如下:(弹出 warning)

如果这么写,那么只有 k 设置了初始值 0,而 i 和 j 是没有初始化的。

0x04 变量的赋值

给已经定义的变量设置一个值,或重新设置一个值,称为 赋值(assignment) 。

如果我们在定义变量的时候没有给上初始值,我们可以在变量定义后给它赋上一个值:

cpp 复制代码
int a;
a = 10;

通过赋值后,此时变量 a 就有值了。

当然,变量在定义的时候就完成初始化了,此时我们也可以给变量赋上一个新值:

cpp 复制代码
int b = 0;   // 定义变量并初始化
b = 10; 

我们给 b 赋值后,此时变量 b 的值不是初始化给的 0 了,而是 10 了。

**💬 代码演示:**赋值前和赋值后

cpp 复制代码
#include <stdio.h>

int main(void)
{
    int a = 0;
    printf("赋值前: %d\n", a);

    a = 10;
    printf("赋值后: %d\n", a);

    return 0;
}

🚩 运行结果如下:

当然,也是支持多变量赋值的:

cpp 复制代码
#include <stdio.h>

int main(void)
{
    int a = 0, b = 0, c = 0;
    printf("赋值前: %d %d %d\n", a, b, c);

    a = 10, b = 20, c = 30;
    printf("赋值后: %d %d %d\n", a, b, c);

    return 0;
}

🚩 运行结果如下:

0x05 变量重定义引发的报错

我们先看看下面的代码:

cpp 复制代码
#include <stdio.h>

int main(void)
{
    int a;
    int a;

    int b = 10;
    int b = 20;

    return 0;
}

可以看到,变量 a 和 b 定义了两次,这在 C 语言中是明令禁止的,引发 重定义问题

会引发如下报错:error C2086: "int a": 重定义,error C2374: "b": 重定义;多次初始化

Ⅲ. 作用域(Scope)

0x00 引入:变量的作用域

变量和常量在程序中都是有作用范围的,这个范围我们称之为变量的 作用域(scope) 。

(常量的概念我们下一章讲解)变量的作用域又可以分为全局作用域局部作用域

0x01 全局变量和局部变量

在函数内部声明或定义的变量称之为 全局变量 (global variable) 。

全局变量的作用域在整个工程。

在函数内部声明或定义的变量称为 局部变量 (local variable) 。

局部变量的作用域仅在该函数的内部,出了函数就无效。

cpp 复制代码
#include <stdio.h>

int A = 10;       // 全局变量

int main(void)
{
    int a = 20;   // 局部变量

    return 0;
}

❓ 如何快速分辨全局变量和局部变量?最简单的方法就是看大括号!

  • 大括号外部定义的变量叫做 全局变量
  • 大括号内部定义的变量叫做 局部变量

0x02 局部变量优先原则

当局部变量和全局变量的名字相同时,局部变量优先。

**💬 代码演示:**局部变量优先

cpp 复制代码
#include <stdio.h>

int var = 100;     // 全局变量

int main(void)
{
    int var = 10;  // 局部变量
    printf("%d\n", var);

    return 0;
}

🚩 运行结果如下:

0x03 利用大括号限制变量作用域

使用大括号可以限制一个变量的作用域,在大括号内的变量就是局部变量。

其作用范围仅仅在这个打括号内,出了这个大括号就无效。

**💬 代码演示:**使用大括号限制变量的作用域

cpp 复制代码
#include <stdio.h>

int main(void)
{
    int a = 0;
    {
        int a = 10;
        printf("大括号内 a 的值:%d\n", a);
    }
    printf("大括号外 a 的值:%d\n", a);

    return 0;
}

🚩 运行结果如下:

这里仍然遵循局部变量优先原则,局部变量优先。

0x04 生命周期

变量创建和销毁之间的时间段,称为 生命周期 (Life Cycle)。

全局变量的生命周期和局部变量的生命周期是不同的:

  • 全局变量:整个程序的生命周期。
  • 局部变量:进入作用于生命周期开始,出了作用域生命周期结束。

**💬 代码演示:**局部变量的生命周期

cpp 复制代码
#include <stdio.h>

int main(void)
{
    {
        int a = 10;
        printf("%d\n", a);
    }   

    printf("%d\n", a);  // 出了作用域了
}

🚩 运行结果: (报错)

cpp 复制代码
📌 [ 笔者 ]   王亦优 | 雷向明
📃 [ 更新 ]   2023.7.10
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
              本人也很想知道这些错误,恳望读者批评指正!

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 📜 参考文献: - C++reference[EB/OL]. []. http://www.cplusplus.com/reference/. - Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . - 百度百科[EB/OL]. []. https://baike.baidu.com/. - 维基百科[EB/OL]. []. https://zh.wikipedia.org/wiki/Wikipedia - R. Neapolitan, Foundations of Algorithms (5th ed.), Jones & Bartlett, 2015. - B. 比特科技. C/C++[EB/OL]. 2021[2021.8.31] - 林锐博士. 《高质量C/C++编程指南》[M]. 1.0. 电子工业, 2001.7.24. - 陈正冲. 《C语言深度解剖》[M]. 第三版. 北京航空航天大学出版社, 2019. - 侯捷. 《STL源码剖析》[M]. 华中科技大学出版社, 2002. - T. Cormen《算法导论》(第三版),麻省理工学院出版社,2009年。 - T. Roughgarden, Algorithms Illuminated, Part 1~3, Soundlikeyourself Publishing, 2018. - J. Kleinberg&E. Tardos, Algorithm Design, Addison Wesley, 2005. - R. Sedgewick&K. Wayne,《算法》(第四版),Addison-Wesley,2011 - S. Dasgupta,《算法》,McGraw-Hill教育出版社,2006。 - S. Baase&A. Van Gelder, Computer Algorithms: 设计与分析简介》,Addison Wesley,2000。 - E. Horowitz,《C语言中的数据结构基础》,计算机科学出版社,1993 - S. Skiena, The Algorithm Design Manual (2nd ed.), Springer, 2008. - A. Aho, J. Hopcroft, and J. Ullman, Design and Analysis of Algorithms, Addison-Wesley, 1974. - M. Weiss, Data Structure and Algorithm Analysis in C (2nd ed.), Pearson, 1997. - A. Levitin, Introduction to the Design and Analysis of Algorithms, Addison Wesley, 2003. - A. Aho, J. - E. Horowitz, S. Sahni and S. Rajasekaran, Computer Algorithms/C++, Computer Science Press, 1997. - R. Sedgewick, Algorithms in C: 第1-4部分(第三版),Addison-Wesley,1998 - R. Sedgewick,《C语言中的算法》。第5部分(第3版),Addison-Wesley,2002 |

相关推荐
安步当歌5 小时前
【FFmpeg】av_write_trailer函数
c语言·c++·ffmpeg·视频编解码·video-codec
HanLop7 小时前
C语言-动态内存管理
c语言·开发语言
EthanWsir7 小时前
嵌入式C语言面试相关知识——关键字(不定期更新)
c语言·开发语言·面试
我们的五年8 小时前
【算法:贪心】:贪心算法介绍+基础题(四个步骤);柠檬水找零(交换论证法)
c语言·数据结构·c++·算法·贪心算法
龙迅代理(jiuli)9 小时前
LT8711GX 国产芯片 Type-C/DP1.4转HDMI2.1 用于加密狗 对接站
c语言·开发语言
鞥牧魂人11 小时前
C-I-O和多线程
c语言·c++·算法
qq_4597300311 小时前
C语言编程与进阶
c语言·开发语言·51
阿飞不修电脑12 小时前
《Linux开发笔记》C语言编译
c语言·开发语言·笔记
我要升天!13 小时前
二叉树节点个数(C语言)
c语言·开发语言
hinewcc13 小时前
Linux内核链表使用方法
linux·c语言·arm开发·链表