1.1.5 rearrange函数
/*
**处理输入行,将指定列的字符连接在一起,输出行以NUL结尾
*/
void
rearrange(char *output, char const *input,
int n_columns, int const columns[])
{
int col; /*columns数组的下标*/
int output_col; /*输出列计数器*/
int len; /*输入行的长度*/
这些语句定义了rearrange函数并声明了一些局部变量。此处最有趣的一点是:前两个参数
被声明为指针,但实际在函数调用时,传给他们的参数是数组名。当数组名作为实参时,
传递给函数的实际上是一个指向数组起始位置的指针,也就是数组在内存中的地址。正因为
实际传递的是一个指针而不是一个数组的拷贝,才使数组名作为参数时具备了传址调用的语
义。函数可以按照操纵指针的方式来操纵实参,也可以像使用数组名一样用下标来引用数组
元素。
但是,由于它的传址调用语义,如果函数修改了形参数组的元素,它实际上讲修改实参数组
的对应元素。因此,例子程序把columns声明为const就由两方面的作用。首先,它声明该函
数的作者的意图是这个参数不能被修改。其次,它导致编译器取验证是否违背该意图。因此
这个函数的调用者不必担心例子程序中作为第四个参数传递给函数的数组中的元素会被修改
len = strlen(input);
output_col = 0;
/*
**处理每对列号
*/
for (col=0; col/*
**如果输入行结束或输出行数组已满,就结束任务
*/
if (columns[col] >= len ||
output_col == MAX_INPUT - 1)
break;
/*
**如果输出行数据空间不够,只复制可以容纳的数组
*/
这种只使用一次的"一次性"程序中,不执行数组边界检查之类的任务,只是简单的让数组
"足够大"从而使其不溢出的做法是很常见的。不幸的是,这种方法有时也应用于实际产品
代码中。这种做法在绝大多数情况下将导致大部分数组空间被浪费,而且即使这样有时仍
会出现溢出,从而导致程序失败。
最后,strncpy函数把选中的字符从输入行复制到输出行中可用的下一个位置,strncpy函
数的前两个参数是目标字符串和源字符串的地址。在这个调用中,目标字符串的位置是
输出数组的起始地址向后偏移output_col列的地址。源字符串的位置则是输入数组起始
地址向后偏移columns[col]个位置的地址。第三个参数指定需要复制的字符数。输出列
计数器随后向后移动nchars个位置。
}
output[output_col] = '\0';
}
循环结束之后,输出字符串将以一个NUL字符作为终止符。
阅读(9033) | 评论(0) | 转发(0) |