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