C++(面向對象編程)

思維導圖

面向對象

1.面向對象思想

概念:面向對象編程(OOP)是一種以對象為基礎的編程范式,強調將數據和操作數據的方法封裝在一起。這就是上篇文章講過的。面向過程是以“怎么解決問題”為核心,而面向對象思想在于“誰來解決問題”為核心。

特點:

1. 將操作的事物看成對象

2. 不需要自己親自去做事,而是直接調用對象的行為完成需要的操作

3. 簡化復雜的分步操作,提高編程效率

2.類和對象

類:類是一個概念,用于描述具體對象的特點,包括屬性(數據)和行為(函數)。自定義類的命名必須使用帕斯卡命名法:所有單詞的首字母大寫。

????????屬性:也就是成員變量,具體的數據。

????????行為:也就是成員函數,具體的函數,可以實現一定的方法。

對象:對象是依照類創建的實體,可以有多個,但是多個對象之間的數據是相互隔離的

一.類和對象的創建和使用

想象現在你就是上帝,你創造一只貓,它有年齡身高名字等基礎屬性,這些就是這個貓的“數據”,它還會奔跑,喵喵叫等,這些就是這個“數據”的動作,也就是“方法”,在C++中就可以把數據和方法封裝在一起,這就有了面向對象的第一個屬性----封裝。這樣一來,這個對象就不只是一個數據,還包含它的方法,就可以讓這個對象完成一些特定行為,而不是我創造貓,我讓貓叫,讓貓跑,而是我創造了貓,讓貓自己叫,自己跑。

1.創建類

#include <iostream>using namespace std;class Cat{
public:                //公有成員,可以在外部訪問string name;        //屬性string color;int age;double weight;void run(){          //行為:跑cout << "run for you" << endl;}void meow(int a){    //叫if(a == 8)cout << "miao miao" << endl;}void name1(){        //顯示名字name = "mike";cout << name << endl;}
};int main()
{return 0;
}

2.創建對象

(1)棧內存對象:

只存活在最近的{}內,{}執行結束后自動銷毀適合臨時使用

 Cat cat1;

(2)堆內存對象:

使用new關鍵字創建使用delete關鍵字銷毀如果不銷毀持續存在導致內存泄漏。堆內存對象使用指針存儲首地址使用->調用成員

Cat *cat2 = new Cat;

3.使用對象

當使用的pubulic修飾的類,可以直接在外部賦值,使用在對象后面加“.”就可以使用內部函數。

#include <iostream>using namespace std;class Cat{
public:                //公有成員,可以在外部訪問string name;        //屬性string color;int age;double weight;void run(){          //行為:跑cout << "run for you" << endl;}void meow(int a){    //叫if(a == 8)cout << "miao miao" << endl;}void name1(){        //顯示名字name = "mike";cout << name << endl;}
};int main()
{//棧內存對象Cat cat1;cat1.name = "Mike";cat1.color = "yellow";cat1.age = 8;cat1.weight = 35.7;/*if(1){            //錯誤,創建的棧內存對象只能存活在最近的兩個{}內,if一結束就不存在Cat cat1;}*/cout << cat1.name <<endl;cout << cat1.color <<endl;cout << cat1.age <<endl;cout << cat1.weight <<endl;cout << "#################" <<endl;cat1.run();cat1.meow(8);cat1.name1();cout << "#################" <<endl;//堆內存對象Cat *cat2 = new Cat;cat2->name = "Join";cat2->color = "red";cat2->age = 7;cat2->weight = 44.2;cout << cat2->name <<endl;cout << cat2->color <<endl;cout << cat2->age <<endl;cout << cat2->weight <<endl;return 0;
}

?

?二.封裝

概念:上面代碼結構體非常相似因為一個完全開放就是結構體實際上需要封裝封裝需要類中一些屬性細節隱藏根據實際需求對外部開放調用讀寫接口

外部讀取數據接口稱為getter外部寫入數據結構稱為setter

核心思想:隱藏內部實現細節,通過公共接口控制訪問

封裝優勢

????????(1)數據保護(防止非法修改)

????????(2)實現與接口分離

????????(3)代碼可維護性增強

