搜索
查看: 2876|回复: 20
打印 上一主题 下一主题

指针函数调用例题

[复制链接]
跳转到指定楼层
楼主
发表于 2013-7-15 09:54:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <stdio.h>
#include <stdlib.h>


/*  编一个指针型函数,将两个字符串连接成一个字符串,函数返回值是连接后  */
/*  所得字符串的首地址。两个原始字符串的首地址作为函数的参数。在主函数  */
/*  中调用该函数,输入两个字符串,并输出连接后的字符串。(不得使用系统  */
/*  函数)                                                                                                              */
/*                                                                                                                           */
/*                                                                                                                           */
/*  程序清单如下:                                                                                                */


char *my_cat(char *p1,char *p2)
{

     static char a[160],*p;
    p=a;
    while (*p1!='\0') *p++=*p1++;
    while (*p2!='\0') *p++=*p2++;
    *p=*p2;   /*补充字符串结束标记,这一句值得学习!*/
    return(a);
}


int main()
{
    char s1[80],s2[80];
    scanf("%s",s1);
    scanf("%s",s2);
    printf("%s\n",my_cat(s1,s2));
    printf("%s\n",my_cat(s2,s1));   
   
    system("pause");
    return 0;
}

沙发
 楼主| 发表于 2013-7-15 10:00:22 | 只看该作者
本帖最后由 嗨,强哥! 于 2013-7-15 10:01 编辑

以上例题是20年前自学考试教材上的例题,函数头根据ANSI C要求写在了函数括号内,其余代码语句与书上是一模一样的。

因为我是初学者,我想这代码有没有落后于现在的要求?可以再优化吗?
板凳
发表于 2013-7-15 14:24:30 | 只看该作者
这个设计不合理,字符串合并的结果保存在一个静态的char array中,那么一次调用的结果会覆盖上一次调用的结果,例如
char *a = my_cat("abc", "de");
char *b = my_cat("de", "fgh");
现在a和 b都指向“defgh”这个字符串

如果一定要返回一个char* ,那么应该这么设计
  1. char* my_cat(char* a, char* b, char* dest)
  2. {
  3.     char* begin = dest;
  4.     while(*a != '\0')
  5.         *dest++ = *a++;
  6.     while(*b != '\0')
  7.         *dest++ = *b++;
  8.     *dest = '\0';
  9.     return begin;
  10. }
复制代码
或者就像标准库中设计的 char* strcat(char* dest, char* from);直接把from的字符拷贝到dest后面

此外,因为空间是静态分配的char [160],如果字符串长度超过159就会出问题。而现代的字符串超过160太正常了.
在C中,应该由库的使用者决定存储空间是怎么分配的,而不是库的编写者,像这个例子里这么设计,是比较拙劣的
   
地板
 楼主| 发表于 2013-7-15 14:42:09 | 只看该作者
rosynirvana 发表于 2013-7-15 14:24
这个设计不合理,字符串合并的结果保存在一个静态的char array中,那么一次调用的结果会覆盖上一次调用的结 ...

您没有读懂题目的意思,参数只能是两个字符串的地址,而您的行参有3个。
撇开这不说,静态变量的使用我觉得您讲的十分正确。静态变量要好好考虑它的使用情况才能决定使用,是吗?
5#
发表于 2013-7-15 14:48:06 | 只看该作者
嗨,强哥! 发表于 2013-7-15 14:42
您没有读懂题目的意思,参数只能是两个字符串的地址,而您的行参有3个。
撇开这不说,静态变量的使用我觉 ...

不不不,题目也没说除了两个首地址之外,不能使用其它的参数啊

点评

函数有3个形参,主函数应该也要有3个实参给它吧?  发表于 2013-7-15 15:16
对的,我理解有误,呵呵。。。。  发表于 2013-7-15 15:09
6#
 楼主| 发表于 2013-7-15 14:48:34 | 只看该作者
rosynirvana 发表于 2013-7-15 14:24
这个设计不合理,字符串合并的结果保存在一个静态的char array中,那么一次调用的结果会覆盖上一次调用的结 ...

char *begin = dest;--->指针变量dset在函数体内没有事先定义怎么就赋值给了begin?
我没有读懂这一行代码。望赐教,不胜感激。
7#
发表于 2013-7-15 14:54:50 | 只看该作者
嗨,强哥! 发表于 2013-7-15 14:48
char *begin = dest;--->指针变量dset在函数体内没有事先定义怎么就赋值给了begin?
我没有读懂这一行代码 ...

