sodwell 发表于 2008-8-20 10:04

re

LZ的要求是参数只有2个,并且返回一个指针,并且把这个返回值付给一个定义的指针,然后把这个指针得内容打印出来<br /><br />看谁写的出来,给出答案前先自己编译后运行正确再给答案<br />window&nbsp;linux下编译都可以<br />

农民讲习所 发表于 2008-8-20 12:39

函数原型就不对

char&nbsp;*mme(char&nbsp;*s1&nbsp;,char&nbsp;*s2)&nbsp;是错的,危险的。<br /><br />应该&nbsp;void&nbsp;mme(char&nbsp;*s,&nbsp;char&nbsp;*s1&nbsp;,char&nbsp;*s2).<br /><br />

sodwell 发表于 2008-8-20 12:58

re

所长&nbsp;&nbsp;strcat&nbsp;的函数原型是char&nbsp;*mme(char&nbsp;*s1&nbsp;,char&nbsp;*s2)&nbsp;写的(名字不一样)。<br />使用void&nbsp;mme(char&nbsp;*s,&nbsp;char&nbsp;*s1&nbsp;,char&nbsp;*s2).是没有问题的<br />strcat的问题是&nbsp;&nbsp;定义&nbsp;char&nbsp;*s1,程序出错,编译没有错。如果定义成&nbsp;&nbsp;char&nbsp;s1[],就没有错。不管这个&nbsp;还包括strcpy&nbsp;&nbsp;..都是一样的。<br />使用操作系统库函数一样出错,更何况自己写了...<br />如:<br />char&nbsp;*p1&nbsp;=&nbsp;&quot;1234&quot;;<br />char&nbsp;*p2&nbsp;=&nbsp;&quot;5678&quot;;<br />strcat(p1,p2);<br />出错!!编译没有任何问题<br />char&nbsp;p1[]&nbsp;=&nbsp;&quot;1234&quot;;<br />char&nbsp;*p2&nbsp;=&nbsp;&quot;5678&quot;;<br />strcat(p1,p2);<br />正确<br /><br />所长能否解释一样原因,小弟实在是搞不明白,更在想以后用malloc申请的指针p1,还能传入strcat的参数1吗?是不是只能用自己写的void&nbsp;mme(char&nbsp;*s,&nbsp;char&nbsp;*s1&nbsp;,char&nbsp;*s2).这样的函数?

农民讲习所 发表于 2008-8-20 13:56

strcat(p1,p2);也不对

正确的应该是:<br />char&nbsp;p1[&nbsp;10&nbsp;]&nbsp;=&nbsp;&quot;1234&quot;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//数组容量要足够<br />char&nbsp;*p2&nbsp;=&nbsp;&quot;5678&quot;;<br />strcat(p1,p2);<br /><br />你能得出结果,不代表没有内存溢出。<br /><br />

sodwell 发表于 2008-8-20 15:25

re

可是用数组的话&nbsp;只要写char&nbsp;p1&nbsp;=&nbsp;&quot;1234&quot;;就可以了&nbsp;&nbsp;没必要写10<br />我始终搞不懂strcat的参数1必须是数组名,不能是指针,有哪位知道啊<br />

农民讲习所 发表于 2008-8-20 15:37

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

问题就出现了。

sodwell 发表于 2008-8-20 16:48

re

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

农民讲习所 发表于 2008-8-20 17:04

编译器的做法是正确的

你使用的所谓指针,char&nbsp;*p2&nbsp;=&nbsp;&quot;5678&quot;;&nbsp;当然不能做参数1,因为编译器认为该指针指向的内存区(数组)没有任何扩展的可能,该内存已经被数据填满。<br /><br />指针是可以的,但具备初始化数据的固定大小的指针是不能做参数1。<br />不过这个编译器特性也比较高级的,很多编译器都没这个功能。<br /><br />如果你只想验证指针能不能做参数1,可以,你这样做:<br /><br />char&nbsp;*p1&nbsp;=&nbsp;&quot;1234&quot;;<br />char&nbsp;*p2&nbsp;=&nbsp;&quot;5678&quot;;<br /><br />char&nbsp;*p3;<br /><br />p3&nbsp;=&nbsp;p1;<br />strcat(p3,p2);<br />这个是能通过的,因为P3没指针固定数组大小。但结果绝对是错误的,因为P3指向内存区域,还是没有任何扩展的可能,容量装不下P2的内容。

sodwell 发表于 2008-8-20 17:41

re

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

农民讲习所 发表于 2008-8-20 17:53

乱说

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

sodwell 发表于 2008-8-20 20:25

re

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

icmap 发表于 2008-8-20 22:19

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

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

hightech929 发表于 2009-9-1 13:44

可是用数组的话 只要写char p1 = "1234";就可以了没必要写10我始终搞不懂strcat的参数1必须是数组名,不能是指针,有哪位知道啊...
sodwell 发表于 2008-8-20 15:25 https://bbs.21ic.com/images/common/back.gif

strcat的参数1可以是指针,但是不能是指向字符串常量的指针,
char *p1 = "1234";
p1是一个指向分配在静态数据段的字符串常量的指针,p1的内容是不能够被修改的,也不能够被cat。
页: 1 [2]
查看完整版本: 简单的C语言问题,请教!