24 / 07 / 12
#include <stdio.h> #include <ctype.h> // forward declarations int can_print_it(char ch); void print_letters(char arg[]); void print_arguments(int argc, char *argv[]) { int i = 0; for(i = 0; i < argc; i++) { print_letters(argv[i]); } } void print_letters(char arg[]) { int i = 0; for(i = 0; arg[i] != '\0'; i++) { char ch = arg[i]; if(can_print_it(ch)) { printf("'%c' == %d ", ch, ch); } } printf("\n"); } int can_print_it(char ch) { return isalpha(ch) || isblank(ch); } int main(int argc, char *argv[]) { print_arguments(argc, argv); return 0; }
重新编写这些函数,使它们的数量减少。比如,你真的需要
can_print_it
吗?
#include <stdio.h> #include <ctype.h> void print_arguments(int argc, char *argv[]) { int i = 0; int j = 0; for(i = 1; i < argc; i++) { for(j = 0; argv[i][j] != '\0'; j++) { char ch = argv[i][j]; if(isalpha(ch) || isblank(ch)) { printf("'%c' == %d; ", ch, ch); } } printf("\n"); } } int main(int argc, char *argv[]) { print_arguments(argc, argv); return 0; }
使用
strlen
函数,让print_arguments
知道每个字符串参数都有多长,之后将长度传入print_letters
。然后重写print_letters
,让它只处理固定的长度,不按照'\0'
终止符。你需要#include <string.h>
来实现它。
void print_arguments(int argc, char *argv[]) { int i = 0; int j = 0; for(i = 1; i < argc; i++) { printf("%lu",strlen(argv[i])); for(j = 0; j < strlen(argv[i]); j++) { char ch = argv[i][j]; if(isalpha(ch) || isblank(ch)) { printf("'%c' == %d; ", ch, ch); } } printf("\n"); } } int main(int argc, char *argv[]) { print_arguments(argc, argv); return 0; }
使用
man
来查询isalpha
和isblank
的信息。使用其它相似的函数来只打印出数字或者其它字符。
C 标准库中还有其他一些类似的函数,用来判断字符类型。以下是一些相关的函数:
isdigit
:检查字符是否为数字。
isalnum
:检查字符是否为字母或数字。
isspace
:检查字符是否为空白字符(空格、换行、制表符等)。
ispunct
:检查字符是否为标点符号。
#include <stdio.h> #include <ctype.h> #include <string.h> void print_arguments(int argc, char *argv[]) { int i = 0; int j = 0; for(i = 1; i < argc; i++) { printf("%lu: ",strlen(argv[i])); for(j = 0; j < strlen(argv[i]); j++) { char ch = argv[i][j]; if(isalnum(ch) || isspace(ch) || ispunct(ch)) { printf("'%c' == %d;\t", ch, ch); } } printf("\n"); } } int main(int argc, char *argv[]) { print_arguments(argc, argv); return 0; }
上网浏览不同的人喜欢什么样的函数格式。永远不要使用“K&R”语法,因为它过时了,而且容易使人混乱,但是当你碰到一些人使用这种格式时,要理解代码做了什么。
文件组织:
每个文件只包含一个独立的概念。
使用头文件保护(#ifndef
, #define
, #endif
)防止重复包含。
命名规范:
变量和函数名使用小驼峰命名法(如 myVariable
)。
全局变量和常量使用全大写字母和下划线(如 GLOBAL_CONSTANT
)。
缩进和空白:
使用2个空格缩进,不使用制表符。
每个函数定义和实现之间留一个空行。
注释:
使用双斜杠(//
)注释单行,使用斜杠星号(/* ... */
)注释多行。
注释应简明扼要,解释代码逻辑而不是代码本身。
函数和变量:
函数应尽量短小,每个函数只做一件事。
避免使用全局变量,使用局部变量和函数参数。
常量:
const
关键字定义常量,避免使用宏定义常量。条件语句和循环:
命名约定:
变量名、函数名、类型名和常量名应使用驼峰命名法(CamelCase),首字母小写。
宏定义使用全大写字母,并且单词之间用下划线分隔。
代码布局:
使用一致的缩进风格,推荐使用四个空格进行缩进。
函数和控制结构的大括号应该独占一行,且大括号应该与相关语句对齐。
注释规范:
函数头应包含描述函数用途、参数和返回值的详细注释。
代码行注释应解释代码的意图、复杂的算法或者可能引起误解的地方。
函数和参数:
函数应该有明确的声明和定义,包括返回类型、函数名和参数列表。
参数应有描述其用途和类型的清晰命名,推荐参数顺序应该符合逻辑顺序。
错误处理:
建议在可能发生错误的地方进行错误检查,并采取适当的错误处理措施。
错误处理应该清晰、一致,并能够提供有用的错误信息和恢复机制。