C语言返回数组的学习笔记

问题来源于今天三班一个学霸问我,他的程序没法运行,什么情况?

那来看看他写的程序,虽然看着有些不舒服。

 代码如下 复制代码
#include <stdio.h>
#include <string.h>
int main()
{
 char tra(char str[]);
 char b[80];
 gets(b);
 puts(tra(b));
return 0;
}
char tra(char str[])
{
 char stri[80];
int i,j,k=0;
i=strlen(str);
for(j=0;j<=2*i-1;j=j+2)
 {
 stri[j]=str[k];
 stri[j+1]=' ';
 k++;
 }
 stri[j-1]='\0';
 return(stri);
}

首先撇去格式不谈了吧……我们来看看程序要实现的效果是什么吧。

用puts语句输出字符 把输入字符,中间用空格隔开

那么在函数中他似乎确实做到了这一点,可是程序却挂了,这是为什么呢?

刚开始我也思考了好一会儿,后来多方查证之后回想起来了。

我们来看一下char tra(char str[])里面的是参数,参数是什么意思,它传递的是一个数组吗?不是,传递的其实是指向数组第一个元素的指针,换句话说,这是一个指针,然后再来看看返回值return(stri),他是一个数组吗?也不是,他只是一个地址罢了,如果我们printf("%p", tra(b));就会看到这个地址了,这并不是字符串,自然用puts()程序会挂。

那么我们能不能使用指针来操作呢?总之,它报错了,因为返回类型不对,所以不能用*来解决问题,同时这涉及到作用域的问题,因为stri其实在return完了之后就已经消失了,如果我们用传统的return值赋值的方法,后来就找不到地址所对应的数值了(这点应该说错了……)修正请见本文最后。

因此我就换了自己熟悉的方案:

 代码如下 复制代码
#include <stdio.h>
#include <string.h>
void tra(char str[], char stri[]);
int main(void)
{
 char b[80], c[80] = {0};
 gets(b);
 tra(b, c);
 puts(c);
return 0;
}
void tra(char str[], char stri[])
{
int i,j,k=0;
i=strlen(str); //5
for(j=0;j<=2*i-1;j=j+2) // j <= 9
 {
 stri[j]=str[k]; // h e l l o\0
 stri[j+1]=' ';
 k++;
 }
 stri[j-1]='\0';
}

这样子就能保证数组可以正常输入输出了,因为它的作用域不仅在此函数内部。

当然,后来学霸还问了某些类似于这样行不行的问题,在最终实践之后得出了一系列结论。

当然,以下都是错误的设计,请勿参考。

如:
将函数定义为,输出指针,那样输出类型就对上号了。

 代码如下 复制代码
#include <stdio.h>
#include <string.h>
int main()
{
 char *tra(char str[]);
 char b[80], *p, c[80], d;
 gets(b);
 strcpy(c, tra(b));
 p = tra(b);
 puts(c);
 printf("%c", tra(b)[2]);
 return 0;
}
char *tra(char str[])
{
 char stri[80];
 int i,j,k=0;
 i=strlen(str);
 for(j=0;j<=2*i-1;j=j+2)
 {
 stri[j]=str[k];
 stri[j+1]=' ';
 k++;
 }
 stri[j-1]='\0';
 return(stri);
}

这样也可以正常输出。(注:C是无法用==来赋值数组的。)
或者是这样。

 代码如下 复制代码
#include <stdio.h>
#include <string.h>
int main()
{
char *tra(char str[]);
char b[80];
gets(b);
//puts(tra(b));
puts(tra(b));
return 0;
}
char stri[80];
char *tra(char str[])
{
int i, j, k = 0;
i = strlen(str);
//for(i=0;str[i]!='/0';i++);
for (j = 0; j <= 2 * i - 1; j = j + 2)
{
stri[j] = str[k];
stri[j + 1] = ' ';
k++;
}
stri[j - 1] = '\0';
return(stri);
}

这里将stri写作外部变量,也是可以的。

为什么说以上失败,归根结底在于不可控制,自动变量消失了之后内存里的数据是否存在是个很大的问题。

时间: 2024-09-18 15:28:08

C语言返回数组的学习笔记的相关文章

C语言一维数组初步学习笔记_C 语言

