ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【个人记录】字符串部分复制和指针参数单向传递的问题发现

2021-12-29 20:58:15  阅读:173  来源: 互联网

标签:strmncpy 函数 int 单向 char swap 字符串 指针


考前突击时在头歌遇到个题,我按照我的想法没有整出来,特此记录。

全是废话 大家不必点开阅读

一、原题描述

任务描述

本关任务:实现字符串的部分复制。

编程要求

在右侧编辑器中的Begin-End之间补充代码,实现字符串的部分复制。

提示

函数 strmncpy 的原型为:

  void strmncpy(char *s, int m, int n, char *t);

  • 参数 s 指向源字符串,t 指向字符串复制的目标单元,函数功能为将 s 指向字符串从第 m 个(从0开始编号)字符开始的连续 n 个字符复制到 t 指向的存储单元;

  • 如果第 m 个字符后面的字符数不足 n 个,则复制到 '\0'为止;

  • 如果 s 的长度不到 m,则复制空串。

例如:

  1. char *s = "abcdefghijklmn";
  2. char t[20];
  3. strmncpy(s,4,6,t);
  4. cout << t << endl;

输出结果为:efghij

测试说明

平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:

测试输入:

  1. abcdefghjkksdsd
  2. 5 7

预期输出:fghjkks

测试输入:

  1. asdftyuioplkm
  2. 3 9

预期输出:ftyuioplk

二、疑惑

这是正确的(从网上copy的)代码:

#include <iostream>
using namespace std;

void strmncpy(char *s, int m, int n, char *t);

int main()
{
    char s[128],t[128];
    int m,n;
    cin>>s;     // 输入源串
    cin>>m>>n;     // 输入m和n
    strmncpy(s, m, n, t);     // 字符串复制
    cout << t <<endl;     // 输出复制结果
    return 0;
}

// 函数strmncpy:字符串的部分复制,将s指向字符串从第m个字符开始的n个字符复制的t中
// 参数:s-指向源字符串,t-指向目标字符串,m-起始位置,n-字符个数
// 返回值:无
void strmncpy(char *s, int m, int n, char *t)
{
    // 请在此添加代码,实现函数strmncpy
    /********** Begin *********/
	
	//检测m是否超过s
	char *check = s;
	int position = 0;
	while(*check !='\0')
	{
		check ++;
		position ++;
	} 
	int i, j;
	if(position>=m)
	for(i=m, j=0; i<m+n; i ++, j ++)
	{
		t[j] = s[i];		
		if(s[i] == '\0')  break;
	} 
	t[j] = '\0'; 
    
    /********** End **********/
}

(一)、为什么在被调函数中,我的t仿佛什么都没有发生过一样

这是我的问题代码:

#include <iostream>
using namespace std;

void strmncpy(char *s, int m, int n, char *t);

int main()
{
    char s[128],t[128];
    int m,n;
    cin>>s;     // 输入源串
    cin>>m>>n;     // 输入m和n
    strmncpy(s, m, n, t);     // 字符串复制
    cout << t <<endl;     // 输出复制结果
    return 0;
}

// 函数strmncpy:字符串的部分复制,将s指向字符串从第m个字符开始的n个字符复制的t中
// 参数:s-指向源字符串,t-指向目标字符串,m-起始位置,n-字符个数
// 返回值:无
void strmncpy(char *s, int m, int n, char *t)
{
    // 请在此添加代码,实现函数strmncpy
    /********** Begin *********/
		t = s+m; 
	    *(t+n) = '\0';
	    //cout<<t<<endl;
    /********** End **********/
}

我的想法是:让t指向s+m的那个地址,然后令s+m+n的内容变成‘\0’,这样我就在输出字符串t时有了一个我确定的开头和一个确定的结尾'\0’。

问题表现在:尽管在strmcpy函数内进行cout<<t确实会输出正确结果,但当函数结束调用返回主函数时,t又恢复了调用函数前的样子,仿佛什么都没有发生。

