鱼C论坛

 找回密码
 立即注册
查看: 8190|回复: 39

c语言return数组问题

[复制链接]
发表于 2013-7-16 06:04:17 | 显示全部楼层 |阅读模式
50鱼币
本帖最后由 aleiluya 于 2013-7-16 23:29 编辑

不用指针、全局变量和结构的情况下怎么实现从调用函数把数组返回主函数?

望高手解答~~~谢谢~~~

最好解释下为什么下面代码不可以,不胜感激~~~
  1. /* return数组 */

  2. #include <stdio.h>

  3. char try(char s[]);

  4. void main()
  5. {
  6.         char s[20];

  7.         printf("is:%s", try(s));
  8. }

  9. char try(char s[])
  10. {
  11.           s = "hello!";
  12. }
复制代码
正在学 C程序设计语言(K&R) :练习3-5之前没有指针、全局变量和结构。
以下是为什么我要知道怎么return数组:
  1. /*
  2. 3-5:编写函数itob(n,s,b),将整数n转换为以b为低的数,并将转换结果以字符的形式保存到字符串s中。例如,itob(n,s,16)把整数n格式化成十六进制整数保存在s中。
  3.   */
  4. #include <stdio.h>

  5. char hex(int n, char s[]);
  6. char itob(int n, char s[], int b);
  7. char binary(int n, char s[]);

  8. void main()
  9. {

  10.         int n, b;
  11.         static char s[50];

  12.         printf("请安以下的格式输入:你想要转换的数 以什么形式(只限二进制和十六进制)\n");
  13.         while (1)
  14.         {
  15.                 scanf("%d %d", &n, &b);
  16.                 if ((b == 2) || (b == 16))
  17.                 {
  18.                         printf("%s\n", itob(n, s, b));
  19.                 }
  20.                 else
  21.                 {
  22.                         printf("输入的格式错误,请重新输入!\n");
  23.                 }
  24.         }
  25. }

  26. /*如果是要二进制就调用二进制函数,如果是十六进制就调用十六进制。我记得数组传送是传送数组的首地址也就是物理地址,难道错了嘛?错了的话怎么正确实现。ps:难道要我把三个函数合成一个?*/
  27. char itob(int n, char s[], int b)  //本问题的函数
  28. {
  29.         switch (b)
  30.         {
  31.         case 2:
  32.                 printf("进入函数itob的switch(2)。\n");
  33.                 s = binary(n, s);  //测试,也测试过printf("%s",binary(n,s));
  34.                 printf("%s", s);
  35.                 return s;

  36.                 break;
  37.         case 16:
  38.                 printf("进入函数itob的switch(16)。\n"); //测试
  39.                 return (s = hex(n, s));
  40.                 break;
  41.         }

  42. }

  43. /******************************************************/
  44. char binary(int n, char *s[])  //十进制转二进制
  45. {
  46.         unsigned int i, temp;                // 声明为无符号是因为不能是负数。

  47.         temp = ~0;                                        // 求得在任何机器上最大有多少位,并把结果保存在temp。

  48.         for (i = 0; temp > 0; i++)
  49.         {
  50.                 temp >>= 1;                                // 每循环右移一次就把次数保存在i。
  51.         }



  52.         i--;                                                // 减去本身的次数。
  53.         for (temp = 1; i > 0; i--)        // 把最高位弄成1,其余0。
  54.         {
  55.                 temp <<= 1;
  56.         }
  57.         i = 0;
  58.         while (temp > 0)                        // 用位操作把n以二进制形式提取出来。
  59.         {
  60.                 if ((n & temp) == 0)
  61.                 {
  62.                         s[i++] = '0';
  63.                 }
  64.                 else
  65.                 {
  66.                         s[i++] = '1';
  67.                 }
  68.                 temp >>= 1;                                // 每输出一次就右移一位,进行下一位输出准备。
  69.         }
  70.         s[i] = '\0';
  71.         printf("进入函数binary,现返回s:%s\n", s);//测试

  72.         return s;
  73. }

  74. // / /// /// /// /// /// /// /// /// /// /// /// ///

  75. char hex(int n, char s[])  //十进制转十六进制
  76. {
  77.         unsigned int i, j, temp;        // 声明为无符号是因为不能是负数。
  78.         s[0] = '0';
  79.         s[1] = 'X';
  80.         temp = ~0;                                        // 求得在任何机器上最大有多少位,并把结果保存在temp。

  81.         for (i = 0; temp > 0; i++)
  82.         {
  83.                 temp >>= 1;                                // 每循环右移一次就把次数保存在i。
  84.         }

  85.         i /= 4;
  86.         i--;
  87.         for (temp = 15; i > 0; i--)        // 把最高4位弄成1,其余0。
  88.         {
  89.                 temp <<= 4;
  90.         }
  91.         i = 2;
  92.         while (temp)                                // 第一个循环把左边的空白位删除。
  93.         {
  94.                 if (n & temp)                        // 判断是否是n变量的最高位。
  95.                 {
  96.                         while (temp)                // 第二个循环取值。
  97.                         {
  98.                                 j = n & temp;
  99.                                 while (((j & 15) == 0) && j)        // 如果j不是0就把数字右移到最右边。
  100.                                 {
  101.                                         j >>= 4;
  102.                                 }

  103.                                 if (j > 9)                // 大于9以上的用字母保存。
  104.                                 {
  105.                                         s[i++] = (j - 10) + 'A';
  106.                                 }
  107.                                 else
  108.                                 {
  109.                                         s[i++] = j + '0';
  110.                                 }
  111.                                 temp >>= 4;                // 每循环一次就右移为下次做准备。
  112.                         }
  113.                 }
  114.                 s[i++] = '0';                        // 不是数值的最高位就补0。
  115.                 temp >>= 4;                                // 每循环一次就右移为下次做准备。
  116.         }
  117.         s[--i] = '\0';                                // 字符串结束标志。--是为了覆盖掉循环的0。
  118.         printf("进入函数hex,现返回。\n"); //测试
  119.         return s;
  120. }
