【C++ 语言】C++字符串 ( string 类 | 创建方法 | 控制台输出 | 字符串操作 | 栈内存字符串对象 | string* )(二)

简介: 【C++ 语言】C++字符串 ( string 类 | 创建方法 | 控制台输出 | 字符串操作 | 栈内存字符串对象 | string* )(二)

C++ 字符串 方法调用 ( 堆内存对象 )


C++ 字符串 堆内存对象 方法调用 :


1.堆内存对象创建 : 使用 new 创建的 string 对象 需要在堆内存中为其分配内存 , 返回的是 string* 指针类型 ;

//使用 new 创建的对象 , 就不能使用 . 访问其方法和变量 , 需要使用 -> 符号进行访问 
  // -> 相当于 (*). 运算, 先读取指针内容 , 然后访问其方法或变量
  string* string_c_plus_7 = new string(" New String ");


1.获取字符串长度 : 调用 string 对象的 size() 方法 , 即可返回字符串长度 ; 需要使用 -> 代替 . 操作 ;

//① 获取字符串长度 : 
  int string_c_plus_7_size = string_c_plus_7->size();


2.判断字符串是否为空 : 调用 string 对象的 empty() 方法 , 判断字符串是否为空 ; 需要使用 -> 代替 . 操作 ;

//② 判断字符串是否为空 : 
  bool string_c_plus_7_empty = string_c_plus_7->empty();


3.使用指针的好处 :

① 扩大作用域 : 如果在栈内存中使用 , 有作用域限制 , 出了栈内存 作用域 , 该对象就无效了 ;

② 方便参数传递 : 指针 大小为 4 ( 32 位系统 ) 或 8 ( 64 位系统 ) 个字节 , 其当做参数传递 比直接传递对象 ( 动辄几十上百字节甚至更高 ) 效率更高 ;

4.代码示例 :

//使用 new 创建的对象 , 就不能使用 . 访问其方法和变量 , 需要使用 -> 符号进行访问 
  // -> 相当于 (*). 运算, 先读取指针内容 , 然后访问其方法或变量
  string* string_c_plus_7 = new string(" New String ");
  //① 获取字符串长度 : 
  int string_c_plus_7_size = string_c_plus_7->size();
  cout << "string_c_plus_7 : " << string_c_plus_7_size << endl;
  //② 判断字符串是否为空 : 
  bool string_c_plus_7_empty = string_c_plus_7->empty();
  cout << "string_c_plus_7_empty : " << string_c_plus_7_empty << endl;
  //释放堆内存
  delete string_c_plus_7;
  //使用指针的好处 : 
  // ① 如果在栈内存中使用 , 有作用域限制 , 出了栈内存 作用域 , 该对象就无效了 ; 
  // ② 指针 大小为 4 ( 32 位系统 ) 或 8 ( 64 位系统 ) 个字节 , 
  //   其当做参数传递 比直接传递对象 ( 动辄几十上百字节甚至更高 ) 效率更高


5.运行结果 :

string_c_plus_7 : 12
string_c_plus_7_empty : 0


image.png



C / C++ 字符串 完整代码示例



