0%

朱绂方来

C语言常用循环体

对于初学者而言,循环一般只涉及二元变量,代表了平面里的两个坐标。在平面中输出字符构成的图形时,往往采用 i 代表行、j 代表列,按照给定的函数表达式逐行输出。

1
2
3
4
5
6
7
8
for (condition){
for (condition){
while(condition){
...(code);
}
}
return (variate);
}

还有许多诸如此类的”千层蛋糕”。如果需要实现这类函数,最好先数清楚变量数量,然后理清哪些是不变量、哪些是变量,以及变量之间满足怎样的函数关系,先声明清楚,然后再定义函数。
在定义函数的时候,先写一遍伪代码,让 agent 检查一遍逻辑,查看特殊值和错误值输入时的返回处理,然后再进行编码。反正一天写一道函数题是我的日常……有点惨不忍睹。

C语言累计计数

在C语言中,不使用C标准库的时候,我们需要自己手搓计数器。对于字符串中不同类型的字符(比如说字母、空格、数字等),这主要通过ASCII码来实现。比如对于字母类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/* 我们先声明一个变量并且读取 */
#include <stdio.h>
#define MAXS 100

void ReadString(char s[]);
void Stringcount(char s[]);

/* 以上定义了两个函数原型 */
int main(){
char s[MAXS];
ReadString(s);
Stringcount(s);
return 0;
}

void ReadString(char s[])
{
fgets(s, MAXS, stdin);
}

void Stringcount(char s[])
{
int letter = 0;
int i = 0;
while (s[i] != '\0'){
if ( (s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z') ){
letter++;
}
i++;
}
printf("字母数量: %d\n", letter);
}

或者对于单一字符类型,例如数字字符,我们可以初始化一个计数的”容器”:

1
2
3
4
5
6
7
8
9
10
int count[10] = {0};
/* 自动向数组中的每一个元素写入0 */
/* 这里的数组储存的是每个数字字符(0-9)出现的次数 */
int i = 0;
while (s[i] != '\0'){
if (s[i] >= '0' && s[i] <= '9'){
count[s[i] - '0']++; /* 将字符数字映射到对应的数组下标 */
}
i++;
}

以上便是在C语言中不使用标准库函数,徒手实现字符计数的基本思路。遍历字符串,依据ASCII码范围判断字符类型,将计数累加到对应的变量或数组单元中即可。

一些小细节

对于特殊值的处理是我们不得不小心的一环,我们无法判断和要求用户按照我们的实际功能输入正确的参数,所以我们需要对特殊情况做出分类。一般来说都有:负数、浮点数、字符串、含有特殊字符的字符串、0等等。因为C语言对于数据类型乃至于数据长度有着严苛的要求,所以对输入的数据做分类处理是非常有必要的。一般我们会采用if语句排除掉这些特殊值。
另外,除了在输出中产生的特殊类型数据,我们还经常需要处理函数之间可能产生的特殊数据,比如说我在输入整型数据的时候,由于在进行除法运算或者因为二进制精度不够而产生了浮点数,在我们使用(int)强制可能因为直接舍去末尾小数,而导致与期望值差1,这时候我们需要使用四舍五入,将精度修正为我们需要的。

学习C语言,最难的不是语法本身,而是培养一种”机器思维”——你需要亲自告诉计算机每一个步骤该做什么,没有任何现成的便利可言。但也正是这种笨拙,让我逐渐理解到程序运行的本质。花和人都会遇到各种各样的不幸,代码也会遇到各种各样的bug,但生命的长河、学习的长河,都是无止境的。