c++函数返回指针和引用

写一个常量字符串复制函数

我们以为的方式

写不了,我们把指针指向了这个常量区,看似拥有了,其实不属于str

我们需要把常量字符拿出来,让指针指向栈区或者堆区

#include<iostream>
using namespace std;
int clen(const char* str) {
	int len = 0;
	for (int i = 0; str[i]; i++) len++;
	return len;
}
char* cstr(const char* str) {
	int len = clen(str);
	char strRt[0x20];
	memcpy(strRt, str, len);
	return strRt;
}
int main() {
	char* str = cstr("你好");
	cout << str<<endl;
	return 0;
}

结果依然出错,因为strRt这个字符数组为局部变量传不出来

解决办法1-利用堆

char* cstr(const char* str) {
	int len = clen(str);
	char *strRt = new char[len];
	memcpy(strRt, str, len);
	return strRt;
}

解决办法2-将char数组定义为全局变量

char strRt[0x20];
char* cstr(const char* str) {
	int len = clen(str);
	memcpy(strRt, str, len);
	return strRt;
}

现成的字符串复制函数

strcpy
#include <cstring> //都在这个头文件里面

int main()
{
    char str1[20];
    char str2[20];
    std::cin.get(str2, 20);
    std::strcpy(str1, str2); //将str2的内容赋值到str1
    return 0;
}

但是strcpy是不安全的编译器会报warnning

两种方法可以解除

法一:\#pragma warning( disable : 4996)

法二:#define _CRT_SECURE_NO_WARNINGS

strcpy_s
	strcpy_s(str1, str2); //将str2的内容赋值到str1

没得任何警告

如果str1用new来创建时,就会报错

	char *str1 = new char[20];

这是因为strcpy_s()函数是有两个版本,用两个参数、三个参数都可以,只要可以保证缓冲区大小。
三个参数时:

errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );
两个参数时:
errno_t strcpy_s( char (&strDestination)[size], const char *strSource ); // C++ 独属

若我们使用new来分配储存空间时,就会出现上面说的不能保证缓冲区大小的问题了

语法来说没有什么问题,但是因为str的储存空间是使用new临时分配的,所以并不能保证缓冲区大小,点击运行就会出现上述的错误了。

这种情况的解决方法其实很简单,那就是不符合2个参数的版本就使用3个参数的版本呗。在两个str之间,加上一个参数,标识长度

	char * str;
    str = new char[20];
    strcpy_s(str, strlen(str1)+1, str1);

函数传入结构体参数

结构体尽量不返回实体,内存开销太大了,返回时候在栈里面也需要空间暂存,如果一张游戏地图有500个怪,开销太大了,所以选择用指针,反正指针只占32bit

用堆来新建角色

#include<iostream>
using namespace std;

typedef struct Role{
	const char* name;
	int Hp;
	int MaxHp;
	int Mp;
	int MaxMp;
	int lv;
}*PRole,ROLE;

int clen(const char* str) {
	int len = 0;
	for (int i = 0; str[i]; i++) len++;
	return len;
}
char* cstr(const char* str) {
	int len = clen(str);
	char* strRt = new char[len];
	memcpy(strRt, str, len);
	return strRt;
}
PRole CreateMonster(const char* name, int Hp, int Mp) {
	PRole rt = new ROLE{cstr(name),Hp,Hp,Mp,Mp }; //注意new传回的是地址
	return rt;
}
int main() {
	PRole rt = CreateMonster("你还", 1500, 1500);
	cout << rt->name << endl;
	return 0;
}

用引用来新建角色

引用的本质是指针,本质也是传出指针,还要注意引用使用时候的注意事项.不可用nullptr初始化引用

Role& CreateMonster(const char* name, int Hp, int Mp) {
	PRole rt = new ROLE{cstr(name),Hp,Hp,Mp,Mp }; //注意new传回的是地址
	return *rt; //注意这里返回的是Role实体
}
int main() {
	Role& rt = CreateMonster("你还", 1500, 1500);
	cout << rt.name << endl;
	return 0;
}

反汇编代码

	Role& rt = CreateMonster("你还", 1500, 1500);
01162685  push        5DCh  
0116268A  push        5DCh  
0116268F  push        offset string "\xc4\xe3\xbb\xb9" (01169BD4h)  
01162694  call        CreateMonster (01161578h)  
01162699  add         esp,0Ch  
0116269C  mov         dword ptr [rt],eax 
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值