『C++』我想学C++,C++太难了,那我想入门,给我10分钟我带你入门
從第一個CPP開始寫起:
"hello,world"
c++的具體結構
簡單來說,一個C++程序就是由若干頭文件和函數組成。
#include <iostream>就是一條預處理命令, 它的作用是通知C++編譯系統在對C++程序進行正式編譯之前需做一些預處理工作,導入頭文件下的函數,與類。
函數就是實現代碼邏輯的一個小的單元。
必不可少之主函數
一個C++程序有且只有一個主函數,即main函數。
C++程序就是執行主函數里的代碼,也可以說這個主函數就是C++中的唯一入口。
而main前面的int就是主函數的類型.
cout 是格式輸出函數,這里就記住它的功能就是在屏幕上輸出指定的信息
return是函數的返回值,根據函數類型的不同,返回的值也是不同的。
endl是一個函數模板,這里知道是用來換行的即可。
(注意:C++程序一定是從主函數開始執行的)
良好習慣之規范
一個說明或一個語句占一行,例如:包含頭文件、一個可執行語句結束都需要換行。
函數體內的語句要有明顯縮進,通常以按一下Tab鍵為一個縮進。
括號要成對寫,如果需要刪除的話也要成對刪除。
當一句可執行語句結束的時候末尾需要有分號。
代碼中所有符號均為英文半角符號。
程序解釋——注釋
注釋是寫給程序員看的,不是寫給電腦看的。
C++注釋方法有兩種:
多行注釋: /* 注釋內容 */
單行注釋: //注釋一行
有名有姓的C(標識符)
C++規定,標識符可以是字母(A~Z,a~z)、數字(0~9)、下劃線_組成的字符串,并且第一個字符必須是字母或下劃線。在使用標識符時還有注意以下幾點:
標識符的長度最好不要超過8位,因為在某些版本的C中規定標識符前8位有效,當兩個標識符前8位相同時,則被認為是同一個標識符。
標識符是嚴格區分大小寫的。例如Imooc和imooc 是兩個不同的標識符。
標識符最好選擇有意義的英文單詞組成做到"見名知意",不要使用中文。
標識符不能是C++的關鍵字。
變量命名規則:傳送門
變量及賦值
變量就是可以變化的量,而每個變量都會有一個名字(標識符)。變量占據內存中一定的存儲單元。使用變量之前必須先定義變量,要區分變量名和變量值是兩個不同的概念。
變量定義的一般形式為:數據類型 變量名;
多個類型相同的變量:數據類型 變量名, 變量名, 變量名…;
注意:在定義中不允許連續賦值,如int a=b=c=5;是不合法的。
變量的賦值分為兩種方式:
先聲明再賦值
聲明的同時賦值
基本數據類型
C++中,數據類型可分為:
基本數據類型
構造數據類型
指針類型
空類型四大類
數據類型分類
最常用的整型, 實型與字符型(char,int,float,double):
整型數據是指不帶小數的數字(int,short int,long int, unsigned int, unsigned short int,unsigned long int):
自動類型轉換
數據類型存在自動轉換的情況.
自動轉換發生在不同數據類型運算時,在編譯的時候自動完成。
char類型數據轉換為int類型數據遵循ASCII碼中的對應值.
字節小的可以向字節大的自動轉換,但字節大的不能向字節小的自動轉換
char可以轉換為int,int可以轉換為double,char可以轉換為double。但是不可以反向。
強制類型轉換
強制類型轉換是通過定義類型轉換運算來實現的。其一般形式為:
(數據類型) (表達式)
其作用是把表達式的運算結果強制轉換成類型說明符所表示的類型
在使用強制轉換時應注意以下問題:
數據類型和表達式都必須加括號, 如把(int)(x/2+y)寫成(int)x/2+y則成了把x轉換成int型之后再除2再與y相加了。
轉換后不會改變原數據的類型及變量值,只在本次運算中臨時性轉換。
強制轉換后的運算結果不遵循四舍五入原則。
數據類型簡單的列舉
char :1個字節char*(即指針變量): 4個字節(32位的尋址空間是2^32, 即32個bit,也就是4個字節。同理64位編譯器)short int : 2個字節int: 4個字節unsigned int : 4個字節float: 4個字節double: 8個字節long: 4個字節long long: 8個字節unsigned long: 4個字節 64位編譯器:char :1個字節char*(即指針變量): 8個字節short int : 2個字節int: 4個字節unsigned int : 4個字節float: 4個字節double: 8個字節long: 8個字節long long: 8個字節unsigned long: 8個字節常用庫函數
(1)數學函數
平方根——sqrt
絕對值——fabs
乘冪——第一個參數作為底,第二個是指數double pow(double, double)
實數的余數——兩個參數分別是被除數和除數double fmod(double, double)
(2)其他常用函數
ceil(x)求出不小于x的最小整數(返回與這個整數對應的double值)
floor(x)求出不大于x的最大整數(返回與這個整數對應的double值)
modf(x, doubleip)把x分解為小數部分和整數部分,小數部分作為函數返回值,整數部分通過指針ip返回。
Ps:輸出小數cout<<fixed<<setprecision(2)<<?
ASCII碼
getchar()讀入一個ASCII碼
putchar()輸出一個ASCII碼
#define 宏常量
定義:#define 標識符 字符串
1.宏定義是用宏名來表示一個字符串,在宏展開時又以該字符串取代宏名,這只是一種簡單的代換,字符串中可以含任何字符,可以是常數,也可以是表達式,預處理程序對它不作任何檢查。如有錯誤,只能在編譯已被宏展開后的源程序時發現。
2.宏定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。
3.宏定義其作用域為宏定義命令起到源程序結束。如要終止其作用域可使用#undef命令。
簡而言之,#define可以理解為起名函數,#define number 999 number就被簡單的定義為999。
目前聽說但未遇到的用法:
1.有參宏定義
2.宏定義中的特殊操作符
3.宏定義中的多行定義
4.防止重復包含頭文件
條件分支結構
1.if分支語句
通過以上學習C語言(c++)我們能夠解決什么問題?
1.從整體上說,可以應對簡單的順學結構、條件分支結構。
2.對于小的方面,
(1)有關ASCII碼的計算
(2)浮點數的輸入輸出
(3)驅魔,取余,取整
(4)簡單的數學運算題
(5)倒序輸出
(6)中小學的應用題
…
3.生活方面,
(1)解決生活中簡單的實際問題,將生活中的問題通過程序,制定出對于一類事情解決方案,可以起到“智慧偷懶”的效果。對于郵費計算,吃飯付款等等各類事情都可以通過寫程序得到最優解。
for循環
程序執行順序,先執行表達式1,驗證表達式2是否為真,執行循環體語句,執行表達式3,再驗證表達式2是否為真,若為真繼續執行上述操作,直至表達式2不成立,跳出循環體,執行后續語句。
特殊用法
for()中可以不加語句也可以添加部分語句,語句不存在時跳過執行,參考while循環。
參考例題
描述
孫老師講授的《計算概論》這門課期中考試剛剛結束,他想知道考試中取得的最高分數。因為人數比較多,他覺得這件事情交給計算機來做比較方便。你能幫孫老師解決這個問題嗎?
輸入
輸入兩行,第一行為整數n(1 <= n <
100),表示參加這次考試的人數.第二行是這n個學生的成績,相鄰兩個數之間用單個空格隔開。所有成績均為0到100之間的整數。
輸出
輸出一個整數,即最高的成績。
#include<iostream> #include<cmath> #include<iomanip> using namespace std; int main() {int i,a=0,b=0;int score[100];cin>>a;for(i=0;i<a;i++){cin>>score[i];b=max(b,score[i]);}cout<<b; return 0; }while循環-適合不確定循環次數時使用
while循環
運行順序:首先檢驗條件語句是否為真若為真,執行循環體,直至條件不成立,跳出循環。
參考例題 金幣 描述
國王將金幣作為工資,發放給忠誠的騎士。第一天,騎士收到一枚金幣;之后兩天(第二天和第三天)里,每天收到兩枚金幣;之后三天(第四、五、六天)里,每天收到三枚金幣;之后四天(第七、八、九、十天)里,每天收到四枚金幣……這種工資發放模式會一直這樣延續下去:當連續N天每天收到N枚金幣后,騎士會在之后的連續N+1天里,每天收到N+1枚金幣(N為任意正整數)。
你需要編寫一個程序,確定從第一天開始的給定天數內,騎士一共獲得了多少金幣。 輸入 一個整數(范圍1到10000),表示天數。 輸出
騎士獲得的金幣數 樣例輸入 6 樣例輸出 14
do-while()循環
do { //循環體 }while() 執行順序大體與while循環一樣,但程序至少執行一遍。 將上述程序改寫為do-while()循環
#include <iostream> #include <cstdio> using namespace std; int main() { int a,i=1,sum=0; cin>>a; do { a=a-i; sum=sum+i*i; if(a<0) sum=sum+a*i; i++; }while(a>0)cout<<sum; return 0; }循環體可以用來解決的問題
從上述題目中可以看到
如果程序中存在需要連續反復執行多次的操作,就可以采用。
另外針對操作次數已經,建議使用計數循環方式。
如果操作次數未知,要求達到指定目標才停止,就采用條件循環。
很多函數大都是循環體。
字符串與數組
數組的操作
1°memcpy函數(頭文件<cstring)
數組不能直接復制,可利用memcpy函數
void *memcpy(void *dest, void *src, unsigned int count);
memcpy 函數用于 把資源內存(src所指向的內存區域) 拷貝到目標內存(dest所指向的內存區域);一個size變量控制拷貝的字節數;
使用方式memcpy(b,a,sizeof(int)*k) 從a中賦值k個元素到b數組。
sizeof(int)k表示計算int型所占字節數,然后再乘以k。
類比sizeof(intk),表示計算指向整型的指針變量k所占的字節數。
再淺顯討論sizeof的作用
sizeof(int)*k之所以用sizeof(int)*k而不是用k,因為sizeof(int)*k返回的是字節數,因為數組是int 型的sizeof計算每個元素的字節長度,在乘以k既k個元素的字節,因為memcyp需要知道拷貝內存的字節數。所以拷貝是從開頭開始計算,即k個元素是從a[0]開始計算。由此可以推出將a中元素全部拷貝到b數組中,memcpy(b,a,sizeof(a))。
2°memset函數(頭文件<cstring)
void *memset(void *s , int ch , size_t n ) 在一段內存塊中填充某一個給定的值,常用于較大的對結構體和數組的清零操作。
memset(結構體/數組名 , "用于替換的字符“ , 前n個字符 );
用法可以參考memcpy,也要用sizeof來計算字節。
總結內存復制需要計算字節。
字符串操作String
用法跟char []沒有太大區別,但是功能更加強大
函數
概念:組成C語言源程序的基本單位,完成特定功能的代碼段.
例如main()為主函數:程序入口
函數定義到使用分三步:
1.聲明
2.定義函數
3.調用函數。
一、函數的聲明:
在調用函數之前,進行該函數的聲明 ,由于程序是由上到下執行,編譯器不知道我們是否已經定義了某個函數,為了防止編譯器編譯的時候報錯(函數調用)所以,要告訴編譯器,我已經定義了哪些函數。
二、函數的定義:
返回值類型 函數名(形式參數類型 參數名1,……)
{
函數體;//return (返回值)}返回值類型有兩種:
有參無返回值:void test(int x,float y){ }
有參有返回值: int max(int x,int y){ return x>y?x:y; }
函數的調用
定義:函數名(實參列表);
1)形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。
2)實參可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須具有確定的值 。
3)實參和形參在數量上,類型上,順序上應嚴格一致,否則會發生類型不匹配的錯誤。
實參一定是確定值 不需要類型!!!
1.函數的參數
1)形參和實參
形參:在定義函數的時候,函數名后面小括號中的參數 , 格式: 數據類型 變量 如:int x;
形參的作用域:只能在本函數中使用
實參:調用函數的時候傳遞的參數
2)參數的傳遞的過程
實參的值拷貝一份放到函數形參中
3)函數傳參有三種傳參方式:傳值、傳址、傳引用
①按值傳遞
ⅰ形參和實參各占一個獨立的存儲空間。
ⅱ形參的存儲空間是函數被調用時才分配的,調用開始,系統為形參開辟一個臨時的存儲區,然后將各實參傳遞給形參,這是形參就得到了實參的值。
②地址傳遞
地址傳遞與值傳遞的不同在于,它把實參的存儲地址傳送給形參,使得形參指針和實參指針指向同一塊地址。因此,被調用函數中對形參指針所指向的地址中內容的任何改變都會影響到實參。
③引用傳遞
引用傳遞是以引用為參數,則既可以使得對形參的任何操作都能改變相應數據,又使函數調用方便。引用傳遞是在形參調用前加入引用運算符“&”。引用為實參的別名,和實參是同一個變量,則他們的值也相同,該引用改變則它的實參也改變。
2.函數的返回值
概念:執行函數體中的程序段,最后獲取的值并返回給主調函數,函數的返回值只能通過return 關鍵字進行返回
格式:return 表達式;/ return (表達式);
返回值類型要與返回值相同。
是否要定義形參看是否有未知內容參與運算,調用時實參必須對應.參數傳遞的是值。
函數中可以有多個return ,但是只有一個起作用,因為函數會結束后會帶回一個值。
函數調用和返回
函數調用會使程序的控制權傳遞給被調函數而當前活動會被掛起。
當前函數執行完成后主函數從調用語句之后的語句恢復執行。
函數在執行完函數體的最后一條語句或或遇到return語句時返回。
返回類型和return語句
return 語句形式
return;
return表達式;
非void函數必須返回一個與聲明類型匹配的值否則會引起編譯錯誤。
返回值 默認情況下,函數的返回值是按值傳遞的,得到控制權的函數將接受return語句中指定的表達式值得副本。
返回引用(我覺得特別重要)
函數聲明為返回引用,則不需要對return語句中的表達式進行復制,而是返回對象本身。
函數返回引用僅是它所指向對象的一個別名。
//找出s1和s2中比較短的一個并返回其引用
const string& shorter(const string& s1, const string& s2)
{
return (s1.size() <= s2.size()) ? s1 : s2;
}
//函數返回結果時不會真正復制對象,返回的就是s1或s2本身。
string a=hello;
string b=word;
shorter(a,b)=“Hello”;//返回值為引用。
cout<<a<<’ '<<b;//Hello word;
注:對引用返回值的修改會改變實際返回的對象,為了避免這種情況,可以將返回值聲明稱const。
不能返回自動局部對象的指針或引用:函數執行結束后,函數占用的棧存儲空間被釋放,原本位于這段存儲空間中的局部對象和臨時變量都被釋放,返回的局部對象引用或指針指向不再有效的內存區域
重載函數
如果同一個作用域內的幾個函數名字相同但形參列表不同,則他們是重載函數
形參列表不同的概念:
1.形參數量不同
2.形參類型不同
3.常指針與指針不同,常引用與引用不同。
調用函數時如果存在多個重載函數,編譯器將根據函數調用中指定的實參進行選擇。
存儲類別 static靜態存儲
static對象在控制流程第一次到達其定義點時被初始化,如果沒有提供初始值就被自動初始化為0;
在函數的后續調用中,初始化語句被跳過
靜態對象的值在函數被多次調用之間保持有效,生存期會延續到整個程序結束但他的作用于仍然是局部的,因此需要在同一函數的兩次調用之間保留某些數據時可以使用局部static對象。
素數的判斷
1定義法
除了1與自身外無其他因數。
2.對定義法的改進
若a不是素數則在2到sqrt(a)的范圍內一定存在其因數。所以
最大公約數最小公倍數
a,b最小公倍數=a*b/最大公約數
最大公約數用輾轉相除法
指針的基本概念
1.每個變量都被存放在某個內存地址(以字節為單位)開始的若干個字節中。若干個字節(根據類型確定字節)
2.指針,也稱作“指針變量“,大小為4個字節(或8個字節)的變量,其內容代表一個內存地址。
3.通過指針能夠對任意地址的內存區域進行讀寫。
4.將內存比作房間,則指針內存儲的是房間號。
指針的定義
類型名*指針變量名
int *p; //p是一個指針變量,變量p類型是int *
char * q; //q是一個指針變量,變量q的類型是char *
double *r; //r是一個指針變量,變量r的類型是 double *
void *s; //s是一個指針變量,變量s無類型。
指針的內容
int * w=(int *) 40000;
w的內容,w是指向的地址40000。*w的內容,*w是w地址40000起始的若干字節(sizeof(int))的所儲存的內容。
通過指針訪問指向的內存空間
int*p=int *40000;//指向向地址40000;
*p =123; 將123存入p所指向的地址后的若干字節(sizeof(int))的內存空間。
int n=*p,將p所指向的地址后的若干字節(sizeof(int))的內存空間賦值給 n;
補充
1. 上述*和&的區別
(1)*p是指指針p指向地址的那個變量,例如int a=5;int p=a;那么p的值是a的地址,也就是指針p指向a,p則等于a的值,即p=5。
(2)&,則是引用,比如說有定義int a=5;再定義int b=&a;那么這里的b則引用a的值,即b=5,而再給b賦值:b=10,a的值也會變為10。
(3)函數定義里的參數和&的區別:
(1) 調用 int a1(x)后x的值還是等于0;int a其中a為形參,x為實參,函數調用的過程實際上是一種傳參過程。將x的值賦給a后,函數操作與x無關,即a=x;a=5;
(2)調用 int a2(x)后,x的值等于5;因為這里a引用了x的值。
(3)調用 int a3(x)后,x的值也得等于5;此時不再是傳參,而是傳址,相當于w=a,w與a所指向地址相同。改變*a所指內容就改變 * w所指向的內容
指針的賦值(用法)
指針的用法
char a=‘A’;
char * p=&a;
char *m;
m=p;
int *t;
t=(int) p;類型不匹配,編譯出錯,但可以使用強制類型轉換。
cout<<*p;
可以使用char * a=6161(地址)但容易運行出現問題,因為地址不明確,不知道是本程序的內存地址,還是系統內存地址,或者某進程的地址。一般使用方式如上述。
指針的運算
地址p1<地址p2,->p1< p2 值為真。
地址p1=地址p2,->p1== p2 值為真
地址p1>地址p2,->p1 > p2 值為真
兩個T * 類型的指針p1和p2
p1 – p2 = ( 地址p1 – 地址p2 ) / sizeof(T)
例:int * p1, * p2;
若p1 指向地址100,p2 指向地址60, 則
p1 – p2 = (1000 – 600)/sizeof(int) = (100 – 60)/4 = 10
3)指針變量加減一個整數的結果仍是指針
int p;
int n=a(a為某常數);
p+n:地址p+asieof(int)
則類型為char或其他時,n+p、n-p時, (n+p)、(n-p)時都應該明白其含義。
4)自增運算自減運算
int *p=n;
p++,++p;表達n=n+sizeof(int)
$ ¥ $ ¥指針運算可以使用下標運算符[ ]
int *p;
int n;
p[n]等價于 *[p+n]這不就是數組嗎?
例題
訪問int型變量a前面一字節int a;char *p=(char*)&a;--p;*p='M';cout<<*p;空指針
地址0不能訪問。指向地址0的指針就是空指針
可以用“NULL”關鍵字對任何類型的指針進行賦值。NULL實際上
就是整數0,值為NULL的指針就是空指針:
int * pn = NULL; char * pc = NULL; int * p2 = 0;
指針可以作為條件表達式使用。如果指針的值為NULL,則相當于為
假,值不為NULL,就相當于為真
if§=== if(p!=NULL) <----------> ensp if(!p)=== if( p==NULL )
常量表達式和constexpr與const
常量表達式概念:值不會改變并且在編譯過程中就能計算出結果的表達式。
constexpr必須用常量表達式初始化,也就是說必須在編譯過程就能計算出結果(若要用函數作為constexpr的初始值那么該函數應該是constexpr類型的函數)。
constexpr函數必須滿足下述限制:
函數返回值不能是void類型 函數體不能聲明變量或定義新的類型
函數體只能包含聲明、null語句或者一條return語句
在形參實參結合后,return語句中的表達式為常量表達式
const 不要求在編譯過程中就能計算出結果 (強調運行時不可改變) 大多數情況下并沒有區別。
const限定指針和引用。
指向const對象的指針 const type 指針
指向非const對象地const指針(常指針 ) type const 指針
int num =10;int * const poi =&num;// type const 指針 指針的值初始化后不能改變指向固定的單元(只能指一次)*poi=99;//const限定的是poi的值;可以對指向內容修改,但不可以對指針指向對象修改。int member=10;poi=&member;//錯誤指向const對象的const指針
/*const type const 指針(第一個const限定int表示指針指向的單元是常量, 第二個const限定‘指針’表示指針的值也是常量,因此該指針所在的內存值不允許改變它所指向內存的值也不能改變)*/ int demo=10; const int *const pi=&demo;對象及內容都不能改變const限定引用,與const指針相似
const int a=1; int 7b=a;// const type &引用名(不能用非const引用指向const對象) const int& b=a;//right b=10;//錯誤,const引用不能用來修改他所綁定的對象。 a=10;//const引用僅對自己可參與的操作進行了限定對所指向的對象本身是不是常量未作限定。因為指向的對象也可能不是const,所以允許通過其他途徑改變它的值。 const int &c=a*10;//可以用任意表達式初始化const引用,只要表達式的結果能轉換成引用的類型即可。auto和decltype
由auto聲明變量的類型由編譯器去自動分析表達式的類型,推斷出變量的實際類型(很好用)
auto x=5 auto x=1,c=3.14;//一個int 一個double錯!當auto后定義多個變量時類型要一致 auto poi=Set.begin()//很好用,省了set<type>::iterator decltype 可以通過表達式推斷出定義的變量的類型但是不用該表達式初始化。int i = 4; decltype(i) a; //推導結果為int。a的類型為int。引用
左值與右值
區別 左值 右值
賦值表達式 出現在賦值號左邊 在賦值號右邊的
地址與名字 可以取地址的有名字 不能取地址的沒有名字
生成的表達式 返回左值引用的函數 賦值 下標 解引用和前綴自增自減運算符 返回非引用類型的函數 連同算術、關系、位運算、后綴自增自減運算符、字面值常量、要求轉換的表達式。
文件的輸入輸出
文件的讀寫
如果想以輸入方式打開,就用ifstream來定義;
如果想以輸出方式打開,就用ofstream來定義;
如果想以輸入/輸出方式來打開,就用fstream來定義
與容器一樣流不會降低自己空間,即使用了ss.clear()😭 清空操作如下 😦
ss.clear();//清空流 ss.str("");六.range -for for(int ele :{2,3,44,5,6,77}) {cout<<ele<<endl; } int arr []={1,2,3,4} for(int ele :arr) {cout<<ele<<endl; } vector<int > demo={1,2,3,4};//結合auto關鍵字可以方便地遍歷STL容器 for(auto ele:demo) {cout<<ele<<endl<<; }for(auto& ele:demo) 如果需要修改其中元素可以引用; {ele+=2; }切記!!!!! 不能在遍歷容器時,改變容器的Size,即增刪元素。寫在最后:
Name:風骨散人,目前是一名雙非在校大學生,預計考研,熱愛編程,熱愛技術,喜歡分享,知識無界,希望我的分享可以幫到你!名字的含義:我想有一天我能有能力隨心所欲不逾矩,不總是向生活低頭,有能力讓家人擁有富足的生活而不是為了生計而到處奔波。“世人慌慌張張,不過是圖碎銀幾兩。偏偏這碎銀幾兩,能解世間惆悵,可讓父母安康,可護幼子成長 …”
文章主要內容:
Python,C++,C語言,JAVA,C#等語言的教程
ACM題解、模板、算法等,主要是數據結構,數學和圖論
設計模式,數據庫,計算機網絡,操作系統,計算機組成原理
Python爬蟲、深度學習、機器學習
計算機系408考研的所有專業課內容
目前還在更新中,先關注不迷路。微信公眾號,cnblogs(博客園),CSDN同名“風骨散人”
如果有什么想看的,可以私信我,如果在能力范圍內,我會發布相應的博文!
感謝大家的閱讀!😘你的點贊、收藏、關注是對我最大的鼓勵!
總結
以上是生活随笔為你收集整理的『C++』我想学C++,C++太难了,那我想入门,给我10分钟我带你入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ChatGPT 通过谷歌 L3 工程师入
- 下一篇: 流浪地球 MOSS 雏形,“中国造”量子