局部變量和全局變量
在一個文件里磺送,在所有函數(shù)的外面聲明一個變量车份,如果需要其他的文件也能訪問這個變量谋减,使用extern
。
對于其他文件里定義的函數(shù)扫沼,如果要在另一個文件中調用出爹,則需要在另一個文件中加上前置聲明。
int a = 0; // 在文件1.cpp聲明充甚;
extern int a; // 在文件2.cpp中使用a變量以政,需要在前面加extern
如果有很多很多的文件需要使用全局變量,上面聲明全局變量和全局函數(shù)的方法過于繁瑣伴找,可以通過添加頭文件的方法盈蛮,然后對每個文件引用頭文件即可。
注意:不能在 h 文件中直接定義全局變量 int sum = 0技矮,這樣的話如果有多個C/Cpp文件 include 包含這個頭文件的時候就會提示 sum 重復定義了抖誉。所以一定要在 C/Cpp文件中定義該全局變量,之后在 h 頭文件中聲明該全局變量衰倦。
// 頭文件里的寫法袒炉,其中,a和myfun()的定義可以在任意一個文件里面
extern int a;
void myfun();
- static 靜態(tài)類型局部變量只初始化一次樊零,之后的調用都不進行初始化我磁。
數(shù)組
所以數(shù)組的基本定義格式為:類型名 數(shù)組名[常量表達式]孽文;注意,括號里面的數(shù)是常量夺艰,不能用變量來定義芋哭。如果需要定義變長的數(shù)組,需要使用new
動態(tài)申請郁副。
初始化數(shù)組的時候减牺,如果只設置數(shù)組的長度,不初始化值存谎,建議都初始化為0拔疚,即int a[5] = {0}
,否則既荚,如果不給數(shù)組初始化值稚失,其中的值是亂七八糟隨機的數(shù)值,寫代碼的時候可能會遇到問題固以。
// 定義固定長度數(shù)組
int a[50];
string b[20];
// 定義變長的數(shù)組
int num = 100;
int *student = new int[num];
// 初始化數(shù)組的三種方式
int a[5] = {1, 4, 65, 56, 3};
int b[5] = {3,4}; // 后面沒有初始化的默認為0
int b[] = {1, 3, 4, 45, 5, 0}; // 不指定數(shù)組的長度墩虹,直接輸入數(shù)組的元素
字符數(shù)組
在cpp中嘱巾,字符用單引號憨琳,字符串用雙引號。和數(shù)組的初始化類似旬昭,未初始化的話篙螟,其值為隨機值。
字符數(shù)組在某些情況下可以當作字符串來用问拘。注意遍略,字符數(shù)組和字符串是不太一樣的,字符串數(shù)組若沒有 '\0'骤坐,只能當做數(shù)組處理绪杏,若有 '\0',可以看做字符串纽绍,可以cou<<text蕾久,否則不可以。用字符串初始化字符數(shù)組時拌夏,系統(tǒng)會在字符數(shù)組的末尾自動加上一個字符"\0"僧著,因此數(shù)組的大小比字符串中實際字符的個數(shù)大。
char a[5] = {'a', 'b', 'c', 'd', 'e'}; // 初始化一個字符數(shù)組
char a[10] = {'a', 'b', 'c', 'd', 'e'}; // 初始化字符數(shù)組障簿,由于后面未初始化的部分為'\0'盹愚,因此這個也可以當字符串來用
char a[10] = "hello"; // 可以通過雙引號直接初始化字符數(shù)組,未初始化的部分默認為'\0'
char a[] = {'a', 'b', 'c', 'd', 'e', 'd', 'v'}; // 自動初始化字符數(shù)組的長度
// 使用cout輸出字符串的時候站故,如果是一個字符數(shù)組(而不是字符串)皆怕,會輸出一些亂七八糟的東西,比如:
char a[5] = { 'd', 'a', 'l', 'u', 'm' };
cout << a << endl;
// 這是因為,cout輸出的是字符串愈腾,會一直找'\0'朗兵,才停下
地址與指針
可以通過指針更改變量的值,比如說顶滩,將變量傳入一個函數(shù)余掖,想通過這個函數(shù)更改變量的值。
int* pa = 0; \\定義一個指針
int a = 0
int* pa;
pa = &a;
int b = 1;
*pa = b; // 可以給a更改值礁鲁,此步將a賦值為b的值
數(shù)組與指針
數(shù)組的名字是指向數(shù)組的首地址盐欺,即數(shù)組第0個元素的地址,并且數(shù)組的名稱指向的地址不能更換(int * const 類型)仅醇。通過將指針一個int來得到數(shù)組某個元素前/后面的元素冗美。
int num[100] = { 0 };
int* pnum_0 = &num[0];
int* pnum_1 = &num[1];
pnum_0 += 1 // 此時,pnum_0和pnum_1指向的地址是相同的
// 訪問數(shù)組的兩種方法
num[0]; // 下標法訪問數(shù)組
*(num + idx) // 指針法訪問數(shù)組
結構體數(shù)組與指針
結構體作為函數(shù)參數(shù)析二,默認情況下以值傳遞的方式傳入函數(shù)中粉洼。所以,
- 如果需要通過函數(shù)直接修改結構體叶摄,需要以指針的形式傳入属韧;
- 另外,如果結構體里的成員非常多蛤吓,占用空間非常大宵喂,輸入函數(shù)的時候,如果是直接將結構體傳入函數(shù)会傲,函數(shù)在執(zhí)行的時候會再復制一個結構體锅棕,就導致效率降低,這種情況下淌山,也適合將結構體的指針傳入函數(shù)裸燎。
struct student
{
string name[];
int xuehao;
} zhangsan;
zhangsan.name // 訪問成員,用“.”這個符號
struct* lisi; // 如果是指針形式的struct
lisi->name; // 可以直接用箭頭的形式訪問成員
(*lisi).name; // 也可以先將指針前面加上*變成結構本身泼疑,然后用.的形式訪問成員
枚舉類型及定義新的類型名字
可以用 typedef 類型聲明新的類型名字:除了可以用 struct 結構體德绿,union 聯(lián)合體,enum 枚舉等自定義類型以外王浴,還可以使用 typedef 聲明一個新的類型名字來代替已有的類型名脆炎。注意是新的類型名字,只是名字而已氓辣,不是一種全新的類型秒裕,只是改個名字而已。
typedef unsigned int uint; \\ 重新定義類型unsigned int的名字
enum Eweekday
{
Eweekday1 = 1,
Eweekday2 = 2,
Eweekday3 = 3,
Eweekday4 = 4
};
typedef Eweeekday Ewd; // 重新定義枚舉類型Eweekday的名字
引用
變量的引用就是一個變量的別名钞啸,變量和變量的引用代表著同一個變量几蜻。緊跟在數(shù)據(jù)類型后面的&符號就是引用的聲明符號喇潘,其他情況都可以認為是取地址符號。需要注意的是梭稚,
- 引用不是一種獨立的數(shù)據(jù)類型颖低,引用只有聲明,沒有定義弧烤。必須先定義一個變量忱屑,之后對該變量建立一個引用。
- 聲明一個引用時暇昂,必須同時對其初始化莺戒,即聲明該引用代表哪一個變量。例外是將引用作為參數(shù)定義函數(shù)的時候急波,不需要進行初始化从铲。
- 聲明一個引用后,不能再讓其作為另一個變量的引用了澄暮。
- 不能建立引用數(shù)組名段。
- 可以建立引用的引用,也可以建立引用的指針泣懊。
關于引用的性質伸辟,如果在程序中聲明了b是變量a的引用,實際上在內存中為b開辟了一個指針型的存儲單元嗅定,在其中存放變量a的地址自娩,輸出引用b時用踩,就輸出b所指向的變量a的值渠退,相當于輸出*b。引用其實就是一個指針常量脐彩,他的指向不能改變碎乃,只能指向一個指定的變量。所以惠奸,引用的本質還是指針梅誓,所有引用的功能都可以由指針實現(xiàn)。
int a = 5;
int& b = a; // 創(chuàng)建a的引用
void swap(int& a, int& b); // 定義函數(shù)的時候佛南,不需要對引用進行初始化
int a1 = 1, a2 = 5;
int& b = a1; // 將b作為a1的引用
int&b = a2; // 錯誤梗掰!此時就不能將b再作為a2的引用了
int a = 3;
int&b = a;
int&c = b; // c是a的引用的引用
int* p = &b; // p是a的引用的指針
*p = 5; // 此句將a的值改為了5
c = 6; // 此句將a的值又改為了6
//不用指針,用引用的方式實現(xiàn) swap 函數(shù)嗅回,功能是交換兩個整形變量的值及穗,實現(xiàn)如下,跟指針能達到一樣的效果:
void swap(int& a, int& b)
{
int t = a;
a = b;
b = a;
}
new和delete的使用
因為局部變量的局限性绵载,只能在其作用域內使用埂陆,(比如函數(shù)里創(chuàng)建了一個字符串苛白,想通過函數(shù)返回值傳出去,返回的是char*焚虱,函數(shù)就返回不出去购裙,因為是個局部變量),這個時候就需要用new來動態(tài)分配內存鹃栽。
C++ 中的 new操作符和C語言中的malloc
函數(shù)類似躏率,如果不主動 delete掉這段申請的內存的話,它會一直存在民鼓,直到進程結束后系統(tǒng)會回收掉這段資源禾锤。
注意,使用new申請的是內存摹察,因此是一個指針恩掷。
另外,還有一個更重要的new優(yōu)于malloc的地方供嚎,C++中的類class黄娘,用new申請一個類對象的時候,對象申請成功之后會默認調用其構造函數(shù)克滴,而C語言中的malloc只是會申請空間逼争,但是不會調用對象的構造函數(shù)。
int* p = new int(5); //C++ 中使用 new 來申請一個int類型變量的內存
delete p; //刪除變量
int* p = new int[5]; //使用new申請一個包含5個int元素的數(shù)組
delete [] p; //刪除數(shù)組
類的聲明和類的成員函數(shù)
cpp中的類是從struct發(fā)展而來的劝赔,因此誓焦,struct支持的,class都支持着帽。
cpp中杂伟,類的聲明中,如果不寫public仍翰,默認成員是private的赫粥。
C語言中可以用宏來實現(xiàn)一些相對簡單的函數(shù),例如:
宏跟函數(shù)的區(qū)別是予借,在編譯階段就將宏的代碼展開直接替換調用宏的地方越平。所以省去了函數(shù)調用的壓棧、出棧等開銷灵迫。所以執(zhí)行效率方面要比函數(shù)高秦叛。但是宏定義寫起來比較麻煩,對于比較長的瀑粥,不適合用宏定義挣跋。(一般來說,對于那些需要頻繁調用的小函數(shù)利凑,可以寫成宏的形式)
#define MAX_NUM(x, y) (x > y ? x, y)
在cpp的類中浆劲,可以寫inline內聯(lián)函數(shù)(類似于宏)嫌术,將函數(shù)的代碼直接嵌入到調用的地方,大大的減少了函數(shù)調用的開銷牌借,提高了效率度气。
class Student
{
public:
string name;
int num;
int age;
private:
char sex;
inline int max_num(int x, int y)
{
return x > y ? x : y;
}
public:
int get_max_num(int a, int b, int c)
{
int max_ab = max_num(a, b);
return max_ab > c ? max_ab : c;
}
void print_name()
{
cout << "name = " << name << endl;
}
};
注意:
默認情況下,在類體中直接定義/實現(xiàn)的函數(shù)膨报,C++會自動的將其作為inline內聯(lián)函數(shù)來處理磷籍,所以上面代碼中的:max_num、get_max_num现柠、print_name 函數(shù)都會被看成是 inline 內聯(lián)函數(shù)院领。而在類體外部定義的函數(shù)(指的是在類內聲明,在類外定義的函數(shù))C++則會將其作為普通的類的成員函數(shù)來處理够吩。如果想把類外定義的函數(shù)作為類的內聯(lián)函數(shù)比然,需要加上在函數(shù)最前面加上
inline
作顯式聲明。在函數(shù)的聲明或函數(shù)的定義兩者之一作inline聲明即可周循。值得注意的是强法,如果在類體外定義inline函數(shù),則必須將類定義和成員函數(shù)的定義都放在同一個頭文件中(或者寫在同一個源文件中)湾笛,否則編譯時無法進行置換(將函數(shù)代碼的拷貝嵌入到函數(shù)調用點)饮怯。但是這樣做,不利于類的接口與類的實現(xiàn)分離嚎研,不利于信息隱蔽蓖墅。雖然程序的執(zhí)行效率提高了,但從軟件工程質量的角度來看临扮,這樣做并不是好的辦法论矾。只有在類外定義的成員函數(shù)規(guī)模很小而調用頻率較高時,才將此成員函數(shù)指定為內置函數(shù)公条。
this指針
C++語言中每個對象所占用的存儲空間只是該對象的數(shù)據(jù)成員所占用的存儲空間拇囊,而不包括成員函數(shù)代碼所占用的存儲空間。因此靶橱,在調用成員函數(shù)的時候,函數(shù)是通過一個特殊的指針(this
指針)來區(qū)分不同的對象路捧。
有些時候在類里需要用到this关霸,比如類某成員函數(shù)的參數(shù)和類的某個數(shù)據(jù)成員的變量名一樣,這個時候需要加上this來區(qū)分杰扫。
class Student
{
public:
char name[50];
int num;
int age;
public:
void set_age(int age)
{
this->age = age;
};
};
類的構造函數(shù)
構造函數(shù)(constructors)是一種特殊的成員函數(shù)队寇,與其他成員函數(shù)不同,不需要用戶來主動調用它章姓,構造函數(shù)會在對象被建立時自動被調用的佳遣。
構造函數(shù)的注意事項:
- 構造函數(shù)的名字必須與類名同名识埋,不能隨意命名;
- 構造函數(shù)不具有任何類型零渐,不返回任何值窒舟,連 void 都不是;
- 構造函數(shù)不需要用戶調用诵盼,也不應該被用戶調用惠豺,它是對象建立的時候自動被系統(tǒng)調用,用來初始化剛剛建立的對象的风宁;
- 如果用戶沒有定義自己的類的構造函數(shù)洁墙,那么系統(tǒng)會自動生成一個默認的構造函數(shù),只不過該構造函數(shù)的函數(shù)體是空的戒财,也就是什么都不做热监。
不帶參數(shù)的構造函數(shù)叫Default Constructors,能夠為每個參數(shù)提供默認值饮寞。
class Triangular {
Triangular(); // default constructors
}
Triangular::Triangular() {
//default constructor
_length = 1;
_beg_pos =1;
_next = 1;
}
其他的自定義的constructor類似:
Triangular::Triangular(int len, int bp)
{
// _length和_beg_pos都必須>=1
_length = len > 0 ? len : 1;
_beg_pos = bp > 0 ? bp : 1;
_next = _beg_pos - 1;
}
另一種初始化的語法是member initialization list(成員初始化表)狼纬。
Member initialization list緊接在參數(shù)表最后的冒號后面,是一個以逗號為分割的列表骂际,其中疗琉,欲賦值給class中member的數(shù)值被置于member名稱后面的小括號中:
Triangular::Triangular(const Triangular &rhs)
: _length(rhs._length),
_beg_pos(rhs._beg_pos),
_next(rhs._beg_pos-1)
{ } // Yes, it's empty.
一旦class的對象被定義出來,編譯器便自動根據(jù)獲得的參數(shù)歉铝,挑選出應被調用的constructor盈简,例如:
Triangular t;
Triangular t2(10, 3);
Triangular t3 = 8; //這是在調用constructor,而不是assignment operator
Triangular t5(); // 不能這樣寫太示,這樣會把t5當成一個函數(shù)柠贤!
函數(shù)的重載
C++允許同一函數(shù)名定義多個函數(shù),這些函數(shù)的參數(shù)類型和個數(shù)可以不相同类缤,而且至少要有一個不相同(如果都相同的話就會報重復定義的鏈接錯誤了)臼勉。使一個函數(shù)名可以多用。
函數(shù)重載的要求:
重載函數(shù)的參數(shù)個數(shù)餐弱、參數(shù)類型宴霸、參數(shù)順序 三者中必須至少有一種不同(不然會產生調用疑惑)。函數(shù)的返回值類型可以相同也可以不同膏蚓。
// 函數(shù)重載的例子瓢谢,這里是求兩個不同類型數(shù)字的最大值
int max_num(int a, int b);
bool max_num(int a, int b);
float max_num(float a, float b);
函數(shù)的默認參數(shù)
為了使函數(shù)更加靈活,cpp支持默認參數(shù)驮瞧。比如下面的例子:
函數(shù)默認參數(shù)的注意事項:
- 在函數(shù)聲明的時候指定氓扛,如果沒有函數(shù)的聲明則可以放在函數(shù)的定義中,但是聲明和定義只能選一個论笔;
- 從第一個有默認值的參數(shù)開始采郎,后面的所有參數(shù)必須都有默認值才行千所;
- 調用的時候如果要自定義非第一個默認值的參數(shù),那么前面所有的參數(shù)都要明確的寫上默認值才行蒜埋;
- 從使用角度來說函數(shù)的默認值比重載更方便淫痰,從函數(shù)內部實現(xiàn)角度來說比函數(shù)的重載更復雜。
void get_min_max(int src[], int arr_len, int* max_v = NULL, int* min_v = NULL); // 函數(shù)的聲明
void get_min_max(src, arr_len, NULL, min_v); // 如果不想輸入第三個參數(shù)理茎,就輸入其默認的值
void get_min_max(src, arr_len, NULL); // 如果不想輸入最后一個參數(shù)黑界,可以直接省略
類的析構函數(shù)
析構函數(shù)也是一個在類中跟構造函數(shù)類似的特殊功能的成員函數(shù)。只不過它的作用是與構造函數(shù)相反皂林,是在對象的生命周期結束的時候會被自動調用的朗鸠。在C++中析構函數(shù)的名字跟類名相同,并且前面帶上一個取反的符號~础倍,表達的意思也就是跟構造函數(shù)的過程相反烛占。
析構函數(shù)不返回任何值,沒有函數(shù)類型沟启,也沒有任何函數(shù)的參數(shù)忆家。所以析構函數(shù)不能被重載。一個類可以有多個構造函數(shù)德迹,但只能有一個析構函數(shù)芽卿。
以下幾種情況會自動調用析構函數(shù):
- 如果在一個函數(shù)中定義了一個局部變量的對象,那么當這個函數(shù)執(zhí)行結束時也就是該變量對象生命周期結束的時候胳搞,所以析構函數(shù)會被自動調用卸例;
- 全局變量或者static類型的變量,他們的生命周期一般是在程序退出的時候肌毅,這時候該對象的析構函數(shù)才會被調用筷转;
- 如果是用new操作符動態(tài)的創(chuàng)建了一個對象,只有當用delete進行釋放該對象的時候悬而,析構函數(shù)才會被調用呜舒;
對象的賦值與復制
用等號=
給對象賦值,只是對對象的成員變量的賦值笨奠,對于成員函數(shù)來說不理會袭蝗,也不做賦值處理,因為本身每個類的成員函數(shù)都一樣艰躺,不需要賦值呻袭。
有些成員是不能用=
賦值的,比如成員變量是其他類對象的時候腺兴。
對象的賦值有時候是危險的,比如在對象里使用了new動態(tài)分配內存廉侧,且在析構函數(shù)里delete了內存页响,這個時候篓足,在一個局部空間中對對象進行賦值,程序會崩潰闰蚕。
Student zhangsan = {"zhangsan", 1002, 20};
Student lisi(zhangsan); // 對象的復制
Student wangwu = lisi; // 對象的賦值
對象的復制栈拖,用到了一個特殊的構造函數(shù),名為拷貝構造函數(shù)没陡,用法如下:
class Student
{
public:
char name[50];
int num;
int age;
Student(char* pname, int t_num, int t_age) :num(t_num), age(t_age)
{
strcpy(name, pname);
}
Student(Student& stud)
{
strcpy(name, stud.name);
num = stud.num;
age = stud.age;
}
};
拷貝構造函數(shù)的特點:
- 也是構造函數(shù)涩哟,所以函數(shù)名字就是類名字,且無返回值盼玄;
- 參數(shù)是一般是本類的對象的引用贴彼;
- 如果類沒有提供拷貝構造函數(shù),那么編譯器會默認生成一個拷貝構造函數(shù)埃儿,作用比較單一器仗,只是簡單的將成員變量的值進行復制過去而已。
盡管編譯器會默認生成一個默認的拷貝構造函數(shù)童番,但是由于類的成員變量中有一些是無法進行賦值精钮,因此需要自定義實現(xiàn)拷貝構造函數(shù)。
類的靜態(tài)成員
類的靜態(tài)成員變量:
- 所有對象都可以直接訪問這個靜態(tài)成員變量剃斧,而且值是一樣的轨香;
- 靜態(tài)成員變量在內存中只占用一份存儲空間;
- 靜態(tài)成員變量的值對于所有對象來說都是一樣的幼东。如果其中一個對象調用函數(shù)將其改變了臂容,那么其他成員在訪問這個靜態(tài)成員變量的時候的值都是改變之后的;
- 只要在類中定義了類的靜態(tài)成員變量筋粗,那么就占用存儲空間了策橘,不管有沒有定義這個類的對象,因為靜態(tài)成員變量不屬于任何類對象娜亿,而是屬于該類丽已;
- 靜態(tài)數(shù)據(jù)成員需要在類外進行聲明或聲明并初始化,否則在使用的時候會報鏈接的錯誤买决;
- 類的靜態(tài)成員在定義的時候需要加 static沛婴,在類外聲明的時候不需要加 static 關鍵字;
- 不能用構造函數(shù)的參數(shù)初始化表的形式對靜態(tài)成員進行初始化操作督赤;
- 靜態(tài)數(shù)據(jù)成員既可以通過對象名引用嘁灯,也可以通過類名來直接引用;
- public 公有類型的靜態(tài)數(shù)據(jù)成員躲舌,可以被類的對象引用丑婿,也可以直接用類名來引用。但如果靜態(tài)數(shù)據(jù)成員被定義成private私有的,那么通過對象或者類名來引用都是不可以的羹奉,必須通過類的public類型的靜態(tài)成員函數(shù)引用秒旋。
類的靜態(tài)成員函數(shù):
- 類的靜態(tài)成員函數(shù)也不屬于該類的對象,而是屬于這個類
- 類的靜態(tài)成員函數(shù)可以通過類對象調用诀拭,也可以通過類名調用迁筛;
- 類的靜態(tài)成員函數(shù)是屬于類,不屬于任何對象耕挨,所以靜態(tài)成員函數(shù)中沒有this指針细卧,也就無法訪問本類的非靜態(tài)成員變量,因為不知道是哪個對象的筒占。
- 類的靜態(tài)成員函數(shù)可以直接引用類的靜態(tài)成員變量贪庙,因為他們的作用域相同,都是屬于該類的赋铝。
運算符重載(Operator Overloading)
同一個運算符可以有不同的功能插勤。
運算符重載格式:
返回值類型 operator 運算符名稱 (形參列表){
//TODO:
}
在類中重載運算符:
class complex{
public:
complex();
complex(double real, double imag);
public:
//聲明運算符重載
complex operator+(const complex &A) const;
void display() const;
private:
double m_real; //實部
double m_imag; //虛部
};
complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
//實現(xiàn)運算符重載
complex complex::operator+(const complex &A) const{
return complex(this->m_real + A.m_real, this->m_imag + A.m_imag);
}
void complex::display() const{
cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}
int main(){
complex c1(4.3, 5.8);
complex c2(2.4, 3.7);
complex c3;
c3 = c1 + c2;
c3.display();
return 0;
}
運算符重載函數(shù)不僅可以作為類的成員函數(shù),還可以作為全局函數(shù)革骨。
在全局范圍內重載運算符:
可以看到农尖,運算符重載函數(shù)不是 complex 類的成員函數(shù),但是卻用到了 complex 類的 private 成員變量良哲,所以必須在 complex 類中將該函數(shù)聲明為友元函數(shù)盛卡。
#include <iostream>
using namespace std;
class complex{
public:
complex();
complex(double real, double imag);
public:
void display() const;
//聲明為友元函數(shù)
friend complex operator+(const complex &A, const complex &B);
private:
double m_real;
double m_imag;
};
complex operator+(const complex &A, const complex &B);
complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
void complex::display() const{
cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}
//在全局范圍內重載+
complex operator+(const complex &A, const complex &B){
complex C;
C.m_real = A.m_real + B.m_real;
C.m_imag = A.m_imag + B.m_imag;
return C;
}
int main(){
complex c1(4.3, 5.8);
complex c2(2.4, 3.7);
complex c3;
c3 = c1 + c2;
c3.display();
return 0;
}