#include <iostream>using namespace std;class Cat{
private:                // 私有成員(封裝的核心)string name;string color;int age;double weight;
public:                  // 公共接口string get_name(){                //得到(返回)名字return name;}void set_name(string a){        //設置名字name = a;}string get_color(){            //得到(返回)顏色return color;}void set_color(string a){        //設置顏色color = a;}//嘗試自己寫一下其他操作
};int main()
{//棧內存對象Cat cat1;cat1.set_name("Mike");                    //設置名字cout << cat1.get_name() << endl;cat1.set_color("yellow");                //設置顏色cout << cat1.get_color() << endl;cout << "#################" <<endl;//堆內存對象Cat *cat2 = new Cat;cat2->set_name("Lisa");                    //設置名字cout << cat2->get_name() << endl;cat2->set_color("red");                //設置顏色cout << cat2->get_color() << endl;delete cat2;return 0;
}

?三.構造函數

構造函數(constructor)一種特殊成員函數

????????(1)用于創建對象創建對象必須調用構造函數

????????(2)如果一個類中程序員不寫構造函數編譯器自動添加一個無參構造函數

????????(3)不寫返回值類型返回一個創建對象

????????(4)函數名稱必須類名

構造函數主要功能創建對象完成對象數據初始化

可以和函數重載聯合使用。

1.初始化構造函數:

#include <iostream>using namespace std;class Cat{
private:string name;string color;int age;double weight;
public:Cat(){                    name = "mike";color = "red";age = 4;weight = 33.5;}//函數重載Cat(string a,string b,int c,double d){name = a;color = b;age = c;weight = d;}void printf(){cout << name << endl;cout << color << endl;cout << age << endl;cout << weight << endl;}
};int main()
{//棧內存對象Cat cat1;                                        //不使用參數默認調用無參的構造函數cout << "#################" <<endl;cat1.printf();cout << "#################" <<endl;Cat cat2("Join","blue",8,66.2);                    //調用有參的構造函數cat2.printf();cout << "#################" <<endl;//堆內存對象Cat *cat3 = new Cat("Lisa","red",1,12.5);        //調用有參的構造函數cat3->printf();delete cat3;return 0;
}

2.構造初始化列表:

#include <iostream>using namespace std;class Cat{
private:string name;string color;int age;double weight;
public:Cat(){name = "mike";color = "red";age = 4;weight = 33.5;}//函數重載,構造初始化列表Cat(string a,string b,int c,double d):name(a),color(b),age(c),weight(d){/*name = a;color = b;age = c;weight = d;*/}void printf(){cout << name << endl;cout << color << endl;cout << age << endl;cout << weight << endl;}
};int main()
{//棧內存對象Cat cat1;                                        //不使用參數默認調用無參的構造函數cout << "#################" <<endl;cat1.printf();cout << "#################" <<endl;Cat cat2("Join","blue",8,66.2);                    //調用有參的構造函數cat2.printf();cout << "#################" <<endl;//堆內存對象Cat *cat3 = new Cat("Lisa","red",1,12.5);        //調用有參的構造函數cat3->printf();delete cat3;return 0;
}

3.調用方式:

(1)顯式調用

明確指定使用構造函數,下面代碼中cat1~3都是顯式調用。

(2)隱式調用

沒有明確指定使用構造函數,當隱式調用是一個字符串類型(Cat cat6 = "Lisa";),或報錯,編譯器沒辦法優化復雜這樣復雜的情況。下面代碼中cat4和cat5都是隱式調用。?

#include <iostream>using namespace std;class Cat{
private:int age;double weight;string name;string color;
public:Cat(){age = 4;weight = 33.5;name = "mike";color = "red";}//函數重載,構造初始化列表Cat(int a,double b = 25.3,string c = "mike", string d = "red"):age(a),weight(b),name(c),color(d){cout << a << endl;}void printf(){cout << "年齡:" << age << endl;cout << "體重:" << weight <<endl;cout << "名字:" << name << endl;cout << "顏色:" << color << endl;}
};int main()
{//棧內存對象Cat cat1;                                        //不使用參數默認調用無參的構造函數cout << "#################" <<endl;cat1.printf();cout << "#################" <<endl;Cat cat2(8);                    //調用有參的構造函數cat2.printf();cout << "#################" <<endl;//堆內存對象Cat *cat3 = new Cat(1);        //調用有參的構造函數cat3->printf();delete cat3;cout << "#################" <<endl;Cat cat4 = 8;                   //編譯器優化,可以把8作為參數傳入(隱式調用)cat4.printf();cout << "#################" <<endl;Cat cat5 = {4,44.3,"Lisa","red"};           //隱式調用cat5.printf();//Cat cat6 = "Lisa";              //當第一個參數是字符串類型,就不會優化,對于編譯器而言太復雜return 0;
}