/ 001_CMake_1.cpp: 定义应用程序的入口点。
//
#include "001_CMake_1.h"
#include "c_extern.h"
using namespace std;
//定义方法接收 int& 引用类型变量
//并在方法中修改该变量的值
void quote(int& b) {
  b = 888;
}
int main()
{
  cout << "Hello CMake。" << endl;
  //1. C C++ 兼容
  //博客地址 : https://hanshuliang.blog.csdn.net/article/details/98840708
  //调用 c_extern.h 头文件中定义的方法
  //该方法定义在了 C 语言文件中
  add(1, 2);
  //2. 引用数据类型
  //博客地址 : https://hanshuliang.blog.csdn.net/article/details/99239635
  //代码 展示 流程 : 
  //① 定义 普通 类型 变量
  int a = 8;
  //② 定义 引用类型变量, 格式 : 类型名称& 变量名 = 对应类型变量名称 ;
  int& b = a;
  //③ 调用函数传入引用类型参数 : 将引用类型传给接收引用类型的方法
  quote(b);
  //④ 打印引用数据类型的修改结果 , 结果是 b 被修改成了 888
  cout << b << endl;
  //引用数据类型定义与使用 : 
  // ① 引用数据类型定义 : 类型名称& 变量名 = 对应类型变量名称 ;
  // ② 引用数据类型的使用方法 : 直接当做原来的变量使用即可, 可以替换原来变量的位置使用
  //引用类型解析 : 
  // ① int& 是引用数据类型 , b 是 a 的引用 
  // ② 分配一块内存存放 int 类型数据 8 , 将该内存赋予一个别名 a
  // ③ 同时又给该内存赋予另外一个别名 b 
  //3. 字符串使用
  //C 字符串 表示方法 : 
  // ① 字符数组 : 本质是 字符 数组 char[] , 这里注意字符数组要以 NULL 或 '\0' 结尾; 
  char string_c[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
  // ② 指针 : 使用指针形式表示字符串 , 默认末尾增加 '\0' ;
  char* string_c_p = "hello";
  //字符串打印 : 
  // ① 打印字符串 , cout 后的 << 后可以打印 字符串 , 也可以打印变量
  // ② 输出 cout << 字符串或变量1 << 字符串或变量2 ... << endl 可以拼接 输出信息
  cout << "string_c : " << string_c << endl;
  cout << "string_c_p : " << string_c_p << endl;
  //C 语言中的字符串操作
  //拷贝字符串 
  char string_c_copy_destination[6];
  char string_c_copy_source[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
  // ① 参数 : strcpy 方法是拷贝字符串的方法 , 第一个参数是目标字符串 , 第二个参数是源字符串
  // ② 作用 : 该方法是将 源字符串 拷贝到 目标字符串中
  strcpy(string_c_copy_destination, string_c_copy_source);
  // ③ 打印拷贝结果 : 
  cout << "string_c_copy_destination : " << string_c_copy_destination << endl;
  //拼接字符串 
  //① 定义目标字符串 : 拼接字符串的目标字符串的大小一定要大于等于要拼接的两个字符串大小之和, 否则会报错
  char string_c_cat_destination[30] = " cat dst ";
  char string_c_cat_source[] = " cat src ";
  //② 拼接字符串方法参数 : 第一个参数是目标字符串 , 第二个参数是源字符串
  //③ 目标字符串大小 : 注意 目标字符串的 大小一定要大于 两个字符串实际大小
  strcat(string_c_cat_destination, string_c_cat_source);
  //④ 打印字符串拼接结果 : 
  cout << "string_c_cat_destination : " << string_c_cat_destination << endl;
  //获取字符串长度
  //① 参数 : 传入要获取的字符串 , 该长度不含 '\0' 结尾标志
  //② 作用 : 获取实际的字符串长度 , 即自动识别 '\0' 位置 , 获取其长度 , 与所占用的内存大小无关
  char string_c_len[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
  char string_c_len2[20] = { 'h', 'e', 'l', 'l', 'o', '\0' };
  char * string_c_len3 = "hello";
  //① 字符数组长度 , 测量从开始到 '\0' 的长度, 不包括 '\0'
  int len1 = strlen(string_c_len);
  //② 指定大小的字符数组长度 , 结果不是指定的大小的值 , 获取的是实际字符串长度
  int len2 = strlen(string_c_len2);
  //③ 指针表示的字符串 , 其获取的大小是实际字符串大小, 不包含自动添加的 '\0' 
  int len3 = strlen(string_c_len3);
  //④ 打印 三个字符串大小
  cout << "len1 : " << len1
  << " len2 : " << len2
  << " len3 : " << len3
  << endl;
  //字符串比较
  // ① 参数说明 : 参数是需要比较的两个字符串 , 第一个参数 str1 , 第二个参数 str2
  // ② 对比规则 : str1 和 str2 两个字符串 , 从左到右 逐个对比 ASCII 码 大小 ; 
  //  a. 如果 str1 等于 str2 , 返回 0; 
  //  b. 如果 str1 > str2 , 返回值 大于 0 ;
  //  c. 如果 str1 < str2 , 返回值 小于 0 ;
  //定义需要比较的字符串
  char* string_c_comp_1 = "Hello";
  char* string_c_comp_2 = "Hello";
  char* string_c_comp_3 = "hello";
  // ① 两个字符串相等
  int cmp_result_1_2 = strcmp(string_c_comp_1, string_c_comp_2);
  // ② "Hello" 字符串 (H 对应 ASCII 72) 小于 "hello" 字符串 (h 对应 ASCII 104) , 返回值 小于 0
  int cmp_result_1_3 = strcmp(string_c_comp_1, string_c_comp_3);
  // ③ "hello" 字符串 (h 对应 ASCII 104) 大于 "Hello" 字符串 (H 对应 ASCII 72) , 返回值 大于 0
  int cmp_result_3_1 = strcmp(string_c_comp_3, string_c_comp_1);
  //输出字符串对比结果
  cout << "cmp_result_1_2 : " << cmp_result_1_2 
  << " cmp_result_1_3 : " << cmp_result_1_3
  << " cmp_result_3_1 : " << cmp_result_3_1
  << endl;
  // C++ string 类 : 该类定义在 iostream 头文件中
  //创建 string 类型对象有三种方法 : 
  //① 直接使用字符串赋值 
  //② 调用构造方法赋值 
  //③ 最后可以调用 new 为字符串分配一块内存
  //① 使用字符串赋值
  string string_c_plus_1 = " Hello ";
  //② 调用构造方法 初始化字符串
  string string_c_plus_2(string_c_plus_1);
  string string_c_plus_3(" World ");
  //上面的三种字符串不需要释放 , 因为其定义在栈内存中 , 下面使用 new 创建字符串的情况需要 delete 释放内存 ; 
  //③ 使用 new 申请的内存 , 需要使用 delete 释放
  string *string_c_plus_4 = new string(" New ");
  delete string_c_plus_4;
  //使用 new [] 申请的数组 , 需要使用 delete[] 释放
  //使用 malloc 申请的内存 , 需要使用 free 释放
  //C++ 字符串输出
  //字符串对象不能直接在 cout 中输出, cout << string string_c_plus_5 << endl; 是错误的
  //cout << string_c_plus_2 << endl;
  //要将 string 对象打印到控制台上, 需要将其转为 C 字符串 , char* 或 char[] 才能输出
  cout << string_c_plus_1.c_str() << endl;
  //C++ 字符串拼接
  //① "+" : 操作符重载 , 重新定义了 加号运算符的行为 , 这里加号可以实现字符串拼接 , 与 Java 类似
  //② 调用 string 对象的 append 方法 , 拼接字符串
  string string_c_plus_5 = string_c_plus_1 + string_c_plus_3;
  string string_c_plus_6 = string_c_plus_1.append( string_c_plus_3 );
  //输出拼接的字符串
  cout << string_c_plus_5.c_str() << endl;
  cout << string_c_plus_6.c_str() << endl;
  //获取 C++ 字符串长度 : 调用 string 对象的 size() 方法 , 获取字符串长度
  int string_c_plus_1_size = string_c_plus_1.size();
  cout << "string_c_plus_1_size : " << string_c_plus_1_size << endl;
  //判断 C++ 字符串是否为空 : 调用 string 对象的 empty() 方法 ; 
  bool string_c_plus_1_empty = string_c_plus_1.empty();
  cout << "string_c_plus_1_empty : " << string_c_plus_1_empty << endl;
  //使用 new 创建的对象 , 就不能使用 . 访问其方法和变量 , 需要使用 -> 符号进行访问 
  // -> 相当于 (*). 运算, 先读取指针内容 , 然后访问其方法或变量
  string* string_c_plus_7 = new string(" New String ");
  //① 获取字符串长度 : 
  int string_c_plus_7_size = string_c_plus_7->size();
  cout << "string_c_plus_7 : " << string_c_plus_7_size << endl;
  //② 判断字符串是否为空 : 
  bool string_c_plus_7_empty = string_c_plus_7->empty();
  cout << "string_c_plus_7_empty : " << string_c_plus_7_empty << endl;
  //释放堆内存
  delete string_c_plus_7;
  //使用指针的好处 : 
  // ① 如果在栈内存中使用 , 有作用域限制 , 出了栈内存 作用域 , 该对象就无效了 ; 
  // ② 指针 大小为 4 ( 32 位系统 ) 或 8 ( 64 位系统 ) 个字节 , 
  //   其当做参数传递 比直接传递对象 ( 动辄几十上百字节甚至更高 ) 效率更高 
  return 0;
}



目录
相关文章
|
20天前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
|
20天前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
|
2月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
99 12
|
4月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
3月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
81 16
|
3月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
3月前
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
4月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
3月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
219 6
|
3月前
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!

热门文章

最新文章