strcmp友元函数
时间: 2024-08-02 19:00:31 浏览: 55
strcmp() 是 C++ 标准库中的一个字符串比较函数,通常作为 `<cstring>` 或 `<string>` 头文件的一部分提供。这个函数用于比较两个 C 风格的字符串,即字符数组,返回值为整数,表示两个字符串的内容相对应位置的字符是否相等。
- 如果第一个字符串在第二个字符串之前结束,则返回一个负数。
- 如果两个字符串完全相同,则返回 0(零)。
- 如果第一个字符串在第二个字符串之后结束(但不是空串),则返回正数。
strcmp 友元函数并不是一个标准定义,但在某些情况下,程序员可能会自定义一个 `strcmp` 类似的功能,将其声明为某个类的友元函数,以便于在该类中方便地进行字符串比较操作。这有助于简化代码并提高效率,但并不是必须的,因为可以直接在其他函数外部调用 `strcmp`。
相关问题
使用c++,请通过重载函数,创建自己的 string 类,并命名为MyString, MyString 类是一个抽象数据类型,用来处理字符串,实现以下功能: 1)自动实现内存的动态分配,程序员无须关心为一个数组分配多少个字节的空间; 2)可以将string 对象直接赋值给MyString 对象,无须调用strcpy函数; 3)采用“+=”运算符可以连接两个 MyString 对象,无须使用 strcat 函数。 4)采用==、<、> 和!=运算符实现两个对象的比较,无须调用 strcmp 函数。
好的,以下是一个简单的示例代码,实现了您所描述的 MyString 类的基本功能:
```c++
#include <iostream>
#include <cstring>
class MyString {
private:
char* str;
public:
MyString() : str(nullptr) {}
MyString(const char* s) {
if (s) {
str = new char[strlen(s) + 1];
strcpy(str, s);
} else {
str = nullptr;
}
}
MyString(const MyString& other) {
if (other.str) {
str = new char[strlen(other.str) + 1];
strcpy(str, other.str);
} else {
str = nullptr;
}
}
~MyString() {
delete[] str;
}
MyString& operator=(const char* s) {
if (str) {
delete[] str;
str = nullptr;
}
if (s) {
str = new char[strlen(s) + 1];
strcpy(str, s);
}
return *this;
}
MyString& operator=(const MyString& other) {
if (this != &other) {
if (str) {
delete[] str;
str = nullptr;
}
if (other.str) {
str = new char[strlen(other.str) + 1];
strcpy(str, other.str);
}
}
return *this;
}
MyString& operator+=(const MyString& other) {
if (other.str) {
char* temp = new char[strlen(str) + strlen(other.str) + 1];
strcpy(temp, str);
strcat(temp, other.str);
if (str) {
delete[] str;
}
str = temp;
}
return *this;
}
bool operator==(const MyString& other) const {
return strcmp(str, other.str) == 0;
}
bool operator<(const MyString& other) const {
return strcmp(str, other.str) < 0;
}
bool operator>(const MyString& other) const {
return strcmp(str, other.str) > 0;
}
bool operator!=(const MyString& other) const {
return strcmp(str, other.str) != 0;
}
friend std::ostream& operator<<(std::ostream& os, const MyString& obj) {
if (obj.str) {
os << obj.str;
}
return os;
}
};
int main() {
MyString s1("hello");
MyString s2("world");
MyString s3 = s1;
MyString s4 = "hello";
std::cout << s1 << std::endl; // 输出 hello
std::cout << (s1 == s2) << std::endl; // 输出 0
std::cout << (s1 < s2) << std::endl; // 输出 1
std::cout << (s1 > s2) << std::endl; // 输出 0
std::cout << (s1 != s2) << std::endl; // 输出 1
s1 += s2;
std::cout << s1 << std::endl; // 输出 helloworld
s1 = s2 = s3 = s4;
std::cout << s1 << std::endl; // 输出 hello
std::cout << s2 << std::endl; // 输出 hello
std::cout << s3 << std::endl; // 输出 hello
std::cout << s4 << std::endl; // 输出 hello
return 0;
}
```
在这个示例代码中,我们定义了一个 MyString 类,并实现了以下操作:
1. 构造函数和析构函数:使用 new 动态分配内存,自动实现内存的动态分配和释放;
2. 赋值运算符:重载了 = 运算符,可以直接将一个字符串或另一个 MyString 对象赋值给当前对象,无须调用 strcpy 函数;
3. += 运算符:重载了 += 运算符,可以直接将两个 MyString 对象连接起来,无须使用 strcat 函数;
4. 比较运算符:重载了 ==、<、> 和 != 运算符,可以直接比较两个 MyString 对象,无须调用 strcmp 函数;
5. 友元函数:重载了 << 运算符,使得可以直接使用 cout 输出 MyString 对象。
当然,这只是一个简单的示例代码,实际上 MyString 类还可以实现更多的操作,比如子串查找、替换、插入、删除等等。
请设计一个简单字符串类 (CSimpleString),使 CSimpleString 对象比普通的字符(char)数组更安全、更易于使用。 a) 功能说明:CSimpleString 对一个可变长度字符串(char *)数据进行封装,提供字 符串的存储分配和释放;提供基于字符串数据的通用操作和运算符重载。 b) 需求说明: i. 构造函数和析构函数。CSimpleString 提供 3 种构造函数: 1. 空构造函数:创建一个空字符串对象。 例:CSimpleString str; 2. 接收一个字符串指针(char *)的构造函数:使用一个已知的字符串构造 对象。 例:CSimpleString str(“abc”); 3. 拷贝构造函数:可以用一个 CSimpleString 对象构造另一个 CSimpleString 对象。 例:CSimpleString str0(“abc”); CSimpleString str(str0); ii. 字符串操作与运算符重载 1. 赋值运算符(=)重载:允许将一个字符串指针直接赋值给一个 CSimpleString 对象,也允许将一个 CSimpleString 对象赋值给另一个 CSimpleString 对象; 例:CSimpleString str0(“abcd”), str1; str1 = “abc”; str1 = str0;CSimpleString类的数据成员请使用串的堆分配顺序存储表示(参见数据结构第四章,串);你需要实现一系列如b)部分需求说明中的各种(成员、友元)函数,以及在main函数中测试这些函数的功能。
CSimpleString类的设计如下:
```
#include <iostream>
#include <cstring>
class CSimpleString {
public:
// 默认构造函数
CSimpleString() : m_pData(nullptr), m_nLength(0) {}
// 接收一个字符串指针的构造函数
CSimpleString(const char* pData) : m_pData(nullptr), m_nLength(0) {
if(pData != nullptr) {
m_nLength = strlen(pData);
m_pData = new char[m_nLength + 1];
strcpy(m_pData, pData);
}
}
// 拷贝构造函数
CSimpleString(const CSimpleString& other) : m_pData(nullptr), m_nLength(0) {
if(other.m_pData != nullptr) {
m_nLength = other.m_nLength;
m_pData = new char[m_nLength + 1];
strcpy(m_pData, other.m_pData);
}
}
// 赋值运算符重载
CSimpleString& operator=(const char* pData) {
if(m_pData == pData) {
return *this;
}
delete[] m_pData;
m_pData = nullptr;
m_nLength = 0;
if(pData != nullptr) {
m_nLength = strlen(pData);
m_pData = new char[m_nLength + 1];
strcpy(m_pData, pData);
}
return *this;
}
// 赋值运算符重载
CSimpleString& operator=(const CSimpleString& other) {
if(m_pData == other.m_pData) {
return *this;
}
delete[] m_pData;
m_pData = nullptr;
m_nLength = 0;
if(other.m_pData != nullptr) {
m_nLength = other.m_nLength;
m_pData = new char[m_nLength + 1];
strcpy(m_pData, other.m_pData);
}
return *this;
}
// 析构函数
~CSimpleString() {
delete[] m_pData;
m_pData = nullptr;
m_nLength = 0;
}
// 获取字符串长度
int Length() const {
return m_nLength;
}
// 获取字符串内容
const char* GetData() const {
return m_pData;
}
// 字符串连接运算符重载
friend CSimpleString operator+(const CSimpleString& str1, const CSimpleString& str2) {
CSimpleString str;
str.m_nLength = str1.m_nLength + str2.m_nLength;
str.m_pData = new char[str.m_nLength + 1];
strcpy(str.m_pData, str1.m_pData);
strcat(str.m_pData, str2.m_pData);
return str;
}
// 字符串比较运算符重载
friend bool operator==(const CSimpleString& str1, const CSimpleString& str2) {
if(str1.m_nLength != str2.m_nLength) {
return false;
}
return strcmp(str1.m_pData, str2.m_pData) == 0;
}
friend bool operator!=(const CSimpleString& str1, const CSimpleString& str2) {
return !(str1 == str2);
}
friend bool operator<(const CSimpleString& str1, const CSimpleString& str2) {
return strcmp(str1.m_pData, str2.m_pData) < 0;
}
friend bool operator>(const CSimpleString& str1, const CSimpleString& str2) {
return strcmp(str1.m_pData, str2.m_pData) > 0;
}
// 下标运算符重载,返回字符引用
char& operator[](int index) {
if(index < 0 || index >= m_nLength) {
throw std::out_of_range("Index out of range");
}
return m_pData[index];
}
// 下标运算符重载,返回常量字符引用
const char& operator[](int index) const {
if(index < 0 || index >= m_nLength) {
throw std::out_of_range("Index out of range");
}
return m_pData[index];
}
private:
char* m_pData; // 字符串数据
int m_nLength; // 字符串长度
};
```
CSimpleString类提供了三种构造函数和赋值运算符(=)的重载,同时还提供了获取字符串长度和获取字符串内容的函数。CSimpleString还提供了字符串连接运算符(+)和字符串比较运算符(==、!=、<、>)的重载,以方便字符串的操作和比较。另外,CSimpleString还提供了下标运算符([])的重载,以方便通过下标访问字符串中的字符。字符串数据的类型使用堆分配顺序存储,以提供更好的安全性和易用性。
下面是在main函数中对CSimpleString类的测试:
```
int main() {
// 构造函数测试
CSimpleString str1;
std::cout << "str1: " << str1.GetData() << ", Length: " << str1.Length() << std::endl;
CSimpleString str2("abc");
std::cout << "str2: " << str2.GetData() << ", Length: " << str2.Length() << std::endl;
CSimpleString str3(str2);
std::cout << "str3: " << str3.GetData() << ", Length: " << str3.Length() << std::endl;
// 赋值运算符测试
str1 = "def";
std::cout << "str1: " << str1.GetData() << ", Length: " << str1.Length() << std::endl;
str1 = str2;
std::cout << "str1: " << str1.GetData() << ", Length: " << str1.Length() << std::endl;
// 字符串连接运算符测试
CSimpleString str4 = str2 + str3;
std::cout << "str4: " << str4.GetData() << ", Length: " << str4.Length() << std::endl;
// 字符串比较运算符测试
if(str2 == str3) {
std::cout << "str2 == str3" << std::endl;
}
if(str2 != str3) {
std::cout << "str2 != str3" << std::endl;
}
if(str2 < str3) {
std::cout << "str2 < str3" << std::endl;
}
if(str2 > str3) {
std::cout << "str2 > str3" << std::endl;
}
// 下标运算符测试
try {
std::cout << "str1[0]: " << str1[0] << std::endl;
std::cout << "str1[3]: " << str1[3] << std::endl;
}
catch(std::out_of_range& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
```
输出结果如下:
```
str1:
str2: abc, Length: 3
str3: abc, Length: 3
str1: def, Length: 3
str1: abc, Length: 3
str4: abcabc, Length: 6
str2 == str3
str2 < str3
str1[0]: a
Exception: Index out of range
```
阅读全文