三、问题解决

联想到前几天写的类似的题,我又进行了小小的修改:

我将函数类型由void改为char*,于是乎:

#include <iostream>
using namespace std;

char* strmncpy(char *s, int m, int n, char *t);

int main()
{
    char s[128],t[128];
    int m,n;
    cin>>s;     // 输入源串
    cin>>m>>n;     // 输入m和n
         // 字符串复制
    cout << strmncpy(s, m, n, t) <<endl;     // 输出复制结果
    return 0;
}

// 函数strmncpy:字符串的部分复制,将s指向字符串从第m个字符开始的n个字符复制的t中
// 参数:s-指向源字符串,t-指向目标字符串,m-起始位置,n-字符个数
// 返回值:无
char* strmncpy(char *s, int m, int n, char *t)
{
    // 请在此添加代码,实现函数strmncpy
    /********** Begin *********/
		t = s+m; 
	    *(t+n) = '\0';
	    //cout<<t<<endl;
	    return t;
    /********** End **********/
}

是没有问题的。当然没有问题,你都return回去了嘛

这说明之前写的那个问题代码,它在被调函数中对t的改变并不会影响到main函数的t,即:该函数被调前后,main函数的t仍是空字符串。

这就像下面这个swap函数的单向传递一样:

#include <iostream>
using namespace std;
void swap(int *, int *);
int main()
{
    int a = 2, b = 5;
    cout<<"swap前:"<<endl;
    cout<<"a="<<a<<" b="<<b<<endl<<"&a="<<&a<<" &b="<<&b<<endl; 
    swap(&a, &b);
    cout<<"swap后:"<<endl;
    cout<<"a="<<a<<" b="<<b<<endl<<"&a="<<&a<<" &b="<<&b<<endl;
    return 0;
}

void swap(int *x, int *y)	//实际上是*(&a), *(&b),取a和b所在地址上的内容(即a和b) 
{
    int t = *x;		//现在的x,y 都是地址 
    *x = *y;
    *y = t;
    //试图交换地址
    int *p = x;
	x = y;
	y = p; 
}

 

 如上,在内容交换的过程中,被调函数swap确实让主函数的a,b发生了改变,但是swap()没有改变指针的值。

在我的教科书上它是这么解释的:

void swap2(int *p1, int *p2)

{

        int *p;

        p = p1; p1 = p2; p2 = p;

}

如有函数调用swap2(pa, pb), 其中实参pa、pb分别指向a、b的指针变量。swap2()函数调用过程如图4-9所示。实参pa、pb传递给形参p1、p2,函数交换了p1,p2的值,但pa和pb的值不变,*pa、*pb即a、b的值也不会交换。

 我豁然开朗,回头看看我的问题代码:

void strmncpy(char *s, int m, int n, char *t);

这条声明把t改成x的话,我将很明显地理解为什么我的有问题:

就像定义函数swap(int a,int b)一样,任你在swap里怎么改变形参a和b,它并不会影响实参(这个实参即使命名是a, b,也绝不是swap的那两个形参);所以调用strmncpy(s, m, n, t),任你形参x怎么变化,它的变化都无法影响到主函数的t中。

我已经完全理解了.jpg

(虽然我可能下次碰到这样的事情又会栽倒……)

此外,在临时抱佛脚的复习时,我还留意到课本讨论指针函数int *f(形参表)的这段话,特此记录以防遗忘:

指针函数返回值不能使本函数中的局部变量的地址,因为本函数执行完毕返回主调函数后,函数的局部变量全部释放,主调函数再去访问它,不能保证结果正确。返回值可以是主调函数中的局部变量的地址、数组元素的地址或全局变量的地址等。

不过很显然,int f(形参表)或者double f(形参表)或者一些其他函数是可以return 本函数的局部变量。二者不要混淆。

标签:strmncpy,函数,int,单向,char,swap,字符串,指针
来源: https://blog.csdn.net/Hisser/article/details/122205664

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有