Day_02 C与C++区别

        上篇文章说了C与C++区别中的  头文件命名空间 、 using语法  、 引用类型(常引用  右值引用)  、 基本的输入输出 、 函数思想。

        这次我们再来看看C++ 中结构体   动态内存申请   内存池   string类型 这四种内容的区别

 1.结构体

        与C语言不同的是  C++能在结构体中定义或者申明函数   在结构体中申明的函数可以通过结构体名+作用域标识符(结构体限定名)  来在结构体外定义函数  (结构体中定义的函数叫做成员函数,也叫做行为(方法))

#include <iostream>
using namespace std;

struct A{
    int a;
    float b;
    void print();        //结构体中的函数申明
};

//通过作用域标识符在结构体外定义
void A::print(){
    cout<<a<<b<<endl;
}

 C++中通过结构体定义对象(结构体变量)时可以省略 struct 关键字 直接通过结构体名来定义。

简化了定义的步骤 ,当然也可以通过 struct 关键字来定义 ,不做硬性规定

struct student std;      //定义一个std对象(结构体变量)

student std;                //定义一个std对象

这两行代码本质是一样的。

对于结构体变量成员的访问 C和C++中的区别不大,主要有以下三种

  • 对象(结构体变量).成员

  • 对象指针->成员

  • (*对象指针).成员

 以下是关于结构体的一些测试代码

#include <iostream>
#include <string>
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;
}

 2.动态内存申请

        首先回忆一下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<iostream>
      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<iostream>
      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 后面加上 [ ]  ,以此来表示释放的是一段内存 。当然不加 [] ,释放的也是一段内存,只是为了提高可读性。   [ ]本身没什么实际作用。

    • 结构体内存申请

                对于结构体内存的申请,还是按部就班  

#include<iostream>
using 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;
}

上述代码中有一个需要注意的地方  对结构体成员中的指针变量初始化操作  必须要给他申请内存 才能赋值成功 。

下面是一些动态内存申请的测试代码

#include <iostream>
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;
}

3.内存池

  • 允许大家申请一段内存,共给程序使用,综合管理内存(即申请一段内存,给多个不同的程序分配不同的内存段)

  • #include<iostream>
    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<iostream>
#include<string>
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<iostream>
      #include <string>
      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没有'\0'

        string 类型可以通过.c_str()来转换成c中的char* 类型  然后就可以用%s来输出

string str1 = "ILoveyou";

printf("%s\n", str1.c_str());

  • string 其他函数

        //empty();     //判断string是否为空
        //size();        // 返回string长度 (由于string没有‘\0’,所以是多长就返回多长)                         //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>   //注意和string.h区别
#include <iostream>
#include <cstring>	//string.h和cstring是一样
#include <stdio.h>
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("%s\n", str1.c_str());
	printf("%s\n", 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中没有记录\0 
	for (int i = 0; i < 8; i++) 
	{
		cout << str[i];
	}
	cout << endl;
	//其他函数操作
	//万金油函数
	//empty()
	//size();
	string mystring = "IMissyou";
	//cout << sizeof(mystring) << endl;   //28
	//cout <<"容量:" <<mystring.capacity() << endl;
	cout <<"mystring:"<< mystring.size() << endl;
	string strEmpty;		
	if (strEmpty.empty())				  //return length==0;
	{
		cout << "string为空" << endl;
	}
}
void initString() 
{
	char* str = new char[15];
	//做了自动扩增处理
}
int main() 
{
	//createString();
	//operatorString();
	//compareCAndCpp();
	exOperator();
	return 0;
}

作业

使用动态内存申请创建一个二维数组

#include<iostream>
#include<string>
using namespace std;
//返回二级指针方式
int** fun(int rows, int cols){
	int** pArray = new int*[rows];
	for (int i = 0; i < rows; i++){
		pArray[i] = new int[cols];
	}
	return pArray;
}


//二级指针引用改变指向
void function(int** &pArray, int rows, int cols){
	pArray = new int*[rows];
	for (int i = 0; i < rows; i++){
		pArray[i] = new int[cols];
	}
}

