C++查缺补漏

C语言详解:结构体
模板类/模板函数 template 的用法(超详细)
template:模板

循环

while (cin >> x){}
cin函数,输入NULL时返回0,输入其他值返回它的地址

结构体

typedef struct xxx {} yyy;yyy为结构体xxx的别名,是一种数据类型,需要实例化。
定义结构体 typedef struct 的用法总结

在结构体别名中定义结构体指针

typedef struct DNode{
	ElemType data;
	DNode* prior, * next;
}DNode, * DLinkList;  // * DLinkList 就是指向DNode类型的指针,声明时用DNode和DLinkList都可以

指针

C++指针详解
&:取地址
*:取地址里面的值
向函数传递数组的写法
用“->”的情况:
A是一个类 class / struct
p是一个指向A类型的指针,那么用p访问A中的成员变量和函数时,使用p->x,p->f(x)来访问。

向函数传入变量的指针和引用的区别
传入指针时,函数参数中是对指针的定义 int* a,传入函数的是变量的地址,&a;
传入引用时,函数参数中是对原变量的引用 int &a,传入函数的是原变量,a。
总之,传入指针是 通过指针,对指针指向的内存地址进行操作;传入变量的引用是直接对原变量进行修改。二者效果一样,但是原理不一样。
指针

typedef struct SqList{
	int data[MaxSize];
	int length;
};

void InitList(SqList *list){
	cout<<"type in the length of list:"<<endl;
	cin>>list->length;
	cout<<"type in the data:"<<endl; 
	for(int i = 0; i<list->length; i++)
		cin>>list->data[i];
}
int main(){
	SqList sqlist;
	InitList(&sqlist);
}

引用

typedef struct SqList{
	int data[MaxSize];
	int length;
};

void InitList(SqList &list){
	cout<<"type in the length of list:"<<endl;
	cin>>list.length;
	cout<<"type in the data:"<<endl; 
	for(int i = 0; i<list.length; i++)
		cin>>list.data[i];
}
int main(){
	SqList sqlist;
	InitList(sqlist);
}

上面两段代码,如果用指针访问结构体,则需要用->访问结构体成员;如果用原结构体,则用 . 由此可见,指针和引用的差别。

向函数中传入指针类型的数据
和上面的不同,上面传入的是变量的地址,在函数列表中被定义,成为指针。而本问题描述的是直接将指针类型的数据传入函数。

#include<bits/stdc++.h>

typedef struct DNode{
	ElemType data;
	DNode* prior, * next;
}DNode, * DLinkList;  //DLinkList为指向结构体的指针类型
 
//初始化双链表
bool InitDLinkList(DLinkList L) {  //此处和变量的指针一样,也可该写作 DNode* L
	L = (DLinkList)malloc(sizeof(DLinkList));
	if (L == NULL) {
		return false;          
	}
	L->prior = NULL;
	L->next = NULL;
	return true;
}

int main() {
	DLinkList L;  //定义指针类型数据L
	InitDLinkList(L);  //由于指针的值即为变量的地址,所以和&+变量名一样,都是将地址传入函数。
	return 0;
}

swap的例子
指针

# include<iostream>
using namespace std;

void MySwap(int* a, int* b){  //在列表中定义两个指针a,b,分别指向传入变量a,b的地址 
	int t = 0;  
	t = *a;  //交换值 
	*a = *b;
	*b = t;
	
	//错误的思路:用指针交换来交换 
	int *t = NULL;  //定义中间指针t,用于指针之间的赋值 
	t = a;
	a = b;
	b = t;
	//以上操作只是让函数内的指针ab分别指向了ba,但没有对对应地址内的值进行任何改变 
}

int main(){
	int a = 1,b = 2;
	MySwap(&a, &b);  //传入变量ab的地址 
	cout<<a<<" "<<b;
}
//向函数传入变量的地址。把函数声明和传入函数的形式整体来看,就是 int* a = &a; 
//也就是指针定义操作 

引用

# include<iostream>
using namespace std;

void MySwap(int &a, int &b){  //在列表中定义两个地址引用
	int t = 0;  
	t = a; //直接修改原变量
	a = b;
	b = t;
}

int main(){
	int a = 1,b = 2;
	MySwap(a, b);  //直接传入原始变量ab
	cout<<a<<" "<<b;
}

类和对象

类中不带返回类型的函数为构造函数。造函数可用于为某些成员变量设置初始值。
c语言malloc函数的用法和意义

C++三种常见的实例化方法

  1. 静态实例化:在程序的全局或静态作用域中定义并初始化一个对象,该对象在程序整个生命周期内只存在一个实例。
  2. 堆实例化:使用 new 运算符在动态存储区域中分配内存并实例化一个对象。这样创建的对象在程序运行期间一直存在,直到使用 delete 运算符显式释放其内存。
  3. 栈实例化:在函数或代码块的作用域中定义并实例化一个对象,该对象的生命周期与所在的函数或代码块相同。对象在离开该作用域时自动销毁。

静态实例化的例子

class MyClass {
public:
    MyClass() : m_x(0) {}
    void setX(int x) { m_x = x; }
    int getX() const { return m_x; }
private:
    int m_x;
};

MyClass globalObject;  // 全局实例

int main() {
    static MyClass staticObject;  // 静态实例
    globalObject.setX(5);
    staticObject.setX(10);
    int globalX = globalObject.getX(); // globalX = 5
    int staticX = staticObject.getX(); // staticX = 10
    // ...
    return 0;
}

上面的例子中,通过调用 setX 和 getX 来对全局对象 globalObject 和静态对象 staticObject 的成员变量进行访问。

堆实例化的例子

class MyClass {
public:
    MyClass() : m_x(0) {}
    void setX(int x) { m_x = x; }
    int getX() const { return m_x; }
private:
    int m_x;
};

int main() {
    MyClass* heapObject = new MyClass;  // 堆实例
    heapObject->setX(5);
    int heapX = heapObject->getX(); // heapX = 5
    // ...
    delete heapObject;
    return 0;
}

上面的例子中,通过调用 setX 和 getX 来对堆对象 heapObject 的成员变量进行访问。

栈实例化的例子

class MyClass {
public:
    MyClass() : m_x(0) {}
    void setX(int x) { m_x = x; }
    int getX() const { return m_x; }
private:
    int m_x;
};

void someFunction() {
    MyClass stackObject;  // 栈实例
    stackObject.setX(5);
    int stackX = stackObject.getX(); // stackX = 5
    // ...
}

int main() {
    someFunction();
    return 0;
}

上面的例子中,通过调用 setX 和 getX 来对栈对象 stackObject 的成员变量进行访问。