撰写了文章 更新于 2020-01-13 11:35:14
《程序编写 编程入门 - C/C++》(二)元素与编写风格
本系列收藏夹 https://cowlevel.net/collection/3932815
爱发电!https://afdian.net/@kingfeng
在这一部分,我将介绍代码的组成、拼装方式,讲述什么是程序的“语言”。阅读完这篇文章,你将可以简单的看懂一个程序的结构。
基本元素
标识符
代码中大部分的内容都属于标识符,标识符实际上是一系列名字,例如函数的名字、类型的名字、变量的名字。而程序员所做的工作,即是描述与处理标识符之间的关系。
关键字
关键字是编程语言所提供给程序员可使用的一系列词汇,他有程序语言所决定,描述基本的逻辑结构、定义关键字 或 提供一些基本的功能。
符号
在大部分语言中,标识符和关键字囊括了所有的字母内容,而剩下的则是一系列符号。符号起到分割或连接的作用,他们或围绕着一些文字,或把一些关键字连接起来。
样例
说了这么多,或许有些难懂,我们需要列举一些例子
video.c
static unsigned int get_entry(void)
{
char entry_buf[4];
int i, len = 0;
int key;
unsigned int v;
do {
key = getchar();
if (key == '\b') {
if (len > 0) {
puts("\b \b");
len--;
}
} else if ((key >= '0' && key <= '9') ||
(key >= 'A' && key <= 'Z') ||
(key >= 'a' && key <= 'z')) {
if (len < sizeof(entry_buf)) {
entry_buf[len++] = key;
putchar(key);
}
}
} while (key != '\r');
putchar('\n');
if (len == 0)
return VIDEO_CURRENT_MODE; /* Default */
v = 0;
for (i = 0; i < len; i++) {
v <<= 4;
key = entry_buf[i] | 0x20;
v += (key > '9') ? key-'a'+10 : key-'0';
}
return v;
}
等。。等一下,这么多? 好吧好吧,让我们慢慢来分析,你不需要真正的“记住”什么知识,相对的我希望你能理解程序的结构和代码是怎么被拼装起来的 需要注意,这并不是代码编写或者阅读技巧,而仅仅是来说明关键字是如何把不同的名称组合起来的
首先,从前面来看 看起来是四个词语和一个括号,但当我们覆盖掉所有关键字的时候
static unsigned int get_entry(void)
关键字 关键字 关键字 get_entry (关键字)
char entry_buf[4];
关键字 entry_buf [4]
int i, len = 0;
关键字 i, len = 0
int key;
关键字 key;
unsigned int v;
关键字 关键字 v;当我们忽略最开始的括号(我会在这篇文后续具体讲述详细的语法) 这些句子实际上是使用一系列 关键字 来定义一系列 标识符,有点类似于倒装 这些代码表示了 标识符 是 关键字, 例如 名字 key 是 int, 名字 v 是 unsigned int。这些名字由程序员命名,关键字则是编程语言规范所定义的。
接下来,我们看到了一个 do 关键字,用来描述一个循环但这不重要,同样具体的语法我们会在后续文章讲述
循环 {
key = getchar();
....
} 条件是(key != '\r');以及一个 if 关键字,这是用来判断的
如果 (key == '\b') {
如果 (len > 0) {
puts("\b \b");
len--;
}
} 否则如果 ( (key >= '0' && key <= '9') ||
(key >= 'A' && key <= 'Z') ||
(key >= 'a' && key <= 'z')) {
如果 (len < 获取大小(entry_buf)) {
entry_buf[len++] = key;
putchar(key);
}
}
我们可以看到,在知道关键字的意思之后,所看到的内容逐渐的有了条理性。
从 key = getchar(); 开始,根据名字我们可以推测, 变量 key 从 getchar 函数获取一个值,在字面上意义来讲,这个函数是 “获取一个字符”,我们把获取到的字符给 key。
而后我们经历了一系列的判断, 是针对 key 的,我们遇到了第二个问题,引号。 在C语言中,单引号所包括的是一个字符,而双引号所包括的是一个字符串,一个等于号是赋值,两个等于号是比较两个东西是否相等
把这一段判断浏览过后,你应该发现了,他们都是针对key的比较,因此我们推测这些代码的功能是 根据 key 也就是我们从某个地方获取的字符 具体是什么 来做出不同的反应或执行不同的动作。
走出了 while 部分后,除了一行独立的 putchar 从字面意思看来是把一个字符 推 到什么地方,又是一个if判断 和一个 for循环 但是我们看到了 return 返回,这是我们之前没提到的关键字。他的作用是当执行完一个函数后,会返回一个什么东西作为函数的 “值” 就像一个变量一样,然后这个函数就会结束。
我们在这里看到了两个 return 分别是 VIDEO_CURRENT_MODE 和 v,其中VIDEO_CURRENT_MODE 后还写着 /* Default */ 这是“注释”也就是编写代码的程序员写给阅读这段代码的你看的,如果 len 是 0 那么这段函数会返回 *视频通用模式*,虽然我们并不知道这是个啥, 而注释还告诉了我们,这是默认的返回值。然后会结束这段代码
如果 len 不为零呢,就需要进入下面的循环进行一些数学运算,你可以看到循环内没有关键字,只有一系列运算和赋值符号。但最后,我们返回了v的结果 本质上这和常见的例子“传入两个数字返回他们的和” 没有区别,只不过一个是加减一个是比微积分更复杂的什么东西。
看到这里,我相信你对关键字、标识符、符号 再代码中是如何分布的,有了一个感官上的认识,虽然这种认识还并不足以让你能“写”出什么来,我们并没有提到括号,但括号和数学上理解的差不多,用来把一些零散的东西包起来。
那么我们真正看看一些有用的知识
关键字
再C++中,一共提供了六十余个关键字,大体上分为 流程控制、数据类型、修饰、常用功能。我会将常用的部分添加星号 在这里的内容,虽然不需要立刻牢记,但最终这些是你编程所能用到的最基本的元素而你最终也会熟悉他们。当你见到了这些词汇,如果忘记了他的含义,大可去搜索或者把这些加入书签,在需要的时候回来看看
流程控制
在前文中我们已经提到的包括 if for do 等等即属于这类,他们在代码中起到控制程序走向或者控制程序流程的功能 其包括
- 判断 : switch .. case .. default, if .. else
- 循环 : for,do .. while,continue
- 跳转 : break,goto
- 错误处理 : try .. throw .. catch
在后续的文章中,我们会依次介绍这些关键字,他们的语法和功能。
数据类型
数据类型则是声明了各种语言所提供的基本存储方案,包括
- auto 自动
- bool 布尔 *
- char 字符 *
- class 类 *
- double 双精度 *
- enum 枚举 *
- float 单精度 *
- int 整数 *
- long 长整形 *
- namespace 命名空间 *
- register 寄存器
- short 短整形 *
- struct 结构 *
- template 模板
- union 联合
- void 空 *
- wchar_t 宽字符
在下一篇文章中,我将结合函数来讲解这些数据类型的具体含义和什么时候使用他们
修饰
修饰类似与一种形容词,一般是在某些场合下,为一段代码增加特殊属性或含义。通常需要结合其他关键字来使用
| 关键字 | 含义 | 功能 |
|---|---|---|
| const | 常量 | 来描述对象不能再程序中被改变 * |
| explicit | 显式的 | 用以阻止类的自由转换 |
| export | 导出 | 用于代码间共享一个模板对象 |
| extern | 外部的 | 用以代码间共享一个对象 |
| friend | 友元 | 用以修饰类 * |
| inline | 内联 | 描述一个函数在编译时展开 * |
| mutable | 可变的 | 修饰类中的某个变量永远是可变的 |
| private | 私有的 | 这三种修饰符分别表明 * |
| protected | 被保护的 | 一个类中的元素的访问权限 * |
| public | 公共的 | 限制了该元素如何读取或修改 * |
| long | 长 | 定义变量类型为长变量 * |
| short | 短 | 定义变量类型为短变量 * |
| signed | 有符号的 | 定义变量可拥有正负号 * |
| unsigned | 无符号的 | 定义变量只可为负 * |
| signed | 有符号的 | 定义变量可拥有正负号 * |
| using | 使用 | 表明对一个namespace命名空间的使用 * |
| virtual | 虚的 | 实现C的多态机制 * |
| volatile | 不稳定的 | 表明一个对象可以被外部因素更改 |
常用功能 / 符号
在关键字中,除了以上列举出来有语法地位的部分之外,还包括一些经常使用、特殊含义或涉及软件安全的功能,关键字中提供了这些功能为程序员使用
- asm - 在程序中嵌入汇编代码
- const_cast - 修改类型的const以及volatile
- new、delete - 用以申请和清理动态的内存空间 *
- dynamic_cast、static_cast - 用以实现类之间的安全转换
- extern "C" - 在C++程序中声明一段 需要使用C编译器的代码
- true、false - 用以表明一个布尔类型的真或假 *
- operator - 重载运算符 *
- reinterpret_cast - 用以处理不相关类型的转换
- sizeof - 获取一个对象占用的内存大小 *
- this - 调用者自身的指针 *
- typedef - 定义一个数据类型的新名字 *
- typeid - 指出一个引用对象的实际类型
- typename - 把一个标识符定义为一种类型
- void - 空的 *
标识符
在看过了这么多奇奇怪怪的关键字之后,之后的内容就会更为的轻松 在C语言的严格规则里,标识符的限制只有五条
- 只能由字母、数字、下划线组成
- 不能与关键字相同
- 内部标识符长度不宜超过 64 ,外部不宜超过 32 个字符(实际上现代许多编译器实际允许比这长的多)
- 不能以数字开头
- 区分大小写
这就是你的起名规则,请务必熟记下来。 当然,在这些外,还有更多的是程序员之间所形成的默契,称作代码风格 这些规范往往是及其细致和繁琐的,例如 谷歌开源代码风格指南
相对没有这么繁琐的,linux内核风格,我非常强烈的建议你花一点时间阅读一下这篇文章 双语对照linux内核风格指南
看到这里我相信你或许已经很累了,好消息是,我们就到这里! 如果由任何关于文章的问题或建议,请在留言区留言讨论。