[C++基础] 自定义函数篇
自定义函数篇
1 不使用C/C++字符串库函数,如何自行编写strcpy()函数?
char * strcpy(char *strDest, const char *strSrc)
{
assert((strDest!=NULL) && (strSrc!=NULL));
char *address = strDest;
while( (*strDest++ = *strSrc++) != '\0');
return address ;
}
返回类型为char *主要是为了实现链式表达式。例如:
int length=strlen(strcpy(strDest, "hello world"));
strcpy(strDest, strcpy(strDest1, strSrc));
可以将strSrc复制到strDest1与strDest中,也就是说,可以将函数的返回值做为另一个函数的参数。
2 如何把数字转换成字符串?
C语言中常用到字符串与数字之间的相互转换,常见的此类库函数有atof (字符串转换成浮点数)、atoi (字符串转换成整型数)、atol (字符串转换成长整型数)、itoa (整型数转换成字符串)、ltoa (长整型数转换为字符串)等。
以自定义Myatoi()与Myitoa()函数为例,分别实现自定义字符串转换为整型数函数与自定义整型数转换为字符串函数。以下为自定义Myatoi()函数的实现以及测试代码:
#include<stdio.h>
int Myatoi(char *str)
{
if(str = NULL)
{
printf("Invalid Input");
return -1;
}
while(*str = '') // 跳过开头的空格字符
{
str++;
}
// '0xA1'是不打印字符,一般是占两个字节的汉字
while((*str==(char)0xA1) && (*(str+1)==(char)0xAA))
{
str += 2;
}
int nSign = (*str = '-')?-1:1; // 确定符号位
if(*str='+' || *str='-')
{
*str++;
}
int nResult = 0;
while(*str>='0' && *str<='9')
{
nResult = nResult*10 + (*str-0);
*str++;
}
return nResult * nSign;
}
int main()
{
printf(""%d\n",Myatoi("12345")); // 输出:12345
return 0;
}
以下为自定义Myitoa函数的实现以及测试代码:
#include <stdio.h>
char *Myitoa(int num)
{
char str[1024];
int sign = num,i = 0,j = 0;
char temp[11];
// 如果为负数,则转换为其绝对值
if(sign<0)
{
num = -num;
};
// 数字转换为倒序的字符数组
do
{
temp[i] = num%10 + '0';
num/=10;
i++;
}while(num>0);
// 字符数组加上“符号”
if(sign<0)
{
temp[i++] = '-';
}
// 转换为字符串
temp[i] = '\0';
// 将字符串反转
i—-;
while(i>=0)
{
str[j] = temp[i];
j++;
i--;
}
str[j] ='\0';
return str;
}
int main()
{
printf("%s\n",Myitoa(-12345)); // 输出:12345
return 0;
}
3 将字符串翻转?
#include "stdafx.h"
#include<iostream>
using namespace std;
#define swap(a,b) a=a^b,b=a^b,a=a^b
// 将一个字符串翻转 在不使用额外数据结构和储存空间的情况下
// 注 只能翻转字符数组,翻转字符指针会导致程序崩溃
char* strRev(char *str)
{
int len = strlen(str);
for (int i = 0, j = len - 1; i<j; i++, j--) // 不能是i<=j
swap(str[i], str[j]);
return str;
}
int main(void)
{
char str[6] = "abcde";
strRev(str);
cout << str << endl; // 输出:edcba
}
4 确定字符互斥的两种方法?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
// 确定字符互异方法1-通过string实现 (本质都是通过"遍历"实现)
// 确定字符互异:确定一个字符串的所有字符是否全都不同。
// True代表所有字符全都不同,False代表存在相同的字符。
class Different {
public:
bool checkDifferent(string iniString) {
string str = iniString;
char c;
for (unsigned int i = 0; i<str.length(); i++)
{
c = str.at(i);
for (unsigned int j = i + 1; j<str.length(); j++)
{
if (c == str.at(j))
return false;
}
}
return true;
}
};
// 确定字符互异方法2-通过char*实现 (本质都是通过"遍历"实现)
// 确定字符互异:确定一个字符串的所有字符是否全都不同。
// 返回1代表所有字符全都不同,返回0代表存在相同的字符。
int check(char *str)
{
char *t_str = str;
int len = strlen(str);
char c;
int i, j;
for (i = 0; i<len; i++)
{
c = t_str[i];
for (j = i + 1; j<len; j++)
{
if (c == t_str[j])
return 0;
}
}
return 1;
}
int main(void)
{
Different temp;
temp.checkDifferent("abcd") ? cout << "true" << endl : cout << "false" << endl; // 输出:true
check("abacd") ? cout << "true" << endl : cout << "false" << endl; // 输出:false
}
5 如何自定义内存复制函数memcpy()?
memcpy 是 C 语言中的内存复制函数,它的函数原型为void \*memcpy(void \*dest, const void\*src, size_t n)
。它的目的是将 src 指向地址为起始地址的连续 n 个字节的数据复制到以 dest 指向地址为起始地址的空间内,函数返回指向 dest 的指针。需要注意的是,src 和 dest 所指内存区域不能重叠,同时,与 strcpy 相比,memcpy 遇到 ’\0’ 不结束,而是一定会复制完 n 个字节。
自定义内存复制函数示例如下:
#include <stdio.h>
void *MyMemCpy(void *dest, const void *src, size_t count)
{
char *pdest = static_cast<char*>(dest);
const char *psrc = static_cast<const char*>(src);
if((pdest>psrc) && (pdest<(psrc+count))) // 这种情况:MyMemCpy(str+1, str+0, 9);
{
for(size_t i=count-l; i!=-l; —-i)
pdest[i] = psrc[i];
}
else
{
for(size_t i=0; i<count; ++i) // 这种情况:MyMemCpy(str, str+5, 5);
pdest[i] = psrc[i];
}
return dest;
}
int main()
{
char str[] = "0123456789";
MyMemCpy(str+1, str+0, 9);
printf("%s\n",str);
MyMemCpy(str, str+5, 5);
printf("%s\n",str);
return 0;
}
6 将整型数倒序?
// 将一个整型数字倒序 例12->21 100->1
int fun(int num)
{
int s = 0;
while(num)
{
s = s*10 +num%10;
num/=10;
}
return s;
}
7 字符串循环右移的2种方法?
#include <iostream>
#include <string.h>
using namespace std;
// 循环右移,库函数实现 例如step=2, abcd -> cdab
void loopRightStr(char *str, int step)
{
char tmp[100];
int len = strlen(str);
strcpy(tmp, str + step); // 先复制"abcd"的cd
strcpy(tmp + step, str); // 再复制"abcd"的ab cd
*(tmp + len) = '\0'; // 使用'\0'来截断,去掉后面的cd\0
strcpy(str, tmp); // 再将tmp拷贝给str
}
// 循环右移,不用库函数实现 例如step=2, abcd -> cdab
void loopRightStr2(char *str, int step)
{
char tmp[100];
int len = strlen(str);
for (int i = 0; i<step; i++)
{
tmp[i] = *(str + 2 + i);
}
for (int i = step; i<len; i++)
{
tmp[i] = *(str - step + i);
}
tmp[len] = '\0';
for (int i = 0; i<len; i++)
str[i] = tmp[i]; // 再将tmp拷贝给str
}
int main(void)
{
char str[5] = "abcd";
loopRightStr2(str, 2);
cout << str << endl; // 输出:cdab
}
8 判断是否为回文字符串,是回文字符串,返回1,不是返回0?
#include "stdafx.h"
#include <iostream>
#include <string.h>
using namespace std;
int fun(char *str)
{
int len = strlen(str);
for (int i = 0, j = len - 1; i<j; i++, j--)
{
if (str[i] != str[j])
return 0;
}
return 1;
}
int main(void)
{
char str[7] = "abcba"; //回文:从左读和从右读都是一样的
cout << fun(str) << endl; // 输出 1
}
9 写一个函数?
当参数为 n(n很大)时的值 1-2+3-4+5-6+7......+n。
long fun(long n)
{
if (n <= 0)
{
printf("error:n must > 0!\n");
exit(1);
}
if (0 == n % 2)
return (n / 2)*(-1);
else
return (n / 2)*(-1) + n;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!