在参数列表里面定义了
8#
 楼主| 发表于 2013-7-15 14:54:57 | 只看该作者
rosynirvana 发表于 2013-7-15 14:24
这个设计不合理,字符串合并的结果保存在一个静态的char array中,那么一次调用的结果会覆盖上一次调用的结 ...

dest是实参,不必要再函数中在定义了,这样理解对了吗?呵呵,不好意思啊
9#
发表于 2013-7-15 14:57:12 | 只看该作者
嗨,强哥! 发表于 2013-7-15 14:54
dest是实参,不必要再函数中在定义了,这样理解对了吗?呵呵,不好意思啊

说实话我对一些术语的中文说法不大熟悉,但是dest应该是一个形式参数(parameter)吧
实际参数指的是函数调用时绑定在parameter上面那些变量
10#
 楼主| 发表于 2013-7-15 15:10:50 | 只看该作者
rosynirvana 发表于 2013-7-15 14:57
说实话我对一些术语的中文说法不大熟悉,但是dest应该是一个形式参数(parameter)吧
实际参数指的是函数调 ...

这样一改,主函数要修改吗?
11#
发表于 2013-7-15 15:18:13 | 只看该作者
嗨,强哥! 发表于 2013-7-15 15:10
这样一改,主函数要修改吗?

需要改啊,a和b是两个字符串的地址,dest是存储的位置的地址
12#
 楼主| 发表于 2013-7-15 15:25:33 | 只看该作者
本帖最后由 嗨,强哥! 于 2013-7-15 15:33 编辑
rosynirvana 发表于 2013-7-15 14:48
不不不,题目也没说除了两个首地址之外,不能使用其它的参数啊

对于您的函数有3个形参,我修改了主函数,竟然一次编译成功,呵呵。
-------------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
/*  编一个指针型函数,将两个字符串连接成一个字符串,函数返回值是连接后  */
/*  所得字符串的首地址。两个原始字符串的首地址作为函数的参数。在主函数  */
/*  中调用该函数,输入两个字符串,并输出连接后的字符串。(不得使用系统  */
/*  函数)                                                                                                              */

char *my_cat(char *a, char *b, char *dest)
{
    char *begin = dest;
    while(*a != '\0')
        *dest++ = *a++;
    while(*b != '\0')
        *dest++ = *b++;
    *dest = '\0';
    return begin;
}

int main()
{
    char s1[80],s2[80],s3[160],*p=s3;
    scanf("%s",s1);
    scanf("%s",s2);
    printf("%s\n",my_cat(s1,s2,p));
    printf("%s\n",my_cat(s2,s1,p));   
   
    system("pause");
    return 0;
}
13#
发表于 2013-7-15 15:27:46 | 只看该作者
其实p那个变量是不必要的,直接用s3就可以了

点评

您说的十分正确!感谢提醒。  发表于 2013-7-15 15:34
14#
 楼主| 发表于 2013-7-15 15:44:00 | 只看该作者
rosynirvana 发表于 2013-7-15 15:27
其实p那个变量是不必要的,直接用s3就可以了

修改后的:
----------------------

#include <stdio.h>
#include <stdlib.h>
/*  编一个指针型函数,将两个字符串连接成一个字符串,函数返回值是连接后  */
/*  所得字符串的首地址。两个原始字符串的首地址作为函数的参数。在主函数  */
/*  中调用该函数,输入两个字符串,并输出连接后的字符串。(不得使用系统  */
/*  函数)                                                                                                              */


char *my_cat(char *a, char *b, char *dest)
{
    char *begin = dest;
    while(*a != '\0')
        *dest++ = *a++;
    while(*b != '\0')
        *dest++ = *b++;
    *dest = '\0';
    return begin;
}


int main()
{
    char s1[80],s2[80],s3[160];
    scanf("%s",s1);
    scanf("%s",s2);
    printf("%s\n",my_cat(s1,s2,s3));
     printf("%s\n",my_cat(s2,s1,s3));   
   
    system("pause");
    return 0;
}

15#
发表于 2013-7-19 22:41:28 | 只看该作者
char字符需要%s进行提取。貌似教科·书里没有吧哪里学习的?

点评

是字符串  发表于 2013-7-19 22:52
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表