数组 可以存储一组或者多组数值的变量,里面包含多个元素,数组的每个成员都是一个数组元素. 一维数组 定义:类型 数组名[常量表达式] = {值1, 值2, 值3-}; int a[3] = {0, 1, 2}; float f[2] = {1.2, 2.3, 3.14}; char str[] = {'h', 'e', 'l', 'l', 'o'}; chat str1 = "iPhone";//这也是定义字符数组的方法,字符数组后面会详细讲解,这里先了解一下 当数组元素个数为变量时,

javascript 数组操作学习笔记

1.数组的创建  代码如下 复制代码 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限,是长度 var arrayObj = new Array([element0[, element1[, ...[, elementN]]]]); 创建一个数组并赋值     要说明的是,虽然第二种方法创建数组指定了长度,但实际上所有情况下数组都是变长的,也就是说即使指定了长度为

javascript对象和数组的学习笔记

什么是对象 其实就是一种类型,即引用类型.而对象的值就是引用类型的实例.ECMAScript中引用类型是一种数据类型,用于将数据和功能组织在一起.它也常称为类. 1.Object类型 使用new Object(); 使用字面量创建  代码如下 复制代码 var box = { name: 'caibaojian.com', age: 24 } 输出 alert(box.name) alert(box['name']); var box = { run: function(){ return '1

JavaScript权威设计--JavaScript数组(简要学习笔记九)

1.数组的创建 如: var a=[1.1,null,"a"]; var b=[1, ,3]; //中间的那个元素是undefined var c=[ , , ] 这里c.length你是不是以为是3? 哈哈,长度应该是2.因为数组直接量的语法允许有可选的结尾逗号.   2.数组索引的其他种类 a[-1.23]=true    //创建一个名为-1.23的属性 a["1000"]=0    //如果是字符串,它就转换为数组的索引 a[1.000]    //和a[1

php数组操作学习笔记

什么是数组? 数组是一个数据的集合,相当于一个容器,可以将数据按一定的规则存到这个容器中.相当于旅馆,旅馆内有很多房间,而房间按照一定的规则编号. 数组的构成:基本结构形式如下: $数组名 (键)= 值 数组名:是一个数组区别于另一个数组的方式,就像每个旅馆都有一个名字. 键(key):也成为指针.索引或者标识符.键代表某值在数组中存放的位置,相当于旅馆的门牌号,可以用不同方式命名.通过查询键可以找到相应的值. 值(value):值相当于房间内存放的东西. 赋值创建数组 在php中,创建数组有变

Ruby数组(Array)学习笔记_ruby专题

1.数组的定义 Ruby中的数组是动态数组,存储的数据不用限定类型,数组的长度是根据存储需要动态扩展,所以,在进行数据定义的时候,只用用最简单的方式new一个Array对象就可以了,可以使用以下几种方式: 复制代码 代码如下: arr1=[]      #最简单的Array创建方式 arr2=Array.new    #标准的Array创建方式 arr3=%w[This is a example!] #%w方式转换既定字符串为数组 arr4=(1..10).to_a   #其他集合对象转换为数组

C语言逻辑移位和算术移位学习笔记

C语言的移位操作是程序员日常使用非常频繁的操作之一,用好了移位操作可以为我们省去不少的时间并且程序也可以写得更加漂亮.我们说移位操作是可以分为 左移 和 右移 的,左移的位操作符是 <<,左移一位表示将原数值乘以 2(如果左移使其溢出了将不能得到正确的结果):右移的位操作符是 >>,右移一位表示将原数值除以 2.例如左移操作,如下图所示: 左移3位本质上就是将左边 3 位去掉,在右边用 3 个 0 补全,这就是左移了.看似移位操作很简单,其实这里面是有坑存在的. 如果你认为右移也是

php引用返回function &amp; fun();学习笔记

例子  代码如下 复制代码 <?php     class talker{         private $data = 'Hi';         public function & get(){             return $this->data;         }                public function out(){             echo $this->data;         }       }     $aa = new

Symbian学习笔记

Symbian学习笔记(22) - 关于皮肤的小结 Symbian学习笔记(21)--原来还有这个工具wsdl2cpp,访问webserv Symbian学习笔记(20)--用gSOAP更简单地实现Web Services Clien Symbian学习笔记(19)--初探WebServices API的使用(下) Symbian学习笔记(18)--初探WebServices API的使用(中) Symbian学习笔记(17)--初探WebServices API的使用(上) Symbian学习