复制代码

最佳答案

查看完整内容

05.char try(char s[]); 这个函数返回char类型,char不是数组,也不是字符指针 printf("is:%s", try(s)); 这里试图将char以%s的方式打印出来,所以有问题。 C语言中,数组很容易转换为指针。和基本类型做一个对比,同样作为函数的输入参数,基本类型是值传递,而数组则转换为指针后传递指针(称为引用传递),函数的返回也类似。如果非要以值传递的方式返回一个数组,可以考虑利用结构体。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 06:04:18 | 显示全部楼层
  1. #include <stdio.h>

  2. #define CNT 10
  3. struct MyVec{
  4.         int v[CNT];
  5. };

  6. void init( struct MyVec* p ) {
  7.         int i;
  8.         for(i=0;i<CNT;++i)
  9.                 p->v[i] = i;
  10. }

  11. void show( const struct MyVec* p, const char* msg ) {
  12.         int i;
  13.         puts(msg);
  14.         for(i=0;i<CNT;++i)
  15.                 printf( "%d\n", p->v[i] );
  16. }

  17. struct MyVec test( struct MyVec vec ) {
  18.         int i;
  19.         for(i=0;i<CNT;++i)
  20.                 vec.v[i]*=2;
  21.         return vec;
  22. }

  23. int main () {
  24.         struct MyVec v1;
  25.         struct MyVec v2;
  26.         init(&v1);
  27.         v2 = test(v1);
  28.         show( &v1,"v1 is:" );
  29.         show( &v2,"v2 is:" );
  30. }
复制代码
05.char try(char s[]);
这个函数返回char类型,char不是数组,也不是字符指针
printf("is:%s", try(s));
这里试图将char以%s的方式打印出来,所以有问题。

C语言中,数组很容易转换为指针。和基本类型做一个对比,同样作为函数的输入参数,基本类型是值传递,而数组则转换为指针后传递指针(称为引用传递),函数的返回也类似。如果非要以值传递的方式返回一个数组,可以考虑利用结构体。

评分

参与人数 2鱼币 +10 收起 理由
aleiluyes + 5
小甲鱼 + 5 给力啊!

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 09:16:06 | 显示全部楼层
还没看懂。。。。求合影。呵呵
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 09:41:05 | 显示全部楼层
本帖最后由 编程难 于 2013-7-16 09:49 编辑
  1. #include <stdio.h>

  2. char* trys(char s[]);

  3. void main()
  4. {
  5.         char s[20];

  6.         printf("is:%s", trys(s));
  7. }

  8. char* trys(char s[])
  9. {
  10.    s = "hello!";
  11.    return s;
  12. }
复制代码
上面的写法可以输出,但要意识到问题很严重。具体的等你学的再深入点慢慢理解。
顺便提一句,c/c++中不能返回数组。可以查看c/c++标准。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 09:58:25 | 显示全部楼层

这个写法可以输出 也没什么严重的问题
有瑕疵就是了
你的形参是多余的 main里面的数组s也是多余的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 10:01:07 | 显示全部楼层
仰望天上的光 发表于 2013-7-16 08:19
05.char try(char s[]);
这个函数返回char类型,char不是数组,也不是字符指针
printf("is:%s", try(s)); ...

