上篇文章说了C与C++区别中的 头文件命名空间 、 using语法 、 引用类型(常引用 右值引用) 、 基本的输入输出 、 函数思想。
这次我们再来看看C++ 中结构体 动态内存申请 内存池 string类型 这四种内容的区别
1.结构体与C语言不同的是 C++能在结构体中定义或者申明函数 在结构体中申明的函数可以通过结构体名+作用域标识符(结构体限定名) 来在结构体外定义函数 (结构体中定义的函数叫做成员函数,也叫做行为(方法))
#includeusing namespace std; struct A{ int a; float b; void print(); //结构体中的函数申明 }; //通过作用域标识符在结构体外定义 void A::print(){ cout<
C++中通过结构体定义对象(结构体变量)时可以省略 struct 关键字 直接通过结构体名来定义。
简化了定义的步骤 ,当然也可以通过 struct 关键字来定义 ,不做硬性规定
struct student std; //定义一个std对象(结构体变量)
student std; //定义一个std对象
这两行代码本质是一样的。
对于结构体变量成员的访问 C和C++中的区别不大,主要有以下三种
-
对象(结构体变量).成员
-
对象指针->成员
-
(*对象指针).成员
以下是关于结构体的一些测试代码
#include2.动态内存申请#include using namespace std; struct MM { //protected: 不需要深究后续会讲 //MM() {} 不需要深究后续会讲 //属性,特征 //数据成员 char name[20]; int age; //..... //行为(方法) //成员函数 void print() { cout << name << "t" << age << endl; } void printData(); //在结构体中声明,在外面实现 //通过外部函数修改数据 int& getAge() { return age; } }; //结构体名限定,就是告诉别人这个函数来自哪里 void MM::printData() { cout << name << "t" << age << endl; } //结构体中的变量必须要通过结构体变量(结构体指针)访问 //C++结构体中的函数访问属性,可以直接访问 int main() { struct MM girl = { "小芳",28 }; MM mm = {"小丽",24}; girl.print(); (&mm)->printData(); MM* p = &mm; p->printData(); p->getAge() = 84; p->printData(); p->age = 1991; p->printData(); MM array[3]; return 0; }
首先回忆一下C语言中一些动态内存申请的操作:
1.malloc 申请动态内存 (不带初始化)
2.calloc 申请动态内存 (带初始化)
· 3.realloc 申请动态内存 (重新申请内存)
4.free 释放动态申请的内存
C++中不再使用C语言的动态内存申请函数 而是采用 new 来动态申请(当然 C语言的动态内存申请函数加上对应的头文件 在C++中任然有效)
注意:new 和 malloc 的一个区别,malloc申请的内存在堆区 而new申请的内存在自由存储区
-
C++的动态申请
-
new(申请)和delete(释放)
-
单个变量内存申请 : 例如申请一个int数据类型的指针 int* pa=new int; int* pb=new int(10); //括号用来初始化(可以不加)
-
-
#include
using namespace std; int main(){ //给单个变量申请内存 int* a=new int; char* b=new char; double* c=new double; //申请的时候初始化 ()给单个数据初始化 int* aa=new int(2); //动态申请一个int大小的内存并初始化为2 赋值给指针aa //delete释放内存 delete a; a=nullptr; delete b; b=nullptr; delete c; c=nullptr; delete aa; d=nullptr return 0; } -
数组的动态申请 : 申请一个长度为3的 int类型的数组 :int *parr=new int[3]; 申请一个长度为4的 int类型的数组并初始化:int *parr=new int[4]{1,2,3,4}
-
#include
uisng namespace std; int main(){ //一维数组的动态内存申请 并初始化 []表明数组长度(可以填变量也可以填常量) {}对数组元素初始化 int *parr=new int[4]{1,2,3,4}; char *pchar=new char[4]{'a','b','c','d'}; delete []parr; parr=nullptr; delete []pchar; pchar=nullptr; return 0; } 需要注意的是:在释放动态申请的数组时 ,我们为了代码的可读性 ,一般会在delete 后面加上 [ ] ,以此来表示释放的是一段内存 。当然不加 [] ,释放的也是一段内存,只是为了提高可读性。 [ ]本身没什么实际作用。
-
结构体内存申请
-
对于结构体内存的申请,还是按部就班
#includeusing namespace std; struct studentA{ int age; char[name]; }; struct studentB{ int age; char* name; }; int main(){ //动态内存申请一个结构体对象 并初始化 studentA* stdA=new student{20,"xiao bai"}; //动态内存申请一个结构体对象 //注意这里不能再初始化 这里name 是一个指针类型 studentB* stdB=new student; //需要再次对name动态申请内存 stdB->name=new char[20]; strcpy(stdB->name,"xiao hei"); stdB->age=21; //释放 delete stdA; stdA=nullptr; delete stdB; stdB=nullptr; return 0; }
上述代码中有一个需要注意的地方 对结构体成员中的指针变量初始化操作 必须要给他申请内存 才能赋值成功 。
下面是一些动态内存申请的测试代码
#include3.内存池using namespace std; //允许大家申请一段内存,共给程序使用,综合管理内存 //malloc 内存是在堆区 //new 内存是自由存储区 void testMemory() { char* memorySum = new char[1024]; //.......事情的处理,需要内存,所有内存源自于memorySum //int* pNum = new(申请内存的开始位置) int[3] int* pNum = new(memorySum) int[3]{ 1,2,3 }; //char* pstr = new(pNum + 3) char[20]{ "ILoveyou" }; //和下面这句话是等效的 char* pstr = new(memorySum + 12) char[20]{ "ILoveyou" }; for (int i = 0; i < 3; i++) { cout << pNum[i] << " "; } cout << endl; for (int i = 0; i < 3; i++) { cout << ((int *)memorySum)[i] << " "; } cout << endl << pstr << endl; cout << (memorySum + 12) << endl; delete[] memorySum; memorySum = nullptr; } int main() { testMemory(); return 0; }
-
允许大家申请一段内存,共给程序使用,综合管理内存(即申请一段内存,给多个不同的程序分配不同的内存段)
-
#include
uisng namespace std; int main(){ //申请1024个字节的空间 1k大小 char *memorySum=new char[1024]; //从memorySum开始 分配10个char类型内存给str --- 10字节 //char* str = new(申请内存的开始位置) int[3] char* str = new(memorySum) char[10]; //申请10个int类型内存给arr --- 40字节 int* arr=new(memorySum+10) int[10]; //等效于下面这行 //int *arr=new(str + 10) int[10]; delete []str; str=nullptr; delete []arr; arr=nullptr delete memorySum; memorySum=nullptr; return 0; 给一个程序分配号内存后,再次分配需要在上个程序结束的内存开始分配 :new(内存开始分配的地方)
4.string类型
string类型本身就是一个类
-
string创建(3种方式)
1.带初始化
2.通过另一个字符串创建
3.不带初始化
#include#include using namespace std; //没有这行的话 使用string要加std::string int main(){ //定义一个不赋值 string str1; str1="iLoveYou"; //定义初始化 string str2="hello" string str3("hello"); //通过另一个string类型的值来定义 string str4=str3; return 0; }
-
string基本操作
-
拷贝: 直接用等号就行 str1=str2;
-
赋值:str1="hello";
-
连接:两个字符串相连接直接用加号: str3=str1+str2;
-
比较: str1>str2 str1==str2 (依旧按照c中strcmp的比较方式去比较 只不过直接通过运 算符比)
-
#include
#include using namespace std; int main(){ string str1 = "hello"; string str2 = "world"; //字符串拷贝 str1 = str2; cout << str1 << endl; //字符串连接 string str3 = str1 + " " + str2; cout << str3 << endl; //字符串比较 if (str1 < str2){ cout << "str1小" << endl; } else{ cout << "str2小" << endl; } return 0; }
-
-
C++string与C语言string.h
C++中string没有' '
string 类型可以通过.c_str()来转换成c中的char* 类型 然后就可以用%s来输出
string str1 = "ILoveyou";
printf("%sn", str1.c_str());
-
string 其他函数
//empty(); //判断string是否为空
//size(); // 返回string长度 (由于string没有‘ ’,所以是多长就返回多长) //to_string(); //将括号里的数字直接转化为string类型的字符串//empty()判断是否为空 string strEmpty; if (strEmpty.empty()) //return length==0; { cout << "string为空" << endl; } //直接把数字转换为相应的字符串 string str2 = to_string(1234); //size()返回string长度 int lenth=str2.size();注意:string类型的长度并不等于string类型所占的内存大小,string类型初始所占的内存大小为28 。当长度大于28时 ,string类型会自动扩充string的内存大小。
下面是有关于string类型的一些测试代码
#include//注意和string.h区别 #include #include //string.h和cstring是一样 #include using namespace std; void createString() { //std::string str; string str1; str1 = "ILoveyou"; //所以一般用string不会加const cout << "First:" << str1 << endl; const string cstr; //cstr = "IMissyou"; 错误,常属性不能修改 string str2("ILoveyou"); cout << str2 << endl; string str3 = "IMissyou"; //喜欢这种方式 cout << str3 << endl; string str4(str3); cout << str4 << endl; string str5 = str4; cout << str5 << endl; //一般没有长度限定,在你使用范围下 string str = "2333333333333333333333333333333333333333333333333333333333333"; } void operatorString() { string str1 = "one"; string str2 = "two"; string str3 = str2; cout << str3 << endl; //没有减法 string str4 = str1 + str2; //等效: string str4=str1.append(str2); //C++中尽量用string 不要用char* ,可以用 //比较直接比较即可 //> < != == //str1.compare(str2) 0 -1 1 if (str1 > str2) //比较依旧按照char* 去比较 { cout <<"大的 "<< str1 << endl; } else { cout << "大的 " << str2 << endl; } } void compareCAndCpp() { //C++中是一个自定义类型(类),目前当作结构体即可 //C++string 不能用到C语言的字符串处理函数 //C++如何转换为C语言的char* //c_str() data()函数 string str1 = "ILoveyou"; //printf("%s", str1); printf("%sn", str1.c_str()); printf("%sn", str1.data()); //outtextxy(int x,int y,char* str); //直接把数字转换为相应的字符串 string str2 = to_string(1234); //atoi cout << str2 << endl; } void exOperator() { //采用下表法打印string string str = "IMissyou"; //C++string中没有记录 for (int i = 0; i < 8; i++) { cout << str[i]; } cout << endl; //其他函数操作 //万金油函数 //empty() //size(); string mystring = "IMissyou"; //cout << sizeof(mystring) << endl; //28 //cout <<"容量:" <



