學(xué)做網(wǎng)站 書陜西seo快速排名
目錄
前言:
?1.c++的第一個程序
2.命名空間?
2.1 namespace的定義
2.2 命名空間使用
3.c++輸入&輸出
4.缺省參數(shù)?
5.函數(shù)重載?
前言:
? 我們在之前學(xué)完了c語言的大部分語法知識,是不是意味著我們可以馬上從事開發(fā)呢?其實行業(yè)中的絕大部分崗位都用不到c語言,那我們?yōu)槭裁匆獙W(xué)c語言呢。c語言雖然和我們?nèi)粘i_發(fā)沒有很大的關(guān)系,但是學(xué)習(xí)c語言可以為我們學(xué)習(xí)其他編程語言打下堅實的基礎(chǔ),拓寬我們的編程思維,而在考研中,許多學(xué)校也要求學(xué)習(xí)c語言,數(shù)據(jù)結(jié)構(gòu)也大多是由c語言實現(xiàn)的,所以學(xué)完c語言雖然無法讓我們馬上從事開發(fā)行業(yè),但是可以讓我們獲得諸多好處,讓學(xué)完c語言的我們,學(xué)習(xí)可以從事開發(fā)工作的編程語言——c++,取得事半功倍的效果。
?1.c++的第一個程序
?C++兼容C語?絕?多數(shù)的語法,所以C語?實現(xiàn)的hello world依舊可以運?,C++中需要把定義?件 代碼后綴改為.cpp,vs編譯器看到是.cpp就會調(diào)?C++編譯器編譯,linux下要?g++編譯,不再是gcc:
// test.cpp
#include<stdio.h>
int main()
{printf("hello world\n");return 0;
}
當(dāng)然C++有?套??的輸?輸出,嚴(yán)格說C++版本的hello world應(yīng)該是這樣寫的:?
// test.cpp
// 這?的std cout等我們都看不懂,沒關(guān)系,下?我們會依次講解
#include<iostream>
using namespace std;
int main()
{cout << "hello world\n" << endl;return 0;
}
運行這段代碼:
熟悉的hello world就被我們使用c++語言實現(xiàn)了。?
2.命名空間?
? ?在C/C++中,變量、函數(shù)和后?要學(xué)到的類都是?量存在的,這些變量、函數(shù)和類的名稱將都存在于全 局作?域中,可能會導(dǎo)致很多沖突。使?命名空間的?的是對標(biāo)識符的名稱進?本地化,以避免命名 沖突或名字污染,namespace關(guān)鍵字的出現(xiàn)就是針對這種問題的。
c語?項?類似下?程序這樣的命名沖突是普遍存在的問題,C++引?namespace就是為了更好的解決這樣的問題
我們來看這樣一段代碼:
#include <stdio.h>
#include <stdio.h>
int rand = 10;
int main()
{printf("%d\n", rand);return 0;
}
如果看不懂,試著運行一下:
可以看到此時代碼還可以正常運行,但是如果我們運行下面這段代碼:
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{// 編譯報錯:error C2365: “rand”: 重定義;以前的定義是“函數(shù)”printf("%d\n", rand);return 0;
}
看一下運行結(jié)果:
當(dāng)我們加上stdlib頭文件時,程序卻顯示運行失敗,而這就是典型的命名沖突問題,stdlib庫中存在rand函數(shù),如果我們不包含這個頭文件,那么它在程序中就是一個普通的變量名,當(dāng)我們包含了這個頭文件之后,rand就變成了庫函數(shù)名,而我們使用一個庫函數(shù)的函數(shù)名來作為一個變量名,程序當(dāng)然會運行失敗啦。
2.1 namespace的定義
?(1)定義命名空間,需要使?到namespace關(guān)鍵字,后?跟命名空間的名字,然后接?對{}即可,{}中 即為命名空間的成員。命名空間中可以定義變量/函數(shù)/類型等
namespace a
{int i = 20;//定義變量int add(int x, int y){return x + y;} //定義函數(shù)
}
(2)namespace本質(zhì)是定義出?個域,這個域跟全局域各?獨?,不同的域可以定義同名變量,所以下?的rand不再沖突了
#include<iostream>
#include<stdlib.h>
namespace a
{int rand=100;
}
int main()
{return 0;
}
(3)C++中域有函數(shù)局部域,全局域,命名空間域,類域;域影響的是編譯時語法查找?個變量/函數(shù)/ 類型出處(聲明或定義)的邏輯,所以有了域隔離,名字沖突就解決了。局部域和全局域除了會影響編譯查找邏輯,還會影響變量的聲明周期,命名空間域和類域不影響變量聲明周期。?
(4)namespace只能定義在全局,當(dāng)然他還可以嵌套定義。
#include<iostream>
#include<stdlib.h>
namespace a
{int rand=100;namespace b //嵌套使用命名空間{int rand = 90;}
}
int main()
{return 0;
}
(5)項??程中多?件中定義的同名namespace會認(rèn)為是?個namespace,不會沖突。
(6)C++標(biāo)準(zhǔn)庫都放在?個叫std(standard)的命名空間中。
2.2 命名空間使用
編譯查找?個變量的聲明/定義時,默認(rèn)只會在局部或者全局查找,不會到命名空間??去查找。所以下?程序會編譯報錯。所以我們要使?命名空間中定義的變量/函數(shù),有三種?式:
(1)指定命名空間訪問,項?中推薦這種?式。
#include<iostream>
#include<stdlib.h>
namespace a
{int rand=100;namespace b{int rand = 90;}
}
int main()
{std::cout << a::rand << std::endl;//使用空間名加::(變量名/函數(shù)名)就可以訪問空間中的
//變量/函數(shù)return 0;
}
(2)sing將命名空間中某個成員展開,項?中經(jīng)常訪問的不存在沖突的成員推薦這種?式。
#include<iostream>
#include<stdlib.h>
namespace a
{int c=100;namespace b{int c = 90;}
}
using a::c;
//展開空間中某一個變量
int main()
{std::cout << a::c << std::endl;return 0;
}
(3)展開命名空間中全部成員,項?不推薦,沖突?險很?,?常?練習(xí)程序為了?便推薦使?。
#include<iostream>
#include<stdlib.h>
namespace a
{int c=100;namespace b{int c = 90;}
}
using namespace a;
//展開空間a
int main()
{std::cout << c << std::endl;return 0;
}
3.c++輸入&輸出
(1)<iostream>是Input Output Stream的縮寫,是標(biāo)準(zhǔn)的輸?、輸出流庫,定義了標(biāo)準(zhǔn)的輸?、輸出對象。
(2)std::cin是istream類的對象,它主要?向窄字(narrow characters (of type char))的標(biāo)準(zhǔn)輸 ?流。
(3)std::cout 是ostream 類的對象,它主要?向窄字符的標(biāo)準(zhǔn)輸出流。
(4)std::endl 是?個函數(shù),流插?輸出時,相當(dāng)于插??個換?字符加刷新緩沖區(qū)。
(5)<<是流插入運算符,>>是流提取運算符。(C語?還?這兩個運算符做位運算左移/右移)
? (6)使?C++輸?輸出更?便,不需要像printf/scanf輸?輸出時那樣,需要?動指定格式,C++的輸? 輸出可以?動識別變量類型(本質(zhì)是通過函數(shù)重載實現(xiàn)的,這個以后會講到),其實最重要的是 C++的流能更好的?持?定義類型對象的輸?輸出。
(7)O流涉及類和對象,運算符重載、繼承等很多?向?qū)ο蟮闹R,這些知識我們還沒有講解,所以這 ?我們只能簡單認(rèn)識?下C++IO流的?法,后?我們會有專?的?個章節(jié)來細(xì)節(jié)IO流庫。
(8)cout/cin/endl等都屬于C++標(biāo)準(zhǔn)庫,C++標(biāo)準(zhǔn)庫都放在?個叫std(standard)的命名空間中,所以要 通過命名空間的使??式去?他們。
(9)?般?常練習(xí)中我們可以usingnamespacestd,實際項?開發(fā)中不建議使用using namespace std。
(10)這?我們沒有包含,也可以使?printf和scanf,在包含間接包含了。vs系列 編譯器是這樣的,其他編譯器可能會報錯。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{int a = 0;double b = 0.1;char c = 'x'; cout << a << " " << b << " " << c << endl;std::cout << a << " " << b << " " << c << std::endl;scanf("%d%lf", &a, &b);printf("%d %lf\n", a, b);// 可以?動識別變量的類型cin >> a;cin >> b >> c;cout << a << endl;cout << b << " " << c << endl;return 0;
}
#include<iostream>
using namespace std;
int main()
{// 在io需求?較?的地?,如部分?量輸?的競賽題中,加上以下3?代碼// 可以提?C++IO效率ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);return 0;
}
4.缺省參數(shù)?
(1)缺省參數(shù)是聲明或定義函數(shù)時為函數(shù)的參數(shù)指定?個缺省值。在調(diào)?該函數(shù)時,如果沒有指定實參, 則采?該形參的缺省值,否則使?指定的實參,缺省參數(shù)分為全缺省和半缺省參數(shù)。(有些地?把 缺省參數(shù)也叫默認(rèn)參數(shù))
#include <iostream>
#include <assert.h>
using namespace std;
void Func(int a = 0)
{cout << a << endl;
}
int main()
{Func(); // 沒有傳參時,使?參數(shù)的默認(rèn)值Func(10); // 傳參時,使?指定的實參return 0;
}
(2)全缺省就是全部形參給缺省值,半缺省就是部分形參給缺省值。C++規(guī)定半缺省參數(shù)必須從右往左依次連續(xù)缺省,不能間隔跳躍給缺省值。
(3)帶缺省參數(shù)的函數(shù)調(diào)?,C++規(guī)定必須從左到右依次給實參,不能跳躍給實參。
#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
int main()
{Func1();Func1(1);Func1(1,2);Func1(1,2,3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0;
}
(4)函數(shù)聲明和定義分離時,缺省參數(shù)不能在函數(shù)聲明和定義中同時出現(xiàn),規(guī)定必須函數(shù)聲明給缺省值。?
void func(int i, int x, int y = 78, int q = 56);
//函數(shù)聲明和定義分離,缺省參數(shù)必須給聲明函數(shù)中
#include<iostream>
using namespace std;
void func(int i, int x, int y, int q)
{cout << i << x << y << q << endl;
}
int main()
{func(199,90);return 0;}
5.函數(shù)重載?
??C++?持在同?作?域中出現(xiàn)同名函數(shù),但是要求這些同名函數(shù)的形參不同,可以是參數(shù)個數(shù)不同或者類型不同。這樣C++函數(shù)調(diào)?就表現(xiàn)出了多態(tài)?為,使?更靈活。C語?是不?持同?作?域中出現(xiàn)同 名函數(shù)的。
// 1、參數(shù)類型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、參數(shù)個數(shù)不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
// 3、參數(shù)類型順序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
而返回值不能作為重載條件,因為調(diào)?時也?法區(qū)分:
//void fxx()
//{}
//
//int fxx()
//{
// return 0;
//}
// 下?兩個函數(shù)構(gòu)成重載
// f()但是調(diào)?時,會報錯,存在歧義,編譯器不知道調(diào)?誰
void f1()
{cout << "f()" << endl;
}
void f1(int a = 10)
{cout << "f(int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}