发新帖我要提问
12
返回列表
打印

简单的C语言问题,请教!

[复制链接]
楼主: static
手机看帖
扫描二维码
随时随地手机跟帖
21
sodwell| | 2008-8-20 10:04 | 只看该作者 回帖奖励 |倒序浏览

re

LZ的要求是参数只有2个,并且返回一个指针,并且把这个返回值付给一个定义的指针,然后把这个指针得内容打印出来

看谁写的出来,给出答案前先自己编译后运行正确再给答案
window linux下编译都可以

使用特权

评论回复
22
农民讲习所| | 2008-8-20 12:39 | 只看该作者

函数原型就不对

char *mme(char *s1 ,char *s2) 是错的,危险的。

应该 void mme(char *s, char *s1 ,char *s2).

使用特权

评论回复
23
sodwell| | 2008-8-20 12:58 | 只看该作者

re

所长  strcat 的函数原型是char *mme(char *s1 ,char *s2) 写的(名字不一样)。
使用void mme(char *s, char *s1 ,char *s2).是没有问题的
strcat的问题是  定义 char *s1,程序出错,编译没有错。如果定义成  char s1[],就没有错。不管这个 还包括strcpy  ..都是一样的。
使用操作系统库函数一样出错,更何况自己写了...
如:
char *p1 = "1234";
char *p2 = "5678";
strcat(p1,p2);
出错!!编译没有任何问题
char p1[] = "1234";
char *p2 = "5678";
strcat(p1,p2);
正确

所长能否解释一样原因,小弟实在是搞不明白,更在想以后用malloc申请的指针p1,还能传入strcat的参数1吗?是不是只能用自己写的void mme(char *s, char *s1 ,char *s2).这样的函数?

使用特权

评论回复
24
农民讲习所| | 2008-8-20 13:56 | 只看该作者

strcat(p1,p2);也不对

正确的应该是:
char p1[ 10 ] = "1234";      //数组容量要足够
char *p2 = "5678";
strcat(p1,p2);

你能得出结果,不代表没有内存溢出。

使用特权

评论回复
25
sodwell| | 2008-8-20 15:25 | 只看该作者

re

可是用数组的话 只要写char p1[5] = "1234";就可以了  没必要写10
我始终搞不懂strcat的参数1必须是数组名,不能是指针,有哪位知道啊

使用特权

评论回复
26
农民讲习所| | 2008-8-20 15:37 | 只看该作者

因为P2的内容是加在P1数组上的,但P1数组只有原来那么大小

问题就出现了。

使用特权

评论回复
27
sodwell| | 2008-8-20 16:48 | 只看该作者

re

所长,现在的问题是strcat,strcpy的参数1必须是数组名,而不能是指针,先不管数组大小问题。
因为这个原因,以后不知道是要用void mme(char *s, char *s1 ,char *s2).还是用strcat ?来实现追尾。
如果实现知道字符串大小还好办,直接定义数组。但是就怕字符串大小不固定,需要动态的申请空间,如char *p = (char *)malloc(10);这个时候把P这个指针传入strcat参数1中时绝对出错。难道参数1时指针时,都必须用自己写的void mme(char *s, char *s1 ,char *s2)来实现吗?strcat变得没有用处了!
大伙讨论讨论......

使用特权

评论回复
28
农民讲习所| | 2008-8-20 17:04 | 只看该作者

编译器的做法是正确的

你使用的所谓指针,char *p2 = "5678"; 当然不能做参数1,因为编译器认为该指针指向的内存区(数组)没有任何扩展的可能,该内存已经被数据填满。

指针是可以的,但具备初始化数据的固定大小的指针是不能做参数1。
不过这个编译器特性也比较高级的,很多编译器都没这个功能。

如果你只想验证指针能不能做参数1,可以,你这样做:

char *p1 = "1234";
char *p2 = "5678";

char *p3;

p3 = p1;
strcat(p3,p2);
这个是能通过的,因为P3没指针固定数组大小。但结果绝对是错误的,因为P3指向内存区域,还是没有任何扩展的可能,容量装不下P2的内容。

使用特权

评论回复
29
sodwell| | 2008-8-20 17:41 | 只看该作者

re

是的,加一个P3运行结果还是错的,只有指定一个数组 char p[5]; p做为参数1是正确的,虽然数组是固定的5,但是依然正确。就算是参数1+参数2后大于5,结果依然正确,也就是说只要是数组,结果都正确。只要是指针都错。
最后结论是:需要追尾或比较的是数组,可以放心大胆的使用strcat,strcpy等C语言库函数;如果是需要追尾或比较的是指针,都不能用strcat,strcpy等,需要自己写如:void mme(char *s, char *s1 ,char *s2).这样的带3个参数的函数。
这也许是C语言的错误,或者叫C语言的特点。

使用特权

评论回复
30
农民讲习所| | 2008-8-20 17:53 | 只看该作者

乱说

用P1[5]时已经发生错误,P1+5之后的4个字节被该函数修改,这4个字节是其它程序使用的,不属于P1[]。你能看到结果,是因为P1[5]之后,暂时没有任何变量使用,也可以是P2使用的被修改(变量连续分配的原因)。

使用特权

评论回复
31
sodwell| | 2008-8-20 20:25 | 只看该作者

re

其实我也是这么想的,只能说结果刚好正确,实际开发中肯定不能这么写。应该是预设一个较大的值。
但是我上面说的用法结论应该是正确的。

使用特权

评论回复
32
icmap| | 2008-8-20 22:19 | 只看该作者

strcat 的返回值一般情况下是多于的

strcat的返回值一般情况下是多于的,一般都不用它的返回值。
要想做到 strcat 也容易,关键是 strcat 有它的缺点,即
第一个参数必须要有足够的空间,而第一个参数往往是固定好了的(例如一个字符串),一般不会有多于的空间,即使有,也不能保证能放得下另外一个字符串。
如果用 strcat ,又想保证内存不溢出,首先要分配一个空间,然后还需要将第一个字符串复制到新分配的空间中,然后将新分配的空间作为第一个参数,另外一个字符串作为第二个参数。相当繁琐。

使用特权

评论回复
33
hightech929| | 2009-9-1 13:44 | 只看该作者
可是用数组的话 只要写char p1[5] = "1234";就可以了  没必要写10我始终搞不懂strcat的参数1必须是数组名,不能是指针,有哪位知道啊  ...
sodwell 发表于 2008-8-20 15:25


strcat的参数1可以是指针,但是不能是指向字符串常量的指针,
char *p1 = "1234";
p1是一个指向分配在静态数据段的字符串常量的指针,p1的内容是不能够被修改的,也不能够被cat。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则