補:可以使用explicit屏蔽隱式調用

隱式調用一般用不到,也不好用,使用不安全,容易出現錯誤

#include <iostream>using namespace std;class Cat{
private:int age;double weight;string name;string color;
public:explicit Cat(){age = 4;weight = 33.5;name = "mike";color = "red";}//函數重載,構造初始化列表explicit Cat(int a,double b = 25.3,string c = "mike", string d = "red"):age(a),weight(b),name(c),color(d){cout << a << endl;}void printf(){cout << "年齡:" << age << endl;cout << "體重:" << weight <<endl;cout << "名字:" << name << endl;cout << "顏色:" << color << endl;}
};int main()
{//棧內存對象Cat cat1;                                        //不使用參數默認調用無參的構造函數cout << "#################" <<endl;cat1.printf();cout << "#################" <<endl;Cat cat2(6);                    //調用有參的構造函數cat2.printf();cout << "#################" <<endl;//堆內存對象Cat *cat3 = new Cat(4);        //調用有參的構造函數cat3->printf();delete cat3;cout << "#################" <<endl;/*            //隱式調用失效Cat cat4 = 8;                     cat4.printf();cout << "#################" <<endl;Cat cat5 = {4,44.3,"Lisa","red"};   //隱式調用cat5.printf();*/return 0;
}

4.拷貝構造函數

拷貝就是復制,創建一個和原對象一樣的新對象,被拷貝的對象和拷貝到對象的存儲地址是不一樣的,不是引用。

在每個類創建的時候,如果程序員不寫,都自己會帶一個默認的拷貝構造函數(淺拷貝函數)。

    //拷貝構造函數(不寫也可以,默認存在)Cat(const Cat &a){age = a.age;name = a.name;}Cat cat1();                //創建第一對象    Cat cat2(cat1);            //拷貝一個對象

1.淺拷貝

如果成員變量出現指針類型,默認的拷貝構造函數會直接拷貝指針變量,多個變量保存在同一個地址,這些對象的成員變量都指向同一塊內存,這樣的成員變量不符合面向對象的要求,會導致成員變量隨著這塊空間的內容的變化而變化,還記得我們封裝的時候的核心思想是什么?隱藏內部實現細節,成員變量為什么要用private修飾?就是為了防止外部改變,但是拷貝存在指針類型的對象就會出現成員變量隨著外部變化而變化的情況。

重寫一下代碼(寫簡單點):

#include <iostream>
#include <string.h>
using namespace std;class Cat{
private:int age;char *name;
public://默認的拷貝構造函數(不寫也可以)//構造初始化列表explicit Cat(int a,char *b):age(a),name(b){cout << a << endl;}void printf(){cout << "年齡:" << age << endl;cout << "名字:" << name << endl;}
};int main()
{char name[5] = "Lisa";Cat cat1(6,name);                    //調用有參的構造函數cat1.printf();cout << "#################" <<endl;Cat cat2(cat1);                      //拷貝構造函數cat2.printf();cout << "#################" <<endl;strcpy(name,"Join");                   //此時我們改變name內的值cat2.printf();                        //因為構造類我們用的是指針,所以里面的值發生了改變return 0;
}

2.深拷貝

出現上述情況,我們需要修改拷貝構造函數和初始化構造函數,在初始化構造函數的時候,開辟空間,再把內容復制到新開的空間里,這樣就避免了成員變量指向外部空間。在C++中使用new開辟空間。

開辟堆空間:

    char *a = new char[10];

優化代碼:

#include <iostream>
#include <string.h>
using namespace std;class Cat{
private:int age;char *name;        
public:Cat(const Cat &d){age = d.age;name = new char[5];strcpy(name,d.name);}explicit Cat(){age = 4;name = new char[5];    //開辟空間strcpy(name,"mike");   //復制內容到空間}//函數重載,構造初始化列表explicit Cat(int a,char *b){age = a;name = new char[5];       //開辟空間strcpy(name,b);            //復制內容到空間cout << b << endl;}void printf(){cout << "年齡:" << age << endl;cout << "名字:" << name << endl;}
};int main()
{char name[5] = "Lisa";Cat cat1(6,name);                                        //不使用參數默認調用無參的構造函數cat1.printf();cout << "################" <<endl;Cat cat2(cat1);cat2.printf();cout << "################" <<endl;strcpy(name,"Join");cat2.printf();return 0;
}

四.析構函數

學習上面內容后,還有一個問題,我們使用New開辟的堆空間存在一個問題,這個空間是由程序員開辟和釋放的,程序結束才會釋放。就像上面代碼,我們創造一個棧空間對象,但是內部的name是開的堆空間存放,當對象所在的{}結束,對象cat1就會釋放,當時name沒有釋放,會出現內存泄露。

1.什么是內存泄露?

內存泄露指程序中已動態分配的堆內存由于某種原因未釋放無法釋放,造成系統內存浪費,導致程序運行速度減慢或崩潰。這類問題在長時間運行的應用中尤為嚴重。若果不解決,運行過程總會堆積這樣的垃圾空間。

2.析構函數

這個時候就可以使用析構函數來解決;析構函數(destructor)是構造函數對立函數也是一種特殊成員函數如果程序員不手寫編譯器自動添加一個析構函數;析構函數是用來對對象資源的回收,關閉和釋放。下面就是析構函數初始版本(不寫的默認):

    ~Cat(){}

這也沒參數啊,怎么做到的?別管,問就是C++特性,感興趣可以去看源碼。現在我們在析構函數中加上delete name;專門去釋放存在堆區域的name變量,就解決了內存泄露的問題。

3.優化代碼:

#include <iostream>
#include <string.h>
using namespace std;class Cat{
private:int age;char *name;
public:explicit Cat(){age = 4;name = new char[5];strcpy(name,"mike");}//函數重載,構造初始化列表explicit Cat(int a,char *b){age = a;name = new char[5];strcpy(name,b);cout << b << endl;}//拷貝構造函數Cat(const Cat &a){age = a.age;name = a.name;}void printf(){cout << "年齡:" << age << endl;cout << "名字:" << name << endl;}~Cat(){                             //析構函數,為防止內存泄露cout << "析構函數" << endl;delete name;}
};int main()
{char name[5] = "Lisa";Cat cat1(6,name);                                        //不使用參數默認調用無參的構造函數cat1.printf();cout << "################" <<endl;Cat *cat2 = new Cat;cat2->printf();delete cat2;cout << "################" <<endl;cout << "結束" << endl;return 0;
}

4.析構函數和構造函數比較:

析構函數構造函數

沒有參數

可以有參數,支持默認值和重載

函數名稱是 ~類名

函數名稱是 類名

對象銷毀時被調用

創建對象時調用

各種的資源的回收、關閉和釋放

數據初始化,各種資源的開辟

五.作用域限定符 ::

概念:

作用域限定符?::(也稱為范圍解析運算符)在C++中,是一個關鍵運算符,用于明確指定標識符(變量、函數、類等)所屬的作用域。它的主要功能是消除命名沖突,并提供對特定作用域成員的精確訪問。

1.名字空間

名字空間namespaceC++用于解決重名問題設計。在上一篇文章中提到過。

#include <iostream>//using namespace std;//std是C++源碼的名字空間
int a = 1;
// 自定義名字空間
namespace my {int a = 3;int b = 4;
}
using namespace my;int main()
{int a = 2;std::cout << a << std::endl; // 2// 匿名名字空間std::cout << ::a << std::endl; // 1std::cout << my::a << std::endl; // 3std::string s = "123";std::cout << b << std::endl; // 4return 0;
}

2.類內聲明,類外定義

類內成員(尤指成員函數)可以聲明定義分離聲明類內定義可以寫在類外,這個以后會用的比較頻繁。

#include <iostream>using namespace std;class Teacher
{
private:string name;
public:// 只聲明Teacher(string n);string get_name();void set_name(string n);
};
// 類外定義
Teacher::Teacher(string n)
{name = n;
}
string Teacher::get_name()
{return name;
}
void Teacher::set_name(string n)
{name = n;
}int main()
{Teacher t1("t1");cout << t1.get_name() << endl;t1.set_name("t2");cout << t1.get_name() << endl;return 0;
}

3.與static關鍵字配合

在 C++ 中,作用域限定符?::?與?static?關鍵字?配合使用主要涉及類的靜態成員管理,這是實現類級別數據共享的核心機制。(后面再講)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83954.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83954.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83954.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

驅動程序無法通過使用安全套接字層(SSL)加密與 SQL Server 建立安全連接,

驅動程序無法通過使用安全套接字層(SSL)加密與 SQL Server 建立安全連接,Error: “The server selected protocol version TLS10 is not accepted by client preferences [TLS13&#xff0c;TLS12]”. ClientConnectionId:d5fd8d69-ae88-4055-9f6d-6e8515224ce2】。 基本上就是…

【三大前端語言之一】交互:JavaScript詳解

【三大前端語言之一】交互&#xff1a;JavaScript詳解 在學習完HTML和CSS之后&#xff0c;最后一門前端語言——JavaScript&#xff0c;是重中之重。HTML負責頁面結構&#xff0c;CSS負責頁面樣式&#xff0c;而JavaScript則賦予網頁“生命”&#xff0c;讓網頁可以動起來、響…

LangChain面試內容整理-知識點12:檢索器(Retriever)接口與實現

在LangChain中,檢索器(Retriever)是一個抽象接口,負責根據用戶查詢從數據源中檢索相關文檔。可以把Retriever理解為“搜索工具”:給它一個未經結構化的查詢文本(如用戶問題),它返回一組與之相關的 Document 對象。內部可以基于向量相似度、數據庫查詢、甚至網絡搜索。 …

LLVM前端和優化層

文章目錄 LLVM ArchitectueLLVM 前端Lexical Analysis詞法分析Syntactic analysis 語法分析Syntactic Analyze語義分析 LLVM 優化層Pass 基礎概念Pass 依賴關系Pass API 總結 LLVM Architectue LLVM 前端 LLVM 的前端其實是把源代碼也就是 C、C、Python 這些高級語言變為編譯器…

工作流和Agent 的區別與聯系

工作流和智能體可能讓人混淆的地方就是他們都可能有大模型的加持&#xff0c;都可能有工具的加入供大模型調用&#xff0c;本文做一下對比和聯系 工作流 (Workflow) 定義&#xff1a; 工作流是一系列預定義、結構化且可重復的步驟或任務&#xff0c;旨在完成特定的業務目標或解…

leetcode--用StringBulider反轉字符串單詞的巧妙解法

反轉字符串中的單詞 這道題理想中的操作方式就是先去除前導和尾隨空格&#xff0c;之后設一個尾指針&#xff0c;往前檢索&#xff0c;掃到一個單詞就把這個單詞放到字符串的第一個位置。 很明顯&#xff0c;java中我們不能直接對字符串進行修改&#xff0c;而我們想實現一個一…

連鎖零售行業智慧能源管理解決方案:精準管控,讓每一度電創造價值

在連鎖超市、便利店等業態中&#xff0c;門店分布廣、用能場景復雜、管理成本高是普遍難題。傳統能源管理模式依賴人工抄表與分散管理&#xff0c;存在數據滯后、響應效率低、安全隱患難排查等問題。以某全國幾千家門店的連鎖便利店為例&#xff0c;其面臨的挑戰包括&#xff1…

在 PostgreSQL 中實現 `lck`, `special`, `item` 與 `org_id` 或 `user_id` 組合唯一的約束

在 PostgreSQL 中實現 lck, special, item 與 org_id 或 user_id 組合唯一的約束 要實現 lck, special, item 這三個字段必須與 org_id 或 user_id 中的一個&#xff08;但不能同時&#xff09;組合唯一的約束&#xff0c;你需要創建以下約束&#xff1a; 方案1&#xff1a;使…

g++ a.cpp -o a ‘pkg-config --cflags --libs opencv4‘/usr/bin/ld: 找不到 沒有那個文件或目錄

這個錯誤表明 pkg-config 命令沒有正確執行&#xff0c;導致編譯器無法找到 OpenCV 的庫文件和頭文件路徑。pkg-config 是一個工具&#xff0c;用于查詢已安裝庫的編譯和鏈接選項。如果 pkg-config 無法找到 OpenCV 的配置文件&#xff0c;就會導致這個錯誤。 以下是解決這個問…

定制平板在智能家居中能做些什么?全面解析其核心功能

大家有沒有發現&#xff0c;現在智能家居越來越普及了&#xff0c;很多家庭都在逐步升級自己的居住體驗。而在這一過程中&#xff0c;一種設備正悄悄地取代我們以前常用的開關面板和手機APP&#xff0c;成為整個家庭智能控制的核心&#xff0c;這就是——定制平板。 它可不是我…

【通俗易懂】Linux 線程調度策略詳解

引言&#xff1a;CPU是廚房&#xff0c;調度器是主廚 要真正理解Linux如何處理成千上萬個并發任務&#xff0c;不妨把它想象成一個繁忙的專業廚房。這個比喻不僅能讓抽象概念變得具體&#xff0c;更能揭示其背后深刻的設計哲學。 廚房 (The Kitchen): 代表整個計算機系統。 廚…

筆記本電腦安裝win10哪個版本好_筆記本裝win10專業版圖文教程

筆記本電腦安裝win10哪個版本好&#xff1f;筆記本還是建議安裝win10專業版。Win分為多個版本&#xff0c;其中家庭版&#xff08;Home&#xff09;和專業版&#xff08;Pro&#xff09;是用戶選擇最多的兩個版本。win10專業版在功能以及安全性方面有著明顯的優勢&#xff0c;所…

微服務循環依賴調用引發的血案

問題表現 最近的迭代轉測后遇到了一個比較有意思的問題。在測試環境整體運行還算平穩&#xff0c;但是過一段時間之后&#xff0c;就開始有接口超時了&#xff0c;日志中出現非常多的 “java.net.SocketTimeoutException: Read timed out”。試了幾次重啟大法&#xff0c;每次…

LeetCode - 852. 山脈數組的峰頂索引

題目 852. 山脈數組的峰頂索引 - 力扣&#xff08;LeetCode&#xff09; 思路 使用二分查找來定位峰頂 對于中間元素&#xff0c;比較它與其右側元素的大小&#xff1a; 如果 arr[mid] < arr[mid1]&#xff0c;說明我們在上坡階段&#xff0c;峰頂在右側 如果 arr[mid…

國產ARM/RISCV與OpenHarmony物聯網項目(二)網關數據顯示

本文需要Web服務器開發基礎&#xff0c;可參考下述博文&#xff1a; 物聯網網關Web服務器--lighttpd服務器部署與應用測試 物聯網網關Web服務器--CGI開發接口 一、數據顯示界面與功能設計 1、功能設計說明 程序代碼結構如下&#xff0c;調用關系見彩色部分標示。 數據顯示界面…

Robyn高性能Web框架系列01:Robyn快速入門

Robyn快速入門 安裝 Robyn1、僅安裝基礎 HTTP 路由功能2、帶擴展功能的安裝 第一個Robyn程序1、創建Robyn應用2、Say Hello!3、啟動Robyn應用 Python世界從來不缺少對于性能的追求&#xff0c;Robyn就是其中之一&#xff0c;它將 Python 的異步功能與 Rust 相結合&#xff0c;在…

微信小程序 -----無限新增刪除,同時算出總合算金額。

<view class="refuelMoney-main" style="padding-bottom: 200rpx;"><!-- <view class="add_record">添加加油記錄</view> --><view class="refuel-itemTextArea"><text style="width: 35%;&quo…

linux “Permission Denied“解決方案

Linux 編譯錯誤排查 在軟件開發過程中&#xff0c;編譯錯誤和版本控制問題是開發者每天都會遇到的挑戰。本文將結合實際案例&#xff0c;詳細講解 Linux 環境下常見編譯錯誤的排查方法 權限拒絕錯誤&#xff08;Permission Denied&#xff09; 當執行腳本或程序時&#xff0…

【慧游魯博】【15】后臺管理系統功能完善:儀表盤、多模態交互日志、簡單問答詞條管理

文章目錄 本次更新多模態交互日志效果涉及代碼文件 儀表盤&#xff08;部分&#xff09;效果涉及代碼文件 簡單問答服務詞條管理效果涉及代碼文件 本次更新 代碼真的太多太多了&#xff0c;不放代碼了 多模態交互日志 數據概覽與篩選功能 時間范圍篩選&#xff1a;提供"…

【力扣 簡單 C】21. 合并兩個有序鏈表

目錄 題目 解法一&#xff1a;迭代 解法二&#xff1a;遞歸 題目 解法一&#xff1a;迭代 struct ListNode* merge(struct ListNode* head1, struct ListNode* head2) {struct ListNode* virHead malloc(sizeof(*virHead));struct ListNode* curNode virHead;struct List…