201_C++基础

发布于:2024-05-11 ⋅ 阅读:(116) ⋅ 点赞:(0)

一、C++结构体相关知识

一段代码阐释所有初始化与赋值的情况:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;

//结构体初始化的几种方式
//定义一个node结构体
typedef struct node{
   
    int id;
    int num;
    string name;
    //1、无参数的构造函数数组初始化时调用
    //node():id(),num(),name(){};
    //有参构造
    //node(int a,int b,string c):id(a),num(b),name(c){}
    //2、对于方法3的构造函数初始化,什么都不写就是使用的结构体自带的默认构造函数。
    //如果自己重写了带参数的构造函数,就不能用大括号进行初始化了,即不能再使用指定初始化与顺序初始化了(初始化结构体时如果不传入参数会出现错误)。
    //在建立结构体数组时,如果只写了带参数的构造函数将会出现数组无法初始化的错误
    //3、放在最后的构造函数可以不加分号结尾
    //node(int id,int num,string name){
   
    //     this->id=id;
    //     this->num=num;
    //     this->name=name;
    // }
} node_t;

typedef struct charnode{
   
    int id;
    int num;
    char name[16];
} charnode_t;

struct Test {
   
  int x = 0; // <== 含有默认初始化值的元素,无法使用初始化列表进行初始化
  char v;
};

class Hero {
   
  public:
    Hero() {
   
      cout << "Hero 构造函数调用了" << endl;
    }
    //如果用下面的free释放new出来的h2内存,将不会触发下面的析构函数
    //Hero *h2 = new Hero;
    //free(h2);
    ~Hero() {
   
      cout << "Hero 析构函数调用了" << endl;
    }
};

struct Date{
   
    int day, month, year;
};

int main(){
   
    //初始化的几种方法
    //1、顺序初始化
    node node1st={
   1,2,"node1st"};
    // node node1st;
    cout<<node1st.name<<"---"<<"size:"<<sizeof(node1st)<<endl;
    //2、指定初始化(点号+赋值符号或者使用冒号)
    struct node node2st={
   .id=2,num:5,name:"node2st"};
    cout<<node2st.name<<endl;
    //3、构造函数初始化
    //构造函数初始化常见于 C++ 代码中,因为 C++ 中的 struct 可以看作 class,结构体也可以拥有构造函数
    //struct 如果定义了构造函数的话,就不能用大括号进行初始化了,即不能再使用指定初始化与顺序初始化了
    node_t node3st(5,6,"node3st");
    cout<<node3st.name<<endl;
    //4、使用calloc分配并置为0
    node_t * node4st=(node_t *)calloc(1,sizeof(struct node));
    std::cout << node4st->name<<"--point size:"<<sizeof(node4st)<<endl;
    //5、使用new动态创建结构体变量时,必须是结构体指针类型
    node_t * node5st=new node();
    //虽说delete可以释放calloc的内存,但是我编译器还是报错了,还是得用free来释放
    delete node5st;
    // free(node5st);
    //6、结构体变量使用结构体+()可以初始一个结构体变量的(也就创建了一个新的引用)
    node node6st;
    node6st=node();
    cout<<node6st.name<<"--node6st--"<<"size:"<<sizeof(node6st)<<endl;

    //7、以前是可以部分初始化的,但部分初始化只限于初始化开头的变量,如果某个结构成员未被初始化,则所有跟在它后面的成员都需要保留为未初始化
    //不过我的编辑器部分初始化也报错了,感觉可能部分初始化风险较大吧
    // Date birthday = {23,8};

    //结构体赋值的几种方法
    //变量的赋值和初始化是不一样的,初始化是在变量定义的时候完成的,是属于变量定义的一部分,赋值是在变量定义完成之后想改变变量值的时候所采取的操作
    //无法使用node1st={1,2,"node1st"};这种方式赋值
    //1、使用 memset 对结构体变量进行置空操作
    //如下,使用memset进行赋值时,结构体里不能是string类型,但可以是char或char*
    charnode_t node1ass;
    // 按照编译器默认的方式进行初始化(如果node4st是全局静态存储区的变量,默认初始化为0,如果是栈上的局部变量,默认初始化为随机值)
    memset(&node1ass,0,sizeof(charnode_t));
    cout<<node1ass.name<<endl;
    //2、依次给每一个结构体成员变量进行赋值
    node_t node2ass;
    node2ass.id=5;
    node2ass.name="node2ass";
    cout<<node2ass.name<<endl;
    //3、使用已有的结构体变量给另一个结构体变量赋值(结构体变量之间是可以相互赋值的)
    node_t node3ass;
    node3ass=node1st;
    cout<<node3ass.name<<endl;
    //ps:初始化与赋值有着本质的区别,初始化是变量定义时的第一次赋值,赋值则是定义之后的值的变更操作
    node3ass.name="node3ass";
    cout<<node3ass.name<<"--"<<node1st.name<<endl;
    //4、使用指针指向一个结构体变量
    node_t *node4ass;
    // node4ass=&node1st;
    node4ass=node4st;
    cout<<node4ass->name<<endl;
    node4ass->name="node4ass";
    // cout<<node4ass->name<<"--"<<node1st.name<<endl;
    cout<<node4ass->name<<"--"<<node4st->name<<endl;
    //1、delete主要用来释放new分配的内存,但delete 也可以用来释放由 malloc 和 calloc 分配的内存
    // delete node4ass;
    // delete node4st;
    //2、free主要用来释放由 malloc 和 calloc 分配的内存,也可以释放new 分配的内存,但不推荐使用
    free(node4ass);
    // free(node4st);
    // cout<<node4ass->name<<"--"<<node4st->name<<endl;
    //char *c1 = (char *)malloc(1, 10);
    //c1[0] = 'a';
    //delete[] c1;
    //经过 delete 释放过后,指针变成了野指针,此时再访问内存将是非法的,没有任何数据的,所以会显示乱码
    //free(c1);
    //不要使用 free 去释放由 new 分配的内存,因为它 不会去触发析构函数

网站公告

今日签到

点亮在社区的每一天
去签到