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

news2024/11/23 18:39:59

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

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

 

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

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

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

—— 沃兹基硕德

📜 本章目录:

Ⅰ. 代码注释(Comment)

0x00 引入:注释的作用

0x01 块注释  /*   */

 0x02 行注释  //

0x03 保持注释的美观性

Ⅱ. 变量(Variable)

0x00 变量的声明

0x01 多变量声明

0x02 变量的初始化

0x03 多变量声明的初始化

0x04 变量的赋值

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

Ⅲ. 作用域(Scope)

0x00 引入:变量的作用域

0x01 全局变量和局部变量

0x02 局部变量优先原则

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

0x04 生命周期


Ⅰ. 代码注释(Comment)

0x00 引入:注释的作用

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

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

 

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

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

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

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

0x01 块注释  /*   */

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

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

/* 注释内容 */

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

#include <stdio.h>

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

	return 0;
}

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

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

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

 0x02 行注释  //

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

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

// 注释内容

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

#include <stdio.h>

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

	return 0;
}

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

#include <stdio.h>

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

	return 0;
}

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

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

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

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

/*  启动一个新的线程,运行一个从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 保持注释的美观性

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

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

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

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

Ⅱ. 变量(Variable)

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

0x00 变量的声明

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

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

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

数据类型 变量名;

💬 代码演示:定义变量

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

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

0x01 多变量声明

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

变量类型 变量1, 变量2, 变量3... ;

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

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

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

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

#include <stdio.h>

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

    return 0;
}

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

0x02 变量的初始化

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

数据类型 变量名 = 初始值;

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

int a = 0;   // 设置初始值
int b;       // 不推荐

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

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

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

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

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

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

#include <stdio.h>

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

    return 0;
}

 🚩 运行结果:error

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

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

int a = 0;
char c = 0;
float f = 0.0;
double d = 0.0;

0x03 多变量声明的初始化

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

int i = 0;
int j = 0;
int k = 0;

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

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

int i = 0, j = 0, k = 0;

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

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

int main(void)
{
    int i, j, k = 0;

    return 0;
}

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

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

0x04 变量的赋值

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

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

int a;
a = 10;

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

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

int b = 0;   // 定义变量并初始化
b = 10; 

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

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

#include <stdio.h>

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

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

    return 0;
}

🚩 运行结果如下:

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

#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 变量重定义引发的报错

 我们先看看下面的代码:

#include <stdio.h>

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

    int b = 10;
    int b = 20;

    return 0;
}

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

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

Ⅲ. 作用域(Scope)

0x00 引入:变量的作用域

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

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

0x01 全局变量和局部变量

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

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

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

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

#include <stdio.h>

int A = 10;       // 全局变量

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

    return 0;
}

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

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

0x02 局部变量优先原则

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

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

#include <stdio.h>

int var = 100;     // 全局变量

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

    return 0;
}

🚩 运行结果如下:

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

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

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

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

#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)。

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

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

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

#include <stdio.h>

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

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

🚩 运行结果:(报错)

📌 [ 笔者 ]   王亦优 | 雷向明
📃 [ 更新 ]   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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/786769.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL的约束

目录 1.约束&#xff08;constraint&#xff09;的概述 2.约束的分类 1.约束的字段的个数: 2.约束的作用范围: 3.约束的作用/功能 3.如何添加约束 4.如何查看约束 5.非空约束&#xff08;not null&#xff09; 6.唯一性约束&#xff08;unique&#xff09; 7.主键约…

赛多利斯Sartorius天平java后端对接

业务场景 要将赛多利斯天平的数据读出来解析并且显示到对应的数字框,支持一台设备连接多种精度的天平 后端实现 通过协议解析数据,然后将数据存储 详细代码就不贴了,感兴趣的可以私聊我

区间预测 | MATLAB实现基于Bootstrap的区间预测

区间预测 | MATLAB实现基于Bootstrap的区间预测 目录 区间预测 | MATLAB实现基于Bootstrap的区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 区间预测 | MATLAB实现基于Bootstrap的区间预测 MATLAB实现基于Bootstrap区间预测&#xff08;完整源码和数据&…

被大厂抢着要,最终拿到20k的高薪offer

被大厂抢着要&#xff0c;各个大企业为留住自己不断给自己加薪&#xff0c;这种只在梦中见过的场景&#xff0c;真实的发生在黑马学长身上了&#xff01; 周同学&#xff0c;刚毕业后便从事的IT行业&#xff0c;但 2 年以来&#xff0c;工作一直没有什么起色&#xff0c;为了跳…

Redis高级篇(二)

Redis高级篇之多级缓存 什么是多级缓存 JVM进程缓存 Lua语法入门 实现多级缓存 缓存同步 一、什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后&#xff0c;先查询Redis&#xff0c;如果未命中则查询数据库&#xff0c;如图&#xff1a; 存在下面的问题&#xff1a;…

React 框架下自己写一个braft编辑器,然后将编辑器内容展示在网页端

1.首先自己写一个编辑器 输入文字&#xff1b; 支持选择表情&#xff1b; 可添加小程序链接&#xff1b;可添加网页链接&#xff1b;并且可以编辑删除&#xff1b;效果如下 2.输入完毕后&#xff0c;点击文本输入框保存&#xff0c;将便携式内容回显&#xff0c; 渲染时…

python中——requests爬虫【中文乱码】的3种解决方法

requests是一个较为简单易用的HTTP请求库&#xff0c;是python中编写爬虫程序最基础常用的一个库。 而【中文乱码】问题&#xff0c;是最常遇到的问题&#xff0c;对于初学者来说&#xff0c;是很困恼的。 本文将详细说明&#xff0c;python中使用requests库编写爬虫程序时&…

List集合类详解(附加思维导图)

目录 一、List集合思维导图 二、List集合类的常见方法 2.1、ArrayList集合常用方法 2.2、LinkedList集合常用方法 一、List集合思维导图 二、List集合类的常见方法 2.1、ArrayList集合常用方法 ①.add(Object element) 向列表的尾部添加指定的元素。 ②.size() 返回列表中…

前端vue部署到nginx并且配置https安全证书全流程

说明一下&#xff1a; 本人原本使用的是docker安装nginx通过挂载实现部署&#xff0c;但是出现了很多bug&#xff08;例如部署安全证书后还是无法访问&#xff09;&#xff0c;所以困扰了很久&#xff0c;最后改为本地安装nginx&#xff0c;最终在不懈的努力下终于按照好了&…

H5页面 卡片 分享朋友圈和好友

项目背景&#xff1a; 前后端分离&#xff1a; 后端&#xff1a; C# 开发 前端&#xff1a; 就是微信中打开的 H5页面 纯 H5 业务流程&#xff1a; 因为在 h5 中实现 卡片分享 的一个字段, 需要后端 访问 腾讯API 生成&#xff0c;所以整个分享结构和流程就比较长&#xff…

Stable diffusion 和 Midjourney 怎么选?

通过这段时间的摸索&#xff0c;我将和你探讨&#xff0c;对普通人来说&#xff0c;Stable diffusion 和 Midjourney 怎么选&#xff1f;最重要的是&#xff0c;学好影视后期制作对 AI 绘画创作有哪些帮助&#xff1f;反过来&#xff0c;AI 绘画对影视后期又有哪些帮助&#xf…

Python案例变量实践

编程&#xff1a;非常需要实践&#xff0c;不要光看&#xff0c;一定要动动手 什么是程序&#xff1f; 数据结构算法 数据结构&#xff1a;存储和使用数据的方式 算法&#xff1a;解决问题的步骤 解决一个问题的时候&#xff0c;分析问题&#xff0c;设计算法&#xff0c;编…

网约车服务端线上流量巡检与测试验收技术

摘要 滴滴网约车致力于让出行更美好&#xff0c;平台为司乘提供良好体验的同时承载了广大群众的出行服务&#xff0c;致使我们对服务可用性的要求较高。更快地发现系统bug&#xff0c;可以让更少的司乘用户受影响。发现bug的能力更精细&#xff0c;可以让一些不易被用户感知但…

2D坐标系下的点的转换矩阵(平移、缩放、旋转、错切)

文章目录 1. 平移 &#xff08;Translation&#xff09;2. 缩放 &#xff08;Scaling&#xff09;3. 旋转 &#xff08;Rotation&#xff09;4. 错切 &#xff08;Shearing&#xff09;5. 镜像 &#xff08;Reflection&#xff09; 1. 平移 &#xff08;Translation&#xff09…

Nautilus Chain:主权模块化区块链的早期实践

“Nautilus Chain 是目前行业内首个以模块化的方式构建的主权 Layer3 区块链系统&#xff0c;其也是 Celestia 模块化 Layer0 体系下最早的印证者&#xff0c;现在 Nautilus Chain 主网正式上线&#xff0c;揭示着模块化区块链正在从早期的理论阶段走向实践。” Celestia &…

Godot 4 源码分析 - 获取属性信息

在管道通信基础上&#xff0c;可进行宿主程序与Godot的双向通信。 先拿属性信息试试手。 DrGraph端 static UnicodeString command "Book.position"; if (InputQuery("输入窗口", "请输入待获取的属性信息", command)) {TDrStream_Get drGet…

5.10 Bootstrap 按钮(Button)插件

文章目录 Bootstrap 按钮&#xff08;Button&#xff09;插件加载状态单个切换复选框&#xff08;Checkbox&#xff09;单选按钮&#xff08;Radio&#xff09;用法选项方法 Bootstrap 按钮&#xff08;Button&#xff09;插件 按钮&#xff08;Button&#xff09;在 Bootstrap…

forEach遍历访问set造成的无限循环问题

抛出问题 先给出一段代码&#xff0c;我们创建了一个集合set&#xff0c;它里面有一个元素数字1和2&#xff0c;接着我们调用forEach方法来遍历该集合。在遍历函数中&#xff0c;首先调用delete方法删除数字1&#xff0c;再执行了某些业务操作后紧接着调用add方法将数字1加回&…

Linux系统root用户切换及密码修改

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

2023 年第二届钉钉杯大学生大数据挑战赛 初赛 B:美国纽约公共自行车使用量预测分析 问题二Python代码分析

2023 年第二届钉钉杯大学生大数据挑战赛 初赛 B&#xff1a;美国纽约公共自行车使用量预测分析 问题二 相关链接 【2023 年第二届钉钉杯大学生大数据挑战赛】 初赛 B&#xff1a;美国纽约公共自行车使用量预测分析 问题一Python代码分析 【2023 年第二届钉钉杯大学生大数据挑…