c语言中指针传递的问题

以下程序是输入数字月份,实现输出英语月份
例如:输入3,输出是March
1-8月都能正确输出英文月份,但是9-12月就无法正常输出了,调试的时候查看了下,调用函数能正确返回需要的值,但是在进行printf输出这里出错了,该用数组可以正确输出,请告知我这里指针是哪里用错了,为什么会出现这样的错误。急切等待高手解答
#include <stdio.h>
#include <string.h>
void main()
{
int m,i;
char a[20],b[20];
char *p;
p=a;
char *change(int);
printf("put into month:\n");
scanf("%d",&m);
if(m>=1&&m<=12)
{
p=change(m);
printf("%s\n",p);
}
else printf("you put error month\n");
}
char *change(int x)
{
char a[12][20]={"January","February","March","April","May","June","July","August","September","October","November","December"};
switch(x)
{
case 1:return a[0];break;
case 2:return a[1];break;
case 3:return a[2];break;
case 4:return a[3];break;
case 5:return a[4];break;
case 6:return a[5];break;
case 7:return a[6];break;
case 8:return a[7];break;
case 9:return a[8];break;
case 10:return a[9];break;
case 11:return a[10];break;
default:return a[11];break;
}
}
改用数组接受返回的指针,1-12月都正确,按1楼所说函数结束变量就不存在,这是为什么?
#include <stdio.h>
#include <string.h>
void main()
{
int m,i;
char a[20],b[20];
char *p;
p=a;
char *change(int);
printf("put into month:\n");
scanf("%d",&m);
if(m>=1&&m<=12)
{
p=change(m);
for (i=0;i<20;i++)
{
b[i]=*p;
p++;

}
printf("%s\n",b);
}

else printf("you put error month\n");
}
char *change(int x)
{
char a[12][20]={"January","February","March","April","May","June","July","August","September","October","November","December"};
switch(x)
{
case 1:return a[0];break;
case 2:return a[1];break;
case 3:return a[2];break;
case 4:return a[3];break;
case 5:return a[4];break;
case 6:return a[5];break;
case 7:return a[6];break;
case 8:return a[7];break;
case 9:return a[8];break;
case 10:return a[9];break;
case 11:return a[10];break;
default:return a[11];break;
}
}

根本性的认识错误,返回的是野指针,前面的正确是侥幸
char a[12][20] 是局部动态变量,函数结束变量就不存在了

如果非要返回的话,改用静态变量

#include <stdio.h>
#include <string.h>

char *change(int x);/*函数声明放在外部*/

void main()
{
int m;
char *p;
printf("put into month:\n");
scanf("%d",&m);
if(m>=1&&m<=12)
{
p=change(m);
printf("%s\n",p);
}
else printf("you put error month\n");
}
char *change(int x)
{
static char a[12][20]={"January","February","March","April","May","June","July","August","September","October","November","December"};/*改用静态变量*/

switch(x)
{
case 1:return a[0];break;
case 2:return a[1];break;
case 3:return a[2];break;
case 4:return a[3];break;
case 5:return a[4];break;
case 6:return a[5];break;
case 7:return a[6];break;
case 8:return a[7];break;
case 9:return a[8];break;
case 10:return a[9];break;
case 11:return a[10];break;
default:return a[11];break;
}
}

试一下这个
#include <stdio.h>
#include <string.h>
char *change(int);

void main()
{
int m,i;
char a[20],b[20];
char *p;
p=a;
printf("put into month:\n");
scanf("%d",&m);
if(m>=1&&m<=12)
{
p=change(m);
{
char a[100]="1234567890";/*添加的局部变量*/
}
for (i=0;i<20;i++)
{
b[i]=*p;
p++;

}
printf("%s\n",b);
}

else printf("you put error month\n");
}
char *change(int x)
{
char a[12][20]={"January","February","March","April","May","June","July","August","September","October","November","December"};
switch(x)
{
case 1:return a[0];break;
case 2:return a[1];break;
case 3:return a[2];break;
case 4:return a[3];break;
case 5:return a[4];break;
case 6:return a[5];break;
case 7:return a[6];break;
case 8:return a[7];break;
case 9:return a[8];break;
case 10:return a[9];break;
case 11:return a[10];break;
default:return a[11];break;
}
}

运行时 输入 12,结果就不对了
解释
"January","February"...
这些内容本身是字符串常量,是放在常量区的
运行到 函数change 时
char a[12][20] 是临时分配的,内容是从常量区复制过来的,这个看一下编译生成的汇编代码就很清楚了
函数结束以后 a 就被释放掉了,所以 a 原来的地址里的内容就有不确定性
不可以直接使用

返回局部变量
a 不要定义成 char a[12][20]
定义成 char *a[12]
这样a 是指向常量区的指针,在编译时就已经确定了,可以返回地址

#include <stdio.h>
#include <string.h>
char *change(int);

void main()
{
int m,i;
char a[20],b[20];
char *p;
p=a;
printf("put into month:\n");
scanf("%d",&m);
if(m>=1&&m<=12)
{
p=change(m);
for (i=0;i<20;i++)
{
b[i]=*p;
p++;

}
printf("%s\n",b);
}

else printf("you put error month\n");
}
char *change(int x)
{
char *a[12]={"January","February","March","April","May","June","July","August","September","October","November","December"};
switch(x)
{
case 1:return a[0];break;
case 2:return a[1];break;
case 3:return a[2];break;
case 4:return a[3];break;
case 5:return a[4];break;
case 6:return a[5];break;
case 7:return a[6];break;
case 8:return a[7];break;
case 9:return a[8];break;
case 10:return a[9];break;
case 11:return a[10];break;
default:return a[11];break;
}
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-07-24
把char a[12][20]={"January","February","March","April","May","June","July","August","September","October","November","December"};
定义成全局变量,如果定义在函数体里面的话,返回的局部变量的地址,出了函数体之后,char a[12][20]的作用域就结束了,地址中间的值就是不可预知的了

change可以改成
char *change(int x)
{
return a[x-1];
}
第2个回答  2009-07-25
我也不太清楚,不过我把2维数组换成指针数组就可以了,如果有高手请赐教下
下面是改好的代码:
#include <stdio.h>
#include <string.h>
void main()
{
int m;
char *p = new char[20];
char *change(int);
printf("put into month:\n");
scanf("%d",&m);
while(m>=1&&m<=12)
{
p=change(m);
printf("%s\n",p);
scanf("%d",&m);
}
}

char *change(int x)
{
char *a[12]={"January","February","March","April","May","June","July","August","September","October","November","December"};
switch(x)
{
case 1:return a[0];break;
case 2:return a[1];break;
case 3:return a[2];break;
case 4:return a[3];break;
case 5:return a[4];break;
case 6:return a[5];break;
case 7:return a[6];break;
case 8:return a[7];break;
case 9:return a[8];break;
case 10:return a[9];break;
case 11:return a[10];break;
default:return a[11];break;
}
}
那指针数组和2维数组在内存分配上有何区别呢
恩,明白了,十分感谢,呵呵,可惜我不能给你分,要不我也给个20分了,呵呵
第3个回答  2009-07-24
1楼说的很清楚了··
相似回答