c 如何定义与使用字符串数组[字符串数组作为实参以及形参的表示]
c 里面字符串其实是字符数组。不过,只是知道这个还是很难精确表述字符串以及字符串数组。一般形式的操作是这样子的:char arr[ROW][LENGTH];char *ptr[ROW];for (int i = 0; i < ROW; ++i) {ptr[i] = arr[i];}从理论上讲,char arr[row][col] 与...
c
里面字符串其实是字符数组。不过,只是知道这个还是很难精确表述字符串以及字符串数组。
一般形式的操作是这样子的:
char arr[ROW][LENGTH];
char *ptr[ROW];
for (int i = 0; i < ROW; ++i) {
ptr[i] = arr[i];
}
从理论上讲,char arr[row][col]
与 char * ptr[row]
完全是一个东西。
但是,在作为函数参数的时候,这是两种不同的类型。
对于 call_arr(arr)
, 这里的形参要如何定义呢?
对于 call_ptr(ptr)
,这里的形参又是什么?
函数原型:
call_arr(int col,int row, char arr[row][col]);
call_ptr(int row, char * ptr[row]);
传入这两个参数(arr
以及 ptr
),函数会分别理解成不同类型的指针。
对于第一种,函数只认为这是一个二维的字符数组,不会把每个一维数组作为字符指针(也就是字符串)去处理。
对于第二种,函数会认为这是一个一维数组,每个元素是一个字符指针。
可能你会困惑,第一种难道不能定义成 call_arr(int row, char * arr[row])
这样的形式吗?
- 答案是不能。因为这样定义,在
call_arr()
函数内部,会认为arr
是一个一个字符指针数组。而你传的实际参数是arr
, 这就造成了类型不匹配。
编译也许会通过。但是在实际处理的时候,函数无法将arr
当时一个一维指针数组,也就导致,不能在其中做指针的操作。比如:arr[i] = "hello world";
这种操作就是不被允许的。因为函数认为arr[i]
是一个一维的字符数组。不能将一个字符串常量指针直接赋值给一个字符数组。
如果这时候使用
strncpy(arr[i], "hello world", strlen("hello world"));
当然是可以赋值成功的。不过这也许不是你程序想要的效果。
来看一下具体的示例:
void call(int row, int col, char arr[row][col]) {
printf("call start=====\n");
for (int i = 0; i < row; ++i) {
printf("%s\t", arr[i]);
}
printf("\ncall end=======\n");
}
void prints(char *arr[], int row) {
for (int i = 0; i < row; i++) {
puts(arr[i]);
}
}
int main(int argc, char *argv[]) {
char arr[ROW][LENGTH];
char *ptr[ROW];
for (int i = 0; i < ROW; ++i) {
// 必须要这一步,否则排序就比较麻烦
ptr[i] = arr[i];
}
inputs(ptr, ROW);
call(ROW, LENGTH, arr);
prints(ptr, ROW);
return 0;
}
从输出效果来看,二者没有任何的区别;从代码逻辑看,二者也没有区别。
如果是仅仅看上面示例中的 void prints(char *arr[], int row);
和void call(int row, int col, char arr[row][col]);
基本看不出这两种形式的参数有什么区别。
从输出效果来看,二者没有任何的区别;从代码逻辑看,二者也没有区别。
再深入一点点。
比如还有一个根据字符串长度对数组进行排序的函数:
void sort_by_length(char *arr[], int row) {
for (int i = 0; i < row - 1; i++) {
for (int j = 0; j < row - 1 - i; j++) {
if (strlen(arr[j]) < strlen(arr[j + 1])) {
char *tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
对于 sort_by_length()
能不能传入 arr
这个实参呢?显然是不能的,原因就是之前说的,类型不匹配。arr
被传入,会被理解成一个二维的字符数组;而传入ptr
就可以。
如果非要给
sort_by_length()
传入实参arr
程序会出现运行出错。
那么,如果写成下面这样呢?
sort(ROW,LENGTH, arr); // main 函数里面调用
// 函数实现 -- 错误示例蛤
void sort(int row, int col, char arr[row][col]) {
for (int i = 0; i < row - 1; i++) {
for (int j = 0; j < row - 1 - i; j++) {
if (strlen(arr[j]) < strlen(arr[j + 1])) {
char *tmp = arr[j];
arr[j] = arr[j + 1]; // 编译报错,不能直接给一维数组赋值
arr[j + 1] = tmp; // 编译报错,原因同上
}
}
}
}
error: array type ‘char [col]’ is not assignable
报错提示就是上面这种。
报错原因还是之前说的,类型不匹配。如果传入二维数组,函数只会将其解析成二维数组,不会“智能”的转换成一维字符指针数组。
不完全示例:字符串数组作为实参以及形参的表示
其中的
s_gets(char *, int)
完全可以使用系统函数fgets()
替代。
// 对应字符数组,就必须使用 strcpy 这样的函数去赋值
void abcd(int row, int col, char arr[row][col]) {
for (int i = 0; i < row - 1; i++) {
for (int j = 0; j < row - 1 - i; j++) {
if (strlen(arr[j]) < strlen(arr[j + 1])) {
char tmp[LENGTH];
strncpy(tmp, arr[j], strlen(arr[j]));
strncpy(arr[j], arr[j + 1], strlen(arr[j + 1]));
strncpy(arr[j + 1], tmp, strlen(tmp));
}
}
}
}
// strncpy 不会给字符数组后面加`\0`, 需要手动添加的
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)