C语言中,数组很容易转换为指针。和基本类型做一个对比,同样作为函数的输入参数,基本类型是值传递,而数组则转换为指针后传递指针(称为引用传递)

这段话说错了 传递指针一样是值传递
C语言里面 只有值传递 没有 引用传递
引用是C++的内容
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 10:34:03 | 显示全部楼层
我是师兄 发表于 2013-7-16 09:58
这个写法可以输出 也没什么严重的问题
有瑕疵就是了
你的形参是多余的 main里面的数组s也是多余的

我想楼主的意思很可能是 1.改变main中的数组的内容为hello并且输出。2,通过返回一个数组,而不是指针。这两点,代码中没做到任何一点。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 11:14:06 | 显示全部楼层
哇塞,仰望大神好厉害啊~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 11:18:59 | 显示全部楼层
  1. printf("is:%s", try(s));
复制代码
指针传递时值传递,所以try函数中相当于将指针s的副本_s赋值“hello”,所以,实际上main函数中数组s依然是没有值得,所以这种方法无法实现你想要的结果。

你可以用return来实现。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 12:05:02 | 显示全部楼层
已成往事 发表于 2013-7-16 11:18
指针传递时值传递,所以try函数中相当于将指针s的副本_s赋值“hello”,所以,实际上main函数中数组s依然是没 ...

却是是如此,但是最后一句话,用return来实现什么???不大懂
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 13:06:00 | 显示全部楼层
编程难 发表于 2013-7-16 09:41
上面的写法可以输出,但要意识到问题很严重。具体的等你学的再深入点慢慢理解。
顺便提一句,c/c++中不能返 ...

返回一个数组在C里面的确是做不到
不过 在这里 可以通过一点小技巧 做偷渡的
  1. typedef struct
  2. {
  3. char str[32];
  4. }Str;
  5. Str func()
  6. {
  7. Str str = {"Hello!"};
  8. return str;
  9. }

  10. int main()
  11. {
  12. puts(func().str);
  13. }
复制代码

评分

参与人数 3鱼币 +13 收起 理由
aleiluyes + 5
花火——陌生 + 3 眼前一亮啊
小甲鱼 + 5 非常棒!

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 14:49:40 | 显示全部楼层
你传一个引用过去就可以了。不用返回,你改变的数组就是原来的数组。“&”这个是引用的标志!~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 15:35:14 | 显示全部楼层
我是师兄 发表于 2013-7-16 10:01
C语言中,数组很容易转换为指针。和基本类型做一个对比,同样作为函数的输入参数,基本类型是值传递,而数 ...

嗯,我的原意是说,同样作为函数的参数,基本类型实现的是值传递的语义,而数组(当然实际上被转换为指针了,但作为语义,我们无视这个过程)实现的是引用传递的语义。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 18:24:56 | 显示全部楼层
我是师兄 发表于 2013-7-16 13:06
返回一个数组在C里面的确是做不到
不过 在这里 可以通过一点小技巧 做偷渡的

excellent, 再加个隐式转换,就以假乱真了:lol
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 18:48:02 | 显示全部楼层
菜鸟来学习的··············
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-16 23:33:19 | 显示全部楼层
仰望天上的光 发表于 2013-7-16 08:19
05.char try(char s[]);
这个函数返回char类型,char不是数组,也不是字符指针
printf("is:%s", try(s)); ...

哦问题在哪里知道了,可怎么解决呢,在不用结构的情况下?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-16 23:34:31 | 显示全部楼层
编程难 发表于 2013-7-16 09:41
上面的写法可以输出,但要意识到问题很严重。具体的等你学的再深入点慢慢理解。
顺便提一句,c/c++中不能返 ...

数组的第一个不是地址吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-16 23:35:14 | 显示全部楼层
表示.路过.....:lol
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-16 23:55:50 | 显示全部楼层
刀下留人 发表于 2013-7-16 14:49
你传一个引用过去就可以了。不用返回,你改变的数组就是原来的数组。“&”这个是引用的标志!~

怎么实现?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-17 00:00:53 | 显示全部楼层
aleiluya 发表于 2013-7-16 23:33
哦问题在哪里知道了,可怎么解决呢,在不用结构的情况下?

任何语言都有缺陷。C语言的数组作为函数的参数本身就存在这个问题,这是C语言固有的问题,用结构体是一种解决方案。不用结构体的话,可以考虑换一种其它语言,比如C++语言。毕竟,任何语言都是工具,不过C++语言也有它的缺陷哦。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-19 03:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表