C 返回数组?No!
其实早前的文章已经说过函数和数组和指针了,那么现在再来说一下归根结底还是又忘了的缘故,加上再给原来的多些扩展和补充,尽量达成互补的效果:C 几个程序,我们来聊聊数组,函数和指针
问题来源于今天三班一个学霸问我,他的程序没法运行,什么情况?
那来看看他写的程序,虽然看着有些不舒服。
1#include <stdio.h>
2#include <string.h>
3
4int main()
5{
6 char tra(char str[]);
7 char b[80];
8 gets(b);
9 puts(tra(b));
10return 0;
11}
12char tra(char str[])
13{
14 char stri[80];
15int i,j,k=0;
16i=strlen(str);
17for(j=0;j<=2*i-1;j=j+2)
18 {
19 stri[j]=str[k];
20 stri[j+1]=' ';
21 k++;
22 }
23 stri[j-1]='\0';
24 return(stri);
25}
26
27
首先撇去格式不谈了吧……我们来看看程序要实现的效果是什么吧。
用puts语句输出字符 把输入字符,中间用空格隔开
那么在函数中他似乎确实做到了这一点,可是程序却挂了,这是为什么呢?
刚开始我也思考了好一会儿,后来多方查证之后回想起来了。
我们来看一下char tra(char str[])
里面的是参数,参数是什么意思,它传递的是一个数组吗?不是,传递的其实是指向数组第一个元素的指针,换句话说,这是一个指针,然后再来看看返回值return(stri)
,他是一个数组吗?也不是,他只是一个地址罢了,如果我们printf("%p", tra(b));
就会看到这个地址了,这并不是字符串,自然用puts()
程序会挂。
那么我们能不能使用指针来操作呢?总之,它报错了,因为返回类型不对,所以不能用*
来解决问题,同时这涉及到作用域的问题,因为stri其实在return完了之后就已经消失了,如果我们用传统的return值赋值的方法,后来就找不到地址所对应的数值了(这点应该说错了……)修正请见本文最后。
因此我就换了自己熟悉的方案:
1#include <stdio.h>
2#include <string.h>
3void tra(char str[], char stri[]);
4int main(void)
5{
6 char b[80], c[80] = {0};
7 gets(b);
8 tra(b, c);
9 puts(c);
10return 0;
11}
12void tra(char str[], char stri[])
13{
14int i,j,k=0;
15i=strlen(str); //5
16for(j=0;j<=2*i-1;j=j+2) // j <= 9
17 {
18 stri[j]=str[k]; // h e l l o\0
19 stri[j+1]=' ';
20 k++;
21 }
22 stri[j-1]='\0';
23}
24
这样子就能保证数组可以正常输入输出了,因为它的作用域不仅在此函数内部。
当然,后来学霸还问了某些类似于这样行不行的问题,在最终实践之后得出了一系列结论。
当然,以下都是错误的设计,请勿参考。
如: 将函数定义为,输出指针,那样输出类型就对上号了。
1#include <stdio.h>
2#include <string.h>
3
4int main()
5{
6 char *tra(char str[]);
7 char b[80], *p, c[80], d;
8 gets(b);
9 strcpy(c, tra(b));
10 p = tra(b);
11 puts(c);
12 printf("%c", tra(b)[2]);
13 return 0;
14}
15char *tra(char str[])
16{
17 char stri[80];
18 int i,j,k=0;
19 i=strlen(str);
20 for(j=0;j<=2*i-1;j=j+2)
21 {
22 stri[j]=str[k];
23 stri[j+1]=' ';
24 k++;
25 }
26 stri[j-1]='\0';
27 return(stri);
28}
29
这样也可以正常输出。(注:C是无法用==
来赋值数组的。)
或者是这样。
1#include <stdio.h>
2#include <string.h>
3
4int main()
5{
6char *tra(char str[]);
7char b[80];
8gets(b);
9//puts(tra(b));
10puts(tra(b));
11return 0;
12}
13char stri[80];
14char *tra(char str[])
15{
16
17int i, j, k = 0;
18i = strlen(str);
19//for(i=0;str[i]!='/0';i++);
20for (j = 0; j <= 2 * i - 1; j = j + 2)
21{
22stri[j] = str[k];
23stri[j + 1] = ' ';
24k++;
25}
26stri[j - 1] = '\0';
27return(stri);
28}
29
这里将stri
写作外部变量,也是可以的。
为什么说以上失败,归根结底在于不可控制,自动变量消失了之后内存里的数据是否存在是个很大的问题。
评论 (0)