int main(){
	int rows = 4;
	int cols = 3;

	//接受函数返回值(二级指针)
	int** pArray = fun(rows,cols);
	for (int i = 0; i < rows; i++){
		for (int j = 0; j < cols; j++){
			pArray[i][j] = 1;
		}
	}
	for (int i = 0; i < rows; i++){
		for (int j = 0; j < cols; j++){
			cout << pArray[i][j] << "\t";
		}
		cout << endl;
	}
	cout << endl;
	delete []pArray;
	pArray = nullptr;


	//引用传入二级指针修改指向
	int **pp = nullptr;
	function(pp, rows, cols);
	for (int i = 0; i < rows; i++){
		for (int j = 0; j < cols; j++){
			pArray[i][j] = 2;
		}
	}
	for (int i = 0; i < rows; i++){
		for (int j = 0; j < cols; j++){
			cout << pArray[i][j] << "\t";
		}
		cout << endl;
	}
	delete []pp;
	pArray = nullptr;
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const char* Haab_month_name[] = {"pop", "no", "zip", "zotz", "tzec", "xul", "yoxkin", "mol", "chen", "yax", "zac", "ceh", "mac", "kankin", "muan", "pax", "koyab", "cumhu", "uayet"}; int Tzolkin_day_number[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7}; const char *Tzolkin_day_name[] = {"imix", "ik", "akbal", "kan", "chicchan", "cimi", "manik", "lamat", "muluk", "ok", "chuen", "eb", "ben", "ix", "mem", "cib", "caban", "eznab", "canac", "ahau"}; struct Date { int day; int month; int year; }; // 把哈布历转换成天数 int haab_to_days(int day, const char* month, int year) { int total_days = day + (year * 365); int month_index; for (month_index = 0; month_index < 19; ++month_index) { if (strcmp(Haab_month_name[month_index], month) == 0) { break; } } total_days += month_index * 20; return total_days; } // 把天数转换成托尔金历 void days_to_tzolkin(int total_days, int* day_number, const char** day_name) { int tzolkin_day_count = total_days % 13; int tzolkin_day_index = tzolkin_day_count - 1; if (tzolkin_day_index < 0) tzolkin_day_index = 12; int tzolkin_day_number = Tzolkin_day_number[tzolkin_day_index]; const char *tzolkin_day_name = Tzolkin_day_name[(total_days % 20)]; *day_number = tzolkin_day_number; *day_name = tzolkin_day_name; } int main() { int N; cin >> N; cout << N << endl; for (int i = 0; i < N; ++i) { Date date; char dot; scanf("%d%c%d%s%d", &date.day, &dot, &date.month, Haab_month_name, &date.year); int total_days = haab_to_days(date.day, Haab_month_name, date.year); int tzolkin_day_number; const char *tzolkin_day_name; days_to_tzolkin(total_days, &tzolkin_day_number, &tzolkin_day_name); printf("%d %s %d\n", tzolkin_day_number, tzolkin_day_name, date.year); } return 0; }
06-06
这是一个使用 C++ 编写的程序,用于将 Maya 文化的哈布历转换为托尔金历。程序主要包括以下几个部分: 1. 头文件和命名空间声明 ``` #include <iostream> #include <cstdio> #include <cstring> using namespace std; ``` 2. 定义哈布月份和托尔金日期的名称和数字 ``` const char* Haab_month_name[] = {"pop", "no", "zip", "zotz", "tzec", "xul", "yoxkin", "mol", "chen", "yax", "zac", "ceh", "mac", "kankin", "muan", "pax", "koyab", "cumhu", "uayet"}; int Tzolkin_day_number[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7}; const char *Tzolkin_day_name[] = {"imix", "ik", "akbal", "kan", "chicchan", "cimi", "manik", "lamat", "muluk", "ok", "chuen", "eb", "ben", "ix", "mem", "cib", "caban", "eznab", "canac", "ahau"}; ``` 3. 定义一个日期结构体 ``` struct Date { int day; int month; int year; }; ``` 4. 把哈布历转换成天数 ``` int haab_to_days(int day, const char* month, int year) { int total_days = day + (year * 365); int month_index; for (month_index = 0; month_index < 19; ++month_index) { if (strcmp(Haab_month_name[month_index], month) == 0) { break; } } total_days += month_index * 20; return total_days; } ``` 5. 把天数转换成托尔金历 ``` void days_to_tzolkin(int total_days, int* day_number, const char** day_name) { int tzolkin_day_count = total_days % 13; int tzolkin_day_index = tzolkin_day_count - 1; if (tzolkin_day_index < 0) tzolkin_day_index = 12; int tzolkin_day_number = Tzolkin_day_number[tzolkin_day_index]; const char *tzolkin_day_name = Tzolkin_day_name[(total_days % 20)]; *day_number = tzolkin_day_number; *day_name = tzolkin_day_name; } ``` 6. 主函数,用于读取输入、调用转换函数、并输出结果 ``` int main() { int N; cin >> N; cout << N << endl; for (int i = 0; i < N; ++i) { Date date; char dot; scanf("%d%c%d%s%d", &date.day, &dot, &date.month, Haab_month_name, &date.year); int total_days = haab_to_days(date.day, Haab_month_name, date.year); int tzolkin_day_number; const char *tzolkin_day_name; days_to_tzolkin(total_days, &tzolkin_day_number, &tzolkin_day_name); printf("%d %s %d\n", tzolkin_day_number, tzolkin_day_name, date.year); } return 0; } ``` 以上就是这个程序的主要内容和流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值