【黑马程序员 C++教程从0到1入门编程】【笔记1】数据类型、运算符、程序流程结构、数组、函数、指针、结构体
黑馬程序員匠心之作|C++教程從0到1入門編程,學習編程不再難
文章目錄
- 1、C++初識
- 1.1 第一個c++程序
- 1.2 注釋
- 1.3 變量
- 1.4 常量
- 1.5 關鍵字
- 1.6 標識符命名規則
- 2 數據類型
- 2.1 整型
- 2.2 sizeof關鍵字
- 2.3 實型(浮點型)(科學計數法)(定義float數字后加個f)
- 2.4 字符型
- 2.5 轉義字符
- 2.6 字符串型
- 2.7 布爾類型 bool
- 2.8 數據的輸入(鍵盤輸入cin)
- 3 運算符
- 3.1 算術運算符
- 3.2 賦值運算符
- 3.3 比較運算符
- 3.4 邏輯運算符
- 4 程序流程結構
- 4.1 選擇結構
- 4.1.1 if語句
- 4.1.2 三目運算符(略)
- 4.1.3 switch語句(略)
- 4.2 循環結構(略)
- 4.2.1 while循環語句
- 4.2.2 do...while循環語句
- 4.2.3 for循環語句(略)
- 4.2.4 嵌套循環(略)
- 4.3 跳轉語句(略)
- 4.3.1 break語句
- 4.3.2 continue語句
- 4.3.3 goto語句
- 5 數組
- 5.1 概述
- 5.2 一維數組
- 5.2.1 一維數組定義方式
- 5.2.2 一維數組數組名
- 5.2.3 冒泡排序(略)
- 5.3 二維數組
- 5.3.1 二維數組定義方式
- 5.3.2 二維數組數組名
- 6 函數
- 6.1 概述
- 6.2 函數的定義
- 6.3 函數的調用
- 6.4 值傳遞
- **6.5 函數的常見樣式**
- 6.6 函數的聲明
- 6.7 函數的分文件編寫
- 7 指針
- 7.1 指針的基本概念
- 7.2 指針變量的定義和使用
- 7.3 指針所占內存空間
- 7.4 空指針和野指針
- 7.5 const修飾指針
- 7.6 指針和數組
- 7.7 指針和函數
- 7.8 指針、數組、函數(略)
- 8 結構體
- 8.1 結構體基本概念
- 8.2 結構體定義和使用
- 8.3 結構體數組
- 8.4 結構體指針
- 8.5 結構體嵌套結構體
- 8.6 結構體做函數參數 (傳結構體和傳結構體指針的比較)
- 8.7 結構體中 const使用場景
- 8.8 結構體案例(注意,數組名作為函數參數傳遞時,傳的是首元素地址)(設置隨機數種子srand、rand())
- 8.8.1 案例1
1、C++初識
1.1 第一個c++程序
#include <iostream> using namespace std;int main() {cout << "hello" << endl;system("pause");return 0; }結果:
hello1.2 注釋
單行注釋與多行注釋
1.3 變量
語法:數據類型 變量名 = 初始值;
注意:C++在創建變量時,必須給變量一個初始值,否則會報錯
1.4 常量
#define 宏常量: #define 常量名 常量值
通常在文件上方定義,表示一個常量
const修飾的變量 const 數據類型 常量名 = 常量值
通常在變量定義前加關鍵字const,修飾該變量為常量,不可修改
示例:
//1、宏常量 #define day 7int main() {cout << "一周里總共有 " << day << " 天" << endl;//day = 8; //報錯,宏常量不可以修改//2、const修飾變量const int month = 12;cout << "一年里總共有 " << month << " 個月份" << endl;//month = 24; //報錯,常量是不可以修改的system("pause");return 0; }1.5 關鍵字
提示:在給變量或者常量起名稱時候,不要用C++得關鍵字,否則會產生歧義。
| auto | double | inline | short | typeid |
| bool | dynamic_cast | int | signed | typename |
| break | else | long | sizeof | union |
| case | enum | mutable | static | unsigned |
| catch | explicit | namespace | static_cast | using |
| char | export | new | struct | virtual |
| class | extern | operator | switch | void |
| const | false | private | template | volatile |
| const_cast | float | protected | this | wchar_t |
| continue | for | public | throw | while |
| default | friend | register | true | |
| delete | goto | reinterpret_cast | try |
1.6 標識符命名規則
作用:C++規定給標識符(變量、常量)命名時,有一套自己的規則
- 標識符不能是關鍵字
- 標識符只能由字母、數字、下劃線組成
- 第一個字符必須為字母或下劃線
- 標識符中字母區分大小寫
建議:給標識符命名時,爭取做到見名知意的效果,方便自己和他人的閱讀
2 數據類型
C++規定在創建一個變量或者常量時,必須要指定出相應的數據類型,否則無法給變量分配內存
2.1 整型
作用:整型變量表示的是整數類型的數據
C++中能夠表示整型的類型有以下幾種方式,區別在于所占內存空間不同:
| short(短整型) | 2字節 | (-2^15 ~ 2^15-1) |
| int(整型) | 4字節 | (-2^31 ~ 2^31-1) |
| long(長整形) | Windows為4字節,Linux為4字節(32位),8字節(64位) | (-2^31 ~ 2^31-1) |
| long long(長長整形) | 8字節 | (-2^63 ~ 2^63-1) |
2.2 sizeof關鍵字
作用:利用sizeof關鍵字可以統計數據類型所占內存大小
語法: sizeof( 數據類型 / 變量)
示例:
#include <iostream> using namespace std;int main() {cout << "short 類型所占內存空間為: " << sizeof(short) << endl;cout << "int 類型所占內存空間為: " << sizeof(int) << endl;cout << "long 類型所占內存空間為: " << sizeof(long) << endl;cout << "long long 類型所占內存空間為: " << sizeof(long long) << endl;system("pause");return 0; }結果:
short 類型所占內存空間為: 2 int 類型所占內存空間為: 4 long 類型所占內存空間為: 4 long long 類型所占內存空間為: 82.3 實型(浮點型)(科學計數法)(定義float數字后加個f)
作用:用于表示小數
浮點型變量分為兩種:
兩者的區別在于表示的有效數字范圍不同。
| float | 4字節 | 7位有效數字 |
| double | 8字節 | 15~16位有效數字 |
示例:
#include <iostream> using namespace std;int main() {float f1 = 3.1456756743f;double d1 = 3.1454545555;cout << f1 << endl;cout << d1 << endl;cout << "float sizeof = " << sizeof(f1) << endl;cout << "double sizeof = " << sizeof(d1) << endl;//科學計數法float f2 = 3e2; // 3 * 10 ^ 2 cout << "f2 = " << f2 << endl;float f3 = 3e-2; // 3 * 0.1 ^ 2cout << "f3 = " << f3 << endl;system("pause");return 0; }運行結果:
3.14568 3.14545 float sizeof = 4 double sizeof = 8 f2 = 300 f3 = 0.03float數字后加個f的原因是減少一步轉換,因為不加的話,系統會識別成double型
VS默認最多輸出六位小數
2.4 字符型
作用:字符型變量用于顯示單個字符
語法:char ch = 'a';
注意1:在顯示字符型變量時,用單引號將字符括起來,不要用雙引號
注意2:單引號內只能有一個字符,不可以是字符串
- C和C++中字符型變量只占用1個字節。
- 字符型變量并不是把字符本身放到內存中存儲,而是將對應的ASCII編碼放入到存儲單元
示例:
#include <iostream> using namespace std;int main() {char ch = 'a';cout << ch << endl;cout << sizeof(char) << endl;//ch = "abcde"; //錯誤,不可以用雙引號//ch = 'abcde'; //錯誤,單引號內只能引用一個字符cout << (int)ch << endl; //查看字符a對應的ASCII碼ch = 97; //可以直接用ASCII給字符型變量賦值cout << ch << endl;system("pause");return 0; }運行結果:
a 1 97 a2.5 轉義字符
作用:用于表示一些不能顯示出來的ASCII字符
現階段我們常用的轉義字符有:\n \\ \t
| \a | 警報 | 007 |
| \b | 退格(BS) ,將當前位置移到前一列 | 008 |
| \f | 換頁(FF),將當前位置移到下頁開頭 | 012 |
| \n | 換行(LF) ,將當前位置移到下一行開頭 | 010 |
| \r | 回車(CR) ,將當前位置移到本行開頭 | 013 |
| \t | 水平制表(HT) (跳到下一個TAB位置) | 009 |
| \v | 垂直制表(VT) | 011 |
| \\ | 代表一個反斜線字符"" | 092 |
| ’ | 代表一個單引號(撇號)字符 | 039 |
| " | 代表一個雙引號字符 | 034 |
| ? | 代表一個問號 | 063 |
| \0 | 數字0 | 000 |
| \ddd | 8進制轉義字符,d范圍0~7 | 3位8進制 |
| \xhh | 16進制轉義字符,h范圍09,af,A~F | 3位16進制 |
示例:
#include <iostream> using namespace std;int main() {cout << "\\" << endl;cout << "\tHello" << endl;cout << "\n" << endl;system("pause");return 0; }結果:
\Hello2.6 字符串型
作用:用于表示一串字符
兩種風格
C風格字符串: char 變量名[] = "字符串值"
示例:
注意:C風格的字符串要用雙引號括起來
示例:
注意:C++風格字符串,需要加入頭文件==#include<string>==
2.7 布爾類型 bool
作用:布爾數據類型代表真或假的值
bool類型只有兩個值:
- true — 真(本質是1)
- false — 假(本質是0)
bool類型占1個字節大小
示例:
#include <iostream> using namespace std;int main() {bool flag = true;cout << flag << endl; // 1flag = false;cout << flag << endl; // 0cout << "size of bool = " << sizeof(bool) << endl; //1system("pause");return 0; }2.8 數據的輸入(鍵盤輸入cin)
作用:用于從鍵盤獲取數據
關鍵字:cin
語法: cin >> 變量
示例:
#include <iostream> using namespace std;int main() {//整型輸入int a = 0;cout << "請輸入整型變量:" << endl;cin >> a;cout << a << endl;//浮點型輸入double d = 0;cout << "請輸入浮點型變量:" << endl;cin >> d;cout << d << endl;//字符型輸入char ch = 0;cout << "請輸入字符型變量:" << endl;cin >> ch;cout << ch << endl;//字符串型輸入string str;cout << "請輸入字符串型變量:" << endl;cin >> str;cout << str << endl;//布爾類型輸入bool flag = true;cout << "請輸入布爾型變量:" << endl;cin >> flag;cout << flag << endl;system("pause");return EXIT_SUCCESS; }3 運算符
作用:用于執行代碼的運算
本章我們主要講解以下幾類運算符:
| 算術運算符 | 用于處理四則運算 |
| 賦值運算符 | 用于將表達式的值賦給變量 |
| 比較運算符 | 用于表達式的比較,并返回一個真值或假值 |
| 邏輯運算符 | 用于根據表達式的值返回真值或假值 |
3.1 算術運算符
作用:用于處理四則運算
算術運算符包括以下符號:
| + | 正號 | +3 | 3 |
| - | 負號 | -3 | -3 |
| + | 加 | 10 + 5 | 15 |
| - | 減 | 10 - 5 | 5 |
| * | 乘 | 10 * 5 | 50 |
| / | 除 | 10 / 5 | 2 |
| % | 取模(取余) | 10 % 3 | 1 |
| ++ | 前置遞增 | a=2; b=++a; | a=3; b=3; |
| ++ | 后置遞增 | a=2; b=a++; | a=3; b=2; |
| – | 前置遞減 | a=2; b=–a; | a=1; b=1; |
| – | 后置遞減 | a=2; b=a–; | a=1; b=2; |
示例1:
#include <iostream> using namespace std;//加減乘除 int main() {int a1 = 10;int b1 = 3;cout << a1 + b1 << endl; //13cout << a1 - b1 << endl; //7cout << a1 * b1 << endl; //30cout << a1 / b1 << endl; //3 兩個整數相除結果依然是整數int a2 = 10;int b2 = 20;cout << a2 / b2 << endl; //0int a3 = 10;int b3 = 0;//cout << a3 / b3 << endl; //報錯,除數不可以為0//兩個小數可以相除double d1 = 0.5; double d2 = 0.25;cout << d1 / d2 << endl; //2system("pause");return 0; }示例2:
#include <iostream> using namespace std;//取模 int main() {int a1 = 10;int b1 = 3;cout << 10 % 3 << endl; //1int a2 = 10;int b2 = 20;cout << a2 % b2 << endl; //10int a3 = 10;int b3 = 0;//cout << a3 % b3 << endl; //取模運算時,除數也不能為0//兩個小數不可以取模double d1 = 3.14;double d2 = 1.1;//cout << d1 % d2 << endl;system("pause");return 0; }示例3:
#include <iostream> using namespace std;//遞增 int main() {//后置遞增int a = 10;a++; //等價于a = a + 1cout << a << endl; // 11//前置遞增int b = 10;++b;cout << b << endl; // 11//區別//前置遞增先對變量進行++,再計算表達式int a2 = 10;int b2 = ++a2 * 10;cout << b2 << endl; //110//后置遞增先計算表達式,后對變量進行++int a3 = 10;int b3 = a3++ * 10;cout << b3 << endl; //100system("pause");return 0; }總結:前置遞增先對變量進行++,再計算表達式,后置遞增相反
3.2 賦值運算符
**作用:**用于將表達式的值賦給變量
賦值運算符包括以下幾個符號:
| = | 賦值 | a=2; b=3; | a=2; b=3; |
| += | 加等于 | a=0; a+=2; | a=2; |
| -= | 減等于 | a=5; a-=3; | a=2; |
| *= | 乘等于 | a=2; a*=2; | a=4; |
| /= | 除等于 | a=4; a/=2; | a=2; |
| %= | 模等于 | a=3; a%2; | a=1; |
示例:
#include <iostream> using namespace std;int main() {//賦值運算符// =int a = 10;a = 100;cout << "a = " << a << endl; //100// +=a = 10;a += 2; // a = a + 2;cout << "a = " << a << endl; //12// -=a = 10;a -= 2; // a = a - 2cout << "a = " << a << endl; //8// *=a = 10;a *= 2; // a = a * 2cout << "a = " << a << endl; //20// /=a = 10;a /= 2; // a = a / 2;cout << "a = " << a << endl; //5// %=a = 10;a %= 2; // a = a % 2;cout << "a = " << a << endl; //0system("pause");return 0; }3.3 比較運算符
作用:用于表達式的比較,并返回一個真值或假值
比較運算符有以下符號:
| == | 相等于 | 4 == 3 | 0 |
| != | 不等于 | 4 != 3 | 1 |
| < | 小于 | 4 < 3 | 0 |
| > | 大于 | 4 > 3 | 1 |
| <= | 小于等于 | 4 <= 3 | 0 |
| >= | 大于等于 | 4 >= 1 | 1 |
示例:
#include <iostream> using namespace std;int main() {int a = 10;int b = 20;cout << (a == b) << endl; // 0 cout << (a != b) << endl; // 1cout << (a > b) << endl; // 0cout << (a < b) << endl; // 1cout << (a >= b) << endl; // 0cout << (a <= b) << endl; // 1system("pause");return 0; }注意:C和C++ 語言的比較運算中, “真”用數字“1”來表示, “假”用數字“0”來表示。
3.4 邏輯運算符
**作用:**用于根據表達式的值返回真值或假值
邏輯運算符有以下符號:
| ! | 非 | !a | 如果a為假,則!a為真; 如果a為真,則!a為假。 |
| && | 與 | a && b | 如果a和b都為真,則結果為真,否則為假。 |
| || | 或 | a || b | 如果a和b有一個為真,則結果為真,二者都為假時,結果為假。 |
示例1:邏輯非
#include <iostream> using namespace std;//邏輯運算符 --- 非 int main() {int a = 10;cout << !a << endl; // 0cout << !!a << endl; // 1system("pause");return 0; }總結: 真變假,假變真(只要不是0就為真)
示例2:邏輯與
#include <iostream> using namespace std;//邏輯運算符 --- 與 int main() {int a = 10;int b = 10;cout << (a && b) << endl;// 1a = 10;b = 0;cout << (a && b) << endl;// 0 a = 0;b = 0;cout << (a && b) << endl;// 0system("pause");return 0; }總結:邏輯與運算符總結: 同真為真,其余為假
示例3:邏輯或
#include <iostream> using namespace std;//邏輯運算符 --- 或 int main() {int a = 10;int b = 10;cout << (a || b) << endl;// 1a = 10;b = 0;cout << (a || b) << endl;// 1 a = 0;b = 0;cout << (a || b) << endl;// 0system("pause");return 0; }4 程序流程結構
C/C++支持最基本的三種程序運行結構:順序結構、選擇結構、循環結構
- 順序結構:程序按順序執行,不發生跳轉
- 選擇結構:依據條件是否滿足,有選擇的執行相應功能
- 循環結構:依據條件是否滿足,循環多次執行某段代碼
4.1 選擇結構
4.1.1 if語句
作用:執行滿足條件的語句
if語句的三種形式
-
單行格式if語句
-
多行格式if語句
-
多條件的if語句
單行格式if語句:if(條件){ 條件滿足執行的語句 }
示例:
注意:if條件表達式后不要加分號
示例:
示例:
嵌套if語句:在if語句中,可以嵌套使用if語句,達到更精確的條件判斷
案例:略
4.1.2 三目運算符(略)
作用: 通過三目運算符實現簡單的判斷
語法:表達式1 ? 表達式2 :表達式3
解釋:
如果表達式1的值為真,執行表達式2,并返回表達式2的結果;
如果表達式1的值為假,執行表達式3,并返回表達式3的結果。
總結:和if語句比較,三目運算符優點是短小整潔,缺點是如果用嵌套,結構不清晰
4.1.3 switch語句(略)
作用:執行多條件分支語句
語法:
switch(表達式){case 結果1:執行語句;break;case 結果2:執行語句;break;...default:執行語句;break;}注意1:switch語句中表達式類型只能是整型或者字符型
注意2:case里如果沒有break,那么程序會一直向下執行
總結:與if語句比,對于多條件判斷時,switch的結構清晰,執行效率高,缺點是switch不可以判斷區間
4.2 循環結構(略)
4.2.1 while循環語句
**作用:**滿足循環條件,執行循環語句
語法:while(循環條件){ 循環語句 }
解釋:只要循環條件的結果為真,就執行循環語句
注意:在執行循環語句時候,程序必須提供跳出循環的出口,否則出現死循環
4.2.2 do…while循環語句
作用: 滿足循環條件,執行循環語句
語法: do{ 循環語句 } while(循環條件);
注意:與while的區別在于do…while會先執行一次循環語句,再判斷循環條件
總結:與while循環區別在于,do…while先執行一次循環語句,再判斷循環條件
4.2.3 for循環語句(略)
作用: 滿足循環條件,執行循環語句
語法:for(起始表達式;條件表達式;末尾循環體) { 循環語句; }
注意:for循環中的表達式,要用分號進行分隔
總結:while , do…while, for都是開發中常用的循環語句,for循環結構比較清晰,比較常用
4.2.4 嵌套循環(略)
作用: 在循環體中再嵌套一層循環,解決一些實際問題
例如我們想在屏幕中打印如下圖片,就需要利用嵌套循環
4.3 跳轉語句(略)
4.3.1 break語句
作用: 用于跳出選擇結構或者循環結構
break使用的時機:
- 出現在switch條件語句中,作用是終止case并跳出switch
- 出現在循環語句中,作用是跳出當前的循環語句
- 出現在嵌套循環中,跳出最近的內層循環語句
4.3.2 continue語句
**作用:**在循環語句中,跳過本次循環中余下尚未執行的語句,繼續執行下一次循環
注意:continue并沒有使整個循環終止,而break會跳出循環
4.3.3 goto語句
作用:可以無條件跳轉語句
語法: goto 標記;
解釋:如果標記的名稱存在,執行到goto語句時,會跳轉到標記的位置
注意:在程序中不建議使用goto語句,以免造成程序流程混亂
5 數組
5.1 概述
所謂數組,就是一個集合,里面存放了相同類型的數據元素
特點1:數組中的每個數據元素都是相同的數據類型
特點2:數組是由連續的內存位置組成的
5.2 一維數組
5.2.1 一維數組定義方式
一維數組定義的三種方式:
示例
#include <iostream> using namespace std;int main() {//定義方式1//數據類型 數組名[元素個數];int score[10];//利用下標賦值score[0] = 100;score[1] = 99;score[2] = 85;//利用下標輸出cout << score[0] << endl;cout << score[1] << endl;cout << score[2] << endl;//第二種定義方式//數據類型 數組名[元素個數] = {值1,值2 ,值3 ...};//如果{}內不足10個數據,剩余數據用0補全int score2[10] = { 100, 90,80,70,60,50,40,30,20,10 };//逐個輸出//cout << score2[0] << endl;//cout << score2[1] << endl;//一個一個輸出太麻煩,因此可以利用循環進行輸出for (int i = 0; i < 10; i++){cout << score2[i] << endl;}//定義方式3//數據類型 數組名[] = {值1,值2 ,值3 ...};int score3[] = { 100,90,80,70,60,50,40,30,20,10 };for (int i = 0; i < 10; i++){cout << score3[i] << endl;}system("pause");return 0; }總結1:數組名的命名規范與變量名命名規范一致,不要和變量重名
總結2:數組中下標是從0開始索引
5.2.2 一維數組數組名
一維數組名稱的用途:
示例:
#include <iostream> using namespace std;int main() {//數組名用途//1、可以獲取整個數組占用內存空間大小int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };cout << "整個數組所占內存空間為: " << sizeof(arr) << endl; //40cout << "每個元素所占內存空間為: " << sizeof(arr[0]) << endl; //4cout << "數組的元素個數為: " << sizeof(arr) / sizeof(arr[0]) << endl; //10//2、可以通過數組名獲取到數組首地址(打印的是地址的十進制表示)cout << "數組首地址為: " << (int)arr << endl; //13629676cout << "數組中第一個元素地址為: " << (int)&arr[0] << endl; //13629676cout << "數組中第二個元素地址為: " << (int)&arr[1] << endl; //13629680//arr = 100; 錯誤,數組名是常量,因此不可以賦值system("pause");return 0; }注意:數組名是常量,不可以賦值
總結1:直接打印數組名,可以查看數組所占內存的首地址
總結2:對數組名進行sizeof,可以獲取整個數組占內存空間的大小
5.2.3 冒泡排序(略)
作用: 最常用的排序算法,對數組內元素進行排序
5.3 二維數組
二維數組就是在一維數組上,多加一個維度。
5.3.1 二維數組定義方式
二維數組定義的四種方式:
建議:以上4種定義方式,利用第二種更加直觀,提高代碼的可讀性
示例:
#include <iostream> using namespace std;int main() {//方式1 //數組類型 數組名 [行數][列數]int arr[2][3];arr[0][0] = 1;arr[0][1] = 2;arr[0][2] = 3;arr[1][0] = 4;arr[1][1] = 5;arr[1][2] = 6;for (int i = 0; i < 2; i++){for (int j = 0; j < 3; j++){cout << arr[i][j] << " ";}cout << endl; //endl相當于換行符?\n,貌似是的}//方式2 //數據類型 數組名[行數][列數] = { {數據1,數據2 } ,{數據3,數據4 } };int arr2[2][3] ={{1,2,3},{4,5,6}};//方式3//數據類型 數組名[行數][列數] = { 數據1,數據2 ,數據3,數據4 };int arr3[2][3] = { 1,2,3,4,5,6 };//方式4 //數據類型 數組名[][列數] = { 數據1,數據2 ,數據3,數據4 };int arr4[][3] = { 1,2,3,4,5,6 };system("pause");return 0; }運行結果:
1 2 3 4 5 6總結:在定義二維數組時,如果初始化了數據,可以省略行數
5.3.2 二維數組數組名
- 查看二維數組所占內存空間
- 獲取二維數組首地址
總結1:二維數組名就是這個數組的首地址
總結2:對二維數組名進行sizeof時,可以獲取整個二維數組占用的內存空間大小
5.3.3 二維數組應用案例(略)
6 函數
6.1 概述
作用:將一段經常使用的代碼封裝起來,減少重復代碼
一個較大的程序,一般分為若干個程序塊,每個模塊實現特定的功能。
6.2 函數的定義
函數的定義一般主要有5個步驟:
1、返回值類型
2、函數名
3、參數列表
4、函數體語句
5、return 表達式
語法:
返回值類型 函數名 (參數列表) {函數體語句return表達式}- 返回值類型 :一個函數可以返回一個值。在函數定義中
- 函數名:給函數起個名稱
- 參數列表:使用該函數時,傳入的數據
- 函數體語句:花括號內的代碼,函數內需要執行的語句
- return表達式: 和返回值類型掛鉤,函數執行完后,返回相應的數據
示例:定義一個加法函數,實現兩個數相加
//函數定義 int add(int num1, int num2) {int sum = num1 + num2;return sum; }6.3 函數的調用
功能:使用定義好的函數
語法:函數名(參數)
示例:
#include <iostream> using namespace std;//函數定義 int add(int num1, int num2) //定義中的num1,num2稱為形式參數,簡稱形參 {int sum = num1 + num2;return sum; }int main() {int a = 10;int b = 10;//調用add函數int sum = add(a, b);//調用時的a,b稱為實際參數,簡稱實參cout << "sum = " << sum << endl; //20a = 100;b = 100;sum = add(a, b);cout << "sum = " << sum << endl; //200system("pause");return 0; }總結:函數定義里小括號內稱為形參,函數調用時傳入的參數稱為實參
6.4 值傳遞
- 所謂值傳遞,就是函數調用時實參將數值傳入給形參
- 值傳遞時,如果形參發生,并不會影響實參
示例:
#include <iostream> using namespace std;void swap(int num1, int num2) {cout << "交換前:" << endl;cout << "num1 = " << num1 << endl;cout << "num2 = " << num2 << endl;int temp = num1;num1 = num2;num2 = temp;cout << "交換后:" << endl;cout << "num1 = " << num1 << endl;cout << "num2 = " << num2 << endl;//return ; 當函數聲明時候,不需要返回值,可以不寫return }int main() {int a = 10;int b = 20;swap(a, b);cout << "mian中的 a = " << a << endl;cout << "mian中的 b = " << b << endl;system("pause");return 0; }運行結果:
交換前: num1 = 10 num2 = 20 交換后: num1 = 20 num2 = 10 mian中的 a = 10 mian中的 b = 20 請按任意鍵繼續. . .6.5 函數的常見樣式
常見的函數樣式有4種
示例:
#include <iostream> using namespace std;//函數常見樣式 //1、 無參無返 void test01() {//void a = 10; //無類型不可以創建變量,原因無法分配內存cout << "this is test01" << endl;//test01(); 函數調用 }//2、 有參無返 void test02(int a) {cout << "this is test02" << endl;cout << "a = " << a << endl; }//3、無參有返 int test03() {cout << "this is test03 " << endl;return 10; }//4、有參有返 int test04(int a, int b) {cout << "this is test04 " << endl;int sum = a + b;return sum; }6.6 函數的聲明
作用: 告訴編譯器函數名稱及如何調用函數。函數的實際主體可以單獨定義。
- 函數的聲明可以多次,但是函數的定義只能有一次
示例:
#include <iostream> using namespace std;//聲明可以多次,定義只能一次 //聲明 int max(int a, int b); int max(int a, int b); //定義 int max(int a, int b) {return a > b ? a : b; }int main() {int a = 100;int b = 200;cout << max(a, b) << endl; //200system("pause");return 0; }6.7 函數的分文件編寫
作用:讓代碼結構更加清晰
函數分文件編寫一般有4個步驟
示例:
//swap.h文件 #include<iostream> using namespace std;//實現兩個數字交換的函數聲明 void swap(int a, int b); //swap.cpp文件 #include "swap.h"void swap(int a, int b) {int temp = a;a = b;b = temp;cout << "a = " << a << endl;cout << "b = " << b << endl; } //main函數文件 #include "swap.h" int main() {int a = 100;int b = 200;swap(a, b);system("pause");return 0; }- 特點:cpp文件包含自己的頭文件
- 在頭文件里包含內置頭文件,以及聲明函數等
7 指針
7.1 指針的基本概念
指針的作用: 可以通過指針間接訪問內存
-
內存編號是從0開始記錄的,一般用十六進制數字表示
-
可以利用指針變量保存地址
7.2 指針變量的定義和使用
指針變量定義語法: 數據類型 * 變量名;
示例:
#include <iostream> using namespace std;int main() {//1、指針的定義int a = 10; //定義整型變量a//指針定義語法: 數據類型 * 變量名 ;int* p;//指針變量賦值p = &a; //指針指向變量a的地址cout << &a << endl; //打印數據a的地址 # 00B3FECCcout << p << endl; //打印指針變量p # 00B3FECC//2、指針的使用//通過*操作指針變量指向的內存cout << "*p = " << *p << endl; //*p = 10system("pause");return 0; }指針變量和普通變量的區別
- 普通變量存放的是數據,指針變量存放的是地址
- 指針變量可以通過" * "操作符,操作指針變量指向的內存空間,這個過程稱為解引用
總結1: 我們可以通過 & 符號 獲取變量的地址
總結2:利用指針可以記錄地址
總結3:對指針變量解引用,可以操作指針指向的內存
7.3 指針所占內存空間
提問:指針也是種數據類型,那么這種數據類型占用多少內存空間?
示例:
#include <iostream> using namespace std;int main() {int a = 10;int* p;p = &a; //指針指向數據a的地址cout << *p << endl; //* 解引用 10cout << sizeof(p) << endl; //4cout << sizeof(char*) << endl; //4cout << sizeof(float*) << endl; //4cout << sizeof(double*) << endl; //4system("pause");return 0; }總結:所有指針類型在32位操作系統下是4個字節(在64位操作系統下為8個字節)
7.4 空指針和野指針
空指針:指針變量指向內存中編號為0的空間
用途:初始化指針變量
注意:空指針指向的內存是不可以訪問的
示例1:空指針
#include <iostream> using namespace std;int main() {//指針變量p指向內存地址編號為0的空間int* p = NULL;//訪問空指針報錯 //內存編號0 ~255為系統占用內存,不允許用戶訪問cout << *p << endl; //報錯system("pause");return 0; }野指針:指針變量指向非法的內存空間
示例2:野指針
#include <iostream> using namespace std;int main() {//指針變量p指向內存地址編號為0x1100的空間int* p = (int*)0x1100;//訪問野指針報錯 cout << *p << endl;system("pause");return 0; }總結:空指針和野指針都不是我們申請的空間,因此不要訪問。
7.5 const修飾指針
const修飾指針有三種情況
示例:
#include <iostream> using namespace std;int main() {int a = 10;int b = 10;//const修飾的是指針,指針指向可以改,指針指向的值不可以更改const int* p1 = &a;p1 = &b; //正確//*p1 = 100; 報錯//const修飾的是常量,指針指向不可以改,指針指向的值可以更改int* const p2 = &a;//p2 = &b; //錯誤*p2 = 100; //正確//const既修飾指針又修飾常量const int* const p3 = &a;//p3 = &b; //錯誤//*p3 = 100; //錯誤system("pause");return 0; }技巧:看const右側緊跟著的是指針還是常量, 是指針就是常量指針,是常量就是指針常量
7.6 指針和數組
**作用:**利用指針訪問數組中元素
示例:
#include <iostream> using namespace std;int main() {int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr; //指向數組的指針cout << "第一個元素: " << arr[0] << endl;cout << "指針訪問第一個元素: " << *p << endl;for (int i = 0; i < 10; i++){//利用指針遍歷數組cout << *p << endl;p++;}system("pause");return 0; }結果:
第一個元素: 1 指針訪問第一個元素: 1 1 2 3 4 5 6 7 8 9 107.7 指針和函數
**作用:**利用指針作函數參數,可以修改實參的值
示例:
#include <iostream> using namespace std;//值傳遞 void swap1(int a, int b) {int temp = a;a = b;b = temp; } //地址傳遞 void swap2(int* p1, int* p2) {int temp = *p1;*p1 = *p2;*p2 = temp; }int main() {int a = 10;int b = 20;swap1(a, b); // 值傳遞不會改變實參cout << "a = " << a << endl; //10cout << "b = " << b << endl; //20swap2(&a, &b); //地址傳遞會改變實參cout << "a = " << a << endl; //20cout << "b = " << b << endl; //10system("pause");return 0; }總結:如果不想修改實參,就用值傳遞,如果想修改實參,就用地址傳遞
7.8 指針、數組、函數(略)
**案例描述:**封裝一個函數,利用冒泡排序,實現對整型數組的升序排序
例如數組:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
總結:當數組名傳入到函數作為參數時,被退化為指向首元素的指針
8 結構體
8.1 結構體基本概念
結構體屬于用戶自定義的數據類型,允許用戶存儲不同的數據類型
8.2 結構體定義和使用
語法:struct 結構體名 { 結構體成員列表 };
通過結構體創建變量的方式有三種:
- struct 結構體名 變量名
- struct 結構體名 變量名 = { 成員1值 , 成員2值…}
- 定義結構體時順便創建變量
示例:
#include <iostream> using namespace std;//結構體定義 struct student {//成員列表string name; //姓名int age; //年齡int score; //分數 }stu3; //結構體變量創建方式3 int main() {//結構體變量創建方式1struct student stu1; //struct 關鍵字可以省略stu1.name = "張三";stu1.age = 18;stu1.score = 100;cout << "姓名:" << stu1.name << " 年齡:" << stu1.age << " 分數:" << stu1.score << endl;//結構體變量創建方式2struct student stu2 = { "李四",19,60 };cout << "姓名:" << stu2.name << " 年齡:" << stu2.age << " 分數:" << stu2.score << endl;stu3.name = "王五";stu3.age = 18;stu3.score = 80;cout << "姓名:" << stu3.name << " 年齡:" << stu3.age << " 分數:" << stu3.score << endl;system("pause");return 0; }運行結果:
姓名:張三 年齡:18 分數:100 姓名:李四 年齡:19 分數:60 姓名:王五 年齡:18 分數:80總結1:定義結構體時的關鍵字是struct,不可省略
總結2:創建結構體變量時,關鍵字struct可以省略
總結3:結構體變量利用操作符 ‘’.’’ 訪問成員
8.3 結構體數組
作用:將自定義的結構體放入到數組中方便維護
語法:struct 結構體名 數組名[元素個數] = { {} , {} , ... {} }
示例:
#include <iostream> using namespace std;//結構體定義 struct student {//成員列表string name; //姓名int age; //年齡int score; //分數 };int main() {//結構體數組struct student arr[3] ={{"張三",18,80 },{"李四",19,60 },{"王五",20,70 }};for (int i = 0; i < 3; i++){cout << "姓名:" << arr[i].name << " 年齡:" << arr[i].age << " 分數:" << arr[i].score << endl;}system("pause");return 0; }運行結果:
姓名:張三 年齡:18 分數:80 姓名:李四 年齡:19 分數:60 姓名:王五 年齡:20 分數:708.4 結構體指針
**作用:**通過指針訪問結構體中的成員
- 利用操作符 ->可以通過結構體指針訪問結構體屬性
示例:
#include <iostream> using namespace std;//結構體定義 struct student {//成員列表string name; //姓名int age; //年齡int score; //分數 };int main() {struct student stu = { "張三",18,100, };struct student* p = &stu;p->score = 80; //指針通過 -> 操作符可以訪問成員cout << "姓名:" << p->name << " 年齡:" << p->age << " 分數:" << p->score << endl;system("pause");return 0; }運行結果:
姓名:張三 年齡:18 分數:80總結:結構體指針可以通過 -> 操作符 來訪問結構體中的成員
8.5 結構體嵌套結構體
作用: 結構體中的成員可以是另一個結構體
例如:每個老師輔導一個學員,一個老師的結構體中,記錄一個學生的結構體
示例:
#include <iostream> using namespace std;//學生結構體定義 struct student {//成員列表string name; //姓名int age; //年齡int score; //分數 };//教師結構體定義 struct teacher {//成員列表int id; //職工編號string name; //教師姓名int age; //教師年齡struct student stu; //子結構體 學生 };int main() {struct teacher t1;t1.id = 10000;t1.name = "老王";t1.age = 40;t1.stu.name = "張三";t1.stu.age = 18;t1.stu.score = 100;cout << "教師 職工編號: " << t1.id << " 姓名: " << t1.name << " 年齡: " << t1.age << endl;cout << "輔導學員 姓名: " << t1.stu.name << " 年齡:" << t1.stu.age << " 考試分數: " << t1.stu.score << endl;system("pause");return 0; } 教師 職工編號: 10000 姓名: 老王 年齡: 40 輔導學員 姓名: 張三 年齡:18 考試分數: 100**總結:**在結構體中可以定義另一個結構體作為成員,用來解決實際問題
8.6 結構體做函數參數 (傳結構體和傳結構體指針的比較)
作用:將結構體作為參數向函數中傳遞
傳遞方式有兩種:
- 值傳遞
- 地址傳遞
示例:
#include <iostream> using namespace std;//學生結構體定義 struct student {//成員列表string name; //姓名int age; //年齡int score; //分數 };//值傳遞 void printStudent(student stu) {stu.age = 28;cout << "子函數中 姓名:" << stu.name << " 年齡: " << stu.age << " 分數:" << stu.score << endl; }//地址傳遞 void printStudent2(student* stu) {stu->age = 28;cout << "子函數中 姓名:" << stu->name << " 年齡: " << stu->age << " 分數:" << stu->score << endl; }int main() {student stu = { "張三",18,100 };//值傳遞printStudent(stu);cout << "主函數中 姓名:" << stu.name << " 年齡: " << stu.age << " 分數:" << stu.score << endl;cout << endl;//地址傳遞printStudent2(&stu);cout << "主函數中 姓名:" << stu.name << " 年齡: " << stu.age << " 分數:" << stu.score << endl;system("pause");return 0; } 子函數中 姓名:張三 年齡: 28 分數:100 主函數中 姓名:張三 年齡: 18 分數:100子函數中 姓名:張三 年齡: 28 分數:100 主函數中 姓名:張三 年齡: 28 分數:100總結:如果不想修改主函數中的數據,用值傳遞,反之用地址傳遞
8.7 結構體中 const使用場景
作用:用const來防止誤操作
示例:
#include <iostream> using namespace std;//學生結構體定義 struct student {//成員列表string name; //姓名int age; //年齡int score; //分數 };//const使用場景 void printStudent(const student* stu) //加const防止函數體中的誤操作 {//stu->age = 100; //操作失敗,因為加了const修飾cout << "姓名:" << stu->name << " 年齡:" << stu->age << " 分數:" << stu->score << endl;}int main() {student stu = { "張三",18,100 };printStudent(&stu);system("pause");return 0; }8.8 結構體案例(注意,數組名作為函數參數傳遞時,傳的是首元素地址)(設置隨機數種子srand、rand())
8.8.1 案例1
案例描述:
學校正在做畢設項目,每名老師帶領5個學生,總共有3名老師,需求如下
設計學生和老師的結構體,其中在老師的結構體中,有老師姓名和一個存放5名學生的數組作為成員
學生的成員有姓名、考試分數,創建數組存放3名老師,通過函數給每個老師及所帶的學生賦值
最終打印出老師數據以及老師所帶的學生數據。
示例:
#include <iostream> using namespace std;struct Student {string name;int score; }; struct Teacher {string name;Student sArray[5]; };void allocateSpace(Teacher tArray[], int len) {string tName = "教師";string sName = "學生";string nameSeed = "ABCDE";for (int i = 0; i < len; i++){tArray[i].name = tName + nameSeed[i];for (int j = 0; j < 5; j++){tArray[i].sArray[j].name = sName + nameSeed[j];tArray[i].sArray[j].score = rand() % 61 + 40;}} }void printTeachers(Teacher tArray[], int len) {for (int i = 0; i < len; i++){cout << tArray[i].name << endl;for (int j = 0; j < 5; j++){cout << "\t姓名:" << tArray[i].sArray[j].name << " 分數:" << tArray[i].sArray[j].score << endl;}} }int main() {srand((unsigned int)time(NULL)); //隨機數種子 頭文件 #include <ctime>Teacher tArray[3]; //老師數組int len = sizeof(tArray) / sizeof(Teacher);allocateSpace(tArray, len); //創建數據printTeachers(tArray, len); //打印數據system("pause");return 0; }運行結果:
教師A姓名:學生A 分數:75姓名:學生B 分數:58姓名:學生C 分數:79姓名:學生D 分數:44姓名:學生E 分數:56 教師B姓名:學生A 分數:46姓名:學生B 分數:42姓名:學生C 分數:75姓名:學生D 分數:97姓名:學生E 分數:40 教師C姓名:學生A 分數:62姓名:學生B 分數:63姓名:學生C 分數:42姓名:學生D 分數:92姓名:學生E 分數:99關于srand((unsigned int)time(NULL)),可見:srand((unsigned int)time(NULL))引發的思考
總結
以上是生活随笔為你收集整理的【黑马程序员 C++教程从0到1入门编程】【笔记1】数据类型、运算符、程序流程结构、数组、函数、指针、结构体的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++睡眠延时函数 Sleep() us
- 下一篇: 【黑马程序员 C++教程从0到1入门编程