C++初識
第一個C++程式
編寫一個C++程式總共分為4個步驟
- 建立專案
- 建立檔案
- 編寫程式碼
- 執行程式
建立專案
Visual Studio是我們用來編寫C++程式的工具
建立檔案
編寫程式碼
#include <iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
/*
main函式是一個程式的入口
每個程式都必須有這麼一個函式
有且僅有一個
*/
system("pause");
return 0;
}
執行程式
註釋
作用:在程式碼中加一些說明和解釋,方便自己或其他程式設計師閱讀程式碼
兩種格式
-
單行註釋://說明資訊
- 通常放在一行程式碼上方,或者一條語句的末尾,對該程式碼說明
-
多行註釋:/*說明資訊*/
- 通常放在一段程式碼的上方,對該段程式碼做整體說明
編譯器在執行程式碼時,會忽略註釋的內容
變數
作用:給一段指定的記憶體空間起名,方便操作這段記憶體
語法:資料型別 變數名 = 初始值;
示例
#include <iostream>
using namespace std;
int main()
{
//變數的建立語法:資料型別 變數名 = 變數初始值
int a = 10;
system("pause");
return 0;
}
常量
作用:用於記錄程式中不可更改的資料
C++定義常量兩種方式
#define
巨集常量:#define
常量名 常量值- 通常在檔案上方定義,表示一個常量
cons
修飾的變數:const
資料型別 變數名 常量值- 通常在變數定義前加關鍵字
const
,修飾改變數為常量,不可更改
- 通常在變數定義前加關鍵字
示例
#include <iostream>
using namespace std;
// 巨集常量
#define day 7
int main() {
cout << "一週總共有:" << day << "天" << endl;
// const修飾變數
const int year = 100;
return 0;
}
關鍵字
作用:關鍵字是C++中預先保留的單詞(識別符號)
- 在定義變數或者常量的時候,不要使用關鍵字
識別符號命名規則
作用:C++規定給識別符號(變數、常量)命名時,有一套自己的規則
-
識別符號不能是關鍵字
-
識別符號只能由字母、數字、下劃線組成
-
第一個字元必須為字母或者下劃線
-
識別符號中字母區分大小寫
建議:給識別符號命名時,爭取見名知意的效果
資料型別
C++規定在建立一個變數或者常量時,必須要指定出相應的資料型別,否則無法給變數分配記憶體
整型
作用:整型變數能夠表示的是整數型別的資料
C++中能夠表示整型的型別有以下幾種方式,區別在於所佔記憶體不同
資料型別 | 佔用空間 | 取值範圍 |
---|---|---|
short(短整型) | 2位元組 | -215~215-1 |
int(整型) | 4位元組 | -231~231-1 |
long(長整型) | win為4位元組、Linux32位為4位元組/64位為8位元組 | -231~231-1 |
long long(長長整型) | 8位元組 | -263~263-1 |
sizeof關鍵字
作用:利用sizeof
關鍵字可以統計資料型別所佔記憶體大小
語法:sizeof
(資料型別/變數)
示例
#include <iostream>
using namespace std;
int main() {
int a = 5;
cout << sizeof(a) << endl;
cout << sizeof(int) << endl;
const int year = 100;
cout << sizeof(year) << endl;
return 0;
}
實型(浮點型)
作用:用於表示小數
浮點型分為兩種:
- 單精度
float
- 雙精度
double
兩者的區分在於表示的有效數字範圍不同
資料型別 | 佔用空間 | 有效數字範圍 |
---|---|---|
float | 4bit | 7為有效數字 |
double | 8bit | 15~16位有效數字 |
#include <iostream>
using namespace std;
int main() {
// float
float a = 5.6;
cout << a << endl;
// double
double b = 5.6;
cout << b << endl;
//科學計數法表示
float d = 3e2; //代表 3 * 10 ^ 2
cout << d << endl;
return 0;
}
字元型
作用:字元型變數用於顯示單個字元
語法:char c = "a";
在顯示字元型變數時,用單引號鍵字元括起來,不要用雙引號
單引號內只能有一個字元,不可以是字串
- C++和C中字元型變數只佔用1個位元組
- 字元型變數並不是把字元本身放到記憶體中儲存,而是將對應的ASCII編碼放到儲存單元
#include <iostream>
using namespace std;
int main() {
// 字元型
char d = 'D';
cout << d << endl;
cout << (int)d << endl; // 字元型對應ASCII編碼
/*
char d = "D"; 建立字元型變數時候,要用單引號
char d = 'hello'; 建立字元型變數時候,單引號內只能有一個數值
*/
system("pause");
return 0;
}
轉義字元
作用:用於表示一些不能顯示出來的ASCII字元
常用的轉義字元有://、/t、/n
#include <iostream>
using namespace std;
int main() {
// 換行符 \n
cout << "Hello World \n";
cout <<"Hello World" << endl;
// 反斜杆 \\
cout << "\\" << endl;
// 水平製表符 \t 可以整齊輸出資料
cout << "Hello \t World";
system("pause");
return 0;
}
字串型
作用:用於表示一串字元
兩種風格
-
C風格字串:
char 變數名[] = "字串值"
#include <iostream> using namespace std; int main() { char a[] = "hello world"; // 雙引號 cout << a <<endl; cout << sizeof(a) << endl; // 12 system("pause"); return 0; }
-
C++風格字串:
string 變數名 = "字串值"
#include <iostream> #include <string> // 用C++風格字串的時候,要包含這個標頭檔案 using namespace std; int main() { // 包含一個標頭檔案 string a = "hello world"; cout << a <<endl; cout << sizeof(a) << endl; // 40 system("pause"); return 0; }
布林資料型別 bool
作用:布林資料型別代表真或假的值
bool型別只有兩個值
- true:真(本質是1)
- false:假(本質是0)
bool型別佔一個位元組大小
#include <iostream>
#include <string> // 用C++風格字串的時候,要包含這個標頭檔案
using namespace std;
int main() {
// 建立bool資料型別
bool flag = true; // true代表真
cout << flag << endl; // 本質上,1代表真的值,0代表假的值
// 檢視bool型別佔用的記憶體空間
cout << flag << endl;
system("pause");
return 0;
}
資料的輸入
作用:用於從鍵盤獲取資料
語法:cin >> 變數
#include <iostream>
#include <string> // 用C++風格字串的時候,要包含這個標頭檔案
using namespace std;
int main() {
// 整型
int a = 0;
cout << "請輸入一個整數:";
cin >> a;
cout << "整型變數a = " << a << endl;
// 字串型
string a = "hello";
cout << "請輸入一個字串數:";
cin >> a;
cout << "字串型變數a = " << a << endl;
// bool型
bool a = false; // 非空即為真
cout << "請輸入一個bool數:";
cin >> a;
cout << "bool型變數a = " << a << endl;
// 字元型
char a = '0';
cout << "請輸入一個字元:";
cin >> a;
cout << "字元型變數a = " << a << endl;
// 浮點型
float a = 3.14f;
cout << "請輸入一個浮點數:";
cin >> a;
cout << "浮點型變數a = " << a << endl;
system("pause");
return 0;
}
運算子
作用:用於執行程式碼的運算
算術運算子
作用:用於處理四則運算
"+" 加, "-" 減, "/" 除, "*" 乘, "%" 取餘, "++" 遞增, "--"遞減
#include <iostream>
#include <string> // 用C++風格字串的時候,要包含這個標頭檔案
using namespace std;
int main() {
int a = 10;
int b = 3;
// +
cout << a+b << endl;
//-
cout << a - b << endl;
// / 兩個整數相除 結果為整數,將小數去除
cout << a / b << endl;
// *
cout << a * b << endl;
// % 兩個小數不可進行取餘運算
cout << a % b << endl;
system("pause");
return 0;
}
++ 和 --
#include <iostream>
#include <string> // 用C++風格字串的時候,要包含這個標頭檔案
using namespace std;
int main() {
// ++ 遞增
int a = 10;
++a; // 讓變數進行加一的結果,前置遞增
a++; // 後置遞增
// 前置遞增 先進行變數+1,後進行表示式的運算
int b = 10;
int c = ++b * 10;
cout << "前置b=" << b << endl;
cout << "前置c=" << c << endl;
// 後置遞增 先進行表示式的運算,後讓變數+1
int b1 = 10;
int c1 = b1++ * 10;
cout << "後置b=" << b1 << endl;
cout << "後置c=" << c1 << endl;
system("pause");
return 0;
}
賦值運算子
作用:用於將表示式的值賦給變數
"=" 等於, "+=" 加等於 , "-=" 減等於 , "/=" 除等於 , "%=" 餘等於 , "*=" 乘等於
#include <iostream>
#include <string> // 用C++風格字串的時候,要包含這個標頭檔案
using namespace std;
int main() {
int a = 10;
int b = 20;
// +=
a += b; // 相當於:a = a + b
cout << a << endl;
// -=
a -= b; // 相當於:a = a - b
cout << a << endl;
// /=
a /= b; // 相當於:a = a / b
cout << a << endl;
// *=
a *= b; // 相當於a = a * b
cout << a << endl;
// =
a = b - a;
cout << a << endl;
}
比較運算子
"=="等於 , "<=" 小於等於, ">=" 大於等於 , "!=" 不等於 , "<" 小於 , ">" 大於
返回bool型別
#include <iostream>
#include <string> // 用C++風格字串的時候,要包含這個標頭檔案
using namespace std;
int main() {
int a = 10;
int b = 20;
// >=
cout << (a >= b) << endl;
// <=
cout << (a <= b) << endl;
// ==
cout << (a == b) << endl;
// !=
cout << (a != b) << endl;
// <
cout << (a < b) << endl;
// >
cout << (a > b) << endl;
}
由於運算的優先順序,要用括號隔開
邏輯運算子
作用:用於根據表示式的值返回真值或假值
"!" 非 , "&&" 與 , "||" 或
#include <iostream>
#include <string> // 用C++風格字串的時候,要包含這個標頭檔案
using namespace std;
int main() {
// 邏輯運算子
// ! 真變假、假變真
bool a = true;
cout << !a<< endl;
// && 兩個都為真,則為真;同真則真,其餘為假
int a1 = 10;
int b = 0;
cout << (a1 && b) << endl;
// || 只要有一個為真,則為真;同假則假,其餘為真
cout << (a1 || b) << endl;
// 綜合應用
cout << (a1 || !( a1 && ! a ) );
}
程式流程結構
C/C++支援最基本的三種程式執行結構:順序結構、選擇結構、迴圈結構
- 順序結構:程式按順序執行,不發生跳轉
- 選擇結構:依據條件是否滿足,有選擇的執行相應功能
- 迴圈結構:依據條件是否滿足,迴圈多次執行某段程式碼
選擇結構
if語句
作用:執行滿足條件的語句
if語句的三種形式
- 單行格式if語句
- 多行格式if語句
- 多條件的if語句
單行格式
#include <iostream>
using namespace std;
int main() {
// 選擇結構 單行if語句
// 使用者輸入一個數字
int num = 1;
cout << "請輸入一個數字:";
cin >> num;
// 判斷數字是否大於100,是則輸出原數
if (num >= 100){ // 注意if語句後面不要加分號,否則,if將不會進行判斷
cout << num;
}
}
多行if語句
#include <iostream>
using namespace std;
int main() {
// 選擇結構 單行if語句
// 使用者輸入一個數字
int num = 1;
cout << "請輸入一個數字:";
cin >> num;
// 判斷數字是否大於100,是則輸出原數;否則,輸出0
if (num >= 100) { // 注意if語句後面不要加分號,否則,if將不會進行判斷
cout << num << endl;
}
else {
cout << "0" << endl;
}
}
多條件if語句
#include <iostream>
using namespace std;
int main() {
// 選擇結構 單行if語句
// 使用者輸入一個數字
int num = 1;
cout << "請輸入一個數字:";
cin >> num;
// 判斷數字是否大於600,是則輸出原數;數字是否小於600,大於0,是則輸出100;否則,輸出0
if (num >= 600) { // 注意if語句後面不要加分號,否則,if將不會進行判斷
cout << num << endl;
}
else if (num >= 100) {
cout << "100" << endl;
}
else {
cout << "0" << endl;
}
}
if ( 條件1 ) { 條件1滿足執行語句} else if ( 條件2 ) { 條件2滿足,同時條件1不滿足,執行的語句 }··· else { 都不滿足執行的語句 }
巢狀if語句
在if語句中,可以巢狀使用if語句,達到更加精確的條件判斷
案例:輸入3個數字,判斷出最大的數字
#include <iostream>
using namespace std;
int main() {
int num = 1;
int num1 = 1;
int num2 = 1;
cout << "請輸入三個數字:";
cin >> num;
cin >> num1;
cin >> num2;
if ( num > num1 ) { // 判斷 num 和 num1
if ( num > num2 ) { // 判斷 num 和 num2
cout << num << "最大" << endl;
}
else {
cout << num2 << "最大" << endl;
}
}
else {
if (num1 > num2) {
cout << num1 << "最大" << endl;
}
else {
cout << num2 << "最大" << endl;
}
cout << "判斷完畢" << endl;
}
}
三目運算子
作用:通過三目運算實現簡單的判斷
語法:表示式1 ? 表示式2 : 表示式3
#include <iostream>
using namespace std;
int main() {
// 三目運算
// 將 a 和 b 做比較,將大的值賦值給c
int a = 10;
int b = 20;
int c = 0;
c = a > b ? a : b; // 如果 a 比 b 大,則將a賦值給c
/*
if ( a > b ) {
c = a;
}
else {
c = b
}
*/
}
在C++中,三目運算子返回的是變數,可以繼續賦值
switch語句
作用:執行多條件分支語句
語法:
switch ( 表示式 ) {
case 結果1: 執行語句; break; // switch裡面不一定每個case都要對應break,break的作用的向外跳出一層
······
default: 執行語句; break; // 不一定需要default判斷
}
示例
#include <iostream>
using namespace std;
int main() {
// switch 語句
// 電影打分
int score = 0;
cout << "請輸入分數:";
cin >> score;
cout << "您打的分數為:" << score << endl;
switch (score) {
case 10:
cout << "是經典電影" << endl;
break; // 退出當前分支,如果沒有break,則會繼續向下執行
default: // 當所有條件不滿足時,執行該語句
cout << "普通" << endl;
}
}
缺點:判斷的時候,只能是整型或者字元型,不可以是一個區間
優點:結構清晰,執行效率高
注意
- switch語句中表示式型別只能是整型或者字元型
- case裡如果沒有break,那麼程式會一直向下執行
迴圈結構
while迴圈語句
作用:滿足迴圈條件,執行迴圈語句
語法:while ( 迴圈條件 ) { 迴圈語句 }
解釋:只要迴圈條件的結果為真,就執行迴圈語句
#include <iostream>
using namespace std;
int main() {
int nu = 0;
// 在螢幕中列印0到9的數字
while ( nu < 10 )
{
cout << nu << endl;
nu++;
}
}
猜數字遊戲
#include <iostream>
using namespace std;
// time系統時間標頭檔案包含
#include <ctime>
int main() {
// 新增隨機數的種子,利用當前系統時間生成隨機數,防止每次隨機數一樣
srand((unsigned int)time(NULL));
// 系統生成隨機數
int rand_nu = rand() % 100 + 1; // rand()%100生成0到99的隨機數
// 猜測數字
int guess_nu = 0;
while (guess_nu != rand_nu) {
cout << "請輸入一個數字:";
cin >> guess_nu;
// 判斷
if (guess_nu > rand_nu) {
cout << "輸大了,請重新猜測!!!" << endl;
}
else if (guess_nu < rand_nu){
cout << "輸小了,請重新猜測!!!" << endl;
}
else {
cout << "恭喜你,猜對了!!!" << endl;
break;
}
}
}
do···while迴圈語句
作用:滿足迴圈條件,執行迴圈語句
語法:do {迴圈語句} while (迴圈條件);
注意:與while的區別在於do...while會先執行一次迴圈時間,在判斷迴圈條件
#include <iostream>
using namespace std;
int main() {
// do...while語句
// 在螢幕中輸出 0 到 9 這10個數字
int num = 0;
do {
cout << num << endl;
num++;
}
while (num <= 9);
}
水仙花數
水仙花數是指一個三位數,它的每個位上的數字的3次冪之和等於它本身
如:1 ^ 3 + 5 ^ 3 + 3 ^ 3 = 153
#include <iostream>
using namespace std;
int main() {
int nu = 100;
// 水仙花數
do {
int ge = 0; // 定義個位的數字
int shi = 0; // 定義十位的數字
int bai = 0; // 定義百位的數字
ge = nu % 10;
shi = nu / 10 % 10;
bai = nu / 100;
if (ge*ge*ge + shi*shi*shi + bai*bai*bai == nu){
cout << "水仙花數:" << nu << endl;
}
nu++;
} while ( nu <= 999 );
}
for迴圈語句
作用:滿足迴圈條件,執行迴圈語句
語法:for (起始表示式;條件表示式;末尾迴圈體) { 迴圈語句; }
#include <iostream>
using namespace std;
int main() {
// for迴圈
// 從數字0列印到9
for (int i = 0; i < 10; i++ ) {
cout << i << endl;
}
// 也可以
int i = 0;
for (;;) {
if (i >= 10) {
break;
}
cout << i << endl;
i++;
}
}
案例:敲桌子
從1開始數到數字100,如果數字個位含有7,或者數字十位含有7,或者該數字是7的倍數,我們列印敲桌子,其餘的列印輸出
#include <iostream>
using namespace std;
int main() {
// 從1開始數到數字100,如果數字個位含有7,或者數字十位含有7,或者該數字是7的倍數,我們列印敲桌子,其餘的列印輸出
for (int i = 1; i < 100; i++) {
if (i % 10 == 7 || i % 100 / 10 == 7 || i % 7 == 0) {
cout << "敲桌子" << endl;
}
else {
cout << i << endl;
}
}
}
巢狀迴圈
作用:在迴圈中在巢狀一層迴圈,解決一些實際問題
#include <iostream>
using namespace std;
int main() {
// 巢狀迴圈
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
cout << "*";
}
cout << "" << endl;
}
}
列印九九乘法口訣表
#include <iostream>
using namespace std;
int main() {
// 巢狀迴圈
for (int i = 1; i < 10; i++) {
for (int j = 1; j < i+1; j++) {
cout << i << "*" << j << "=" << i * j << "\t";
}
cout << "" << endl;
}
}
跳轉語句
break語句
作用:用於跳出選擇結構或者迴圈結構
break使用的時機:
- 出現在switch語句中,作用是終止case並跳出switch
- 出現在迴圈語句中,作用是跳出當前的迴圈語句
- 出現在巢狀迴圈中,跳出最近的內層迴圈語句
continue語句
作用:在迴圈語句中,跳過本次迴圈中餘下尚未執行的語句,繼續執行下一次迴圈
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i <= 10; i++) {
if (i % 2 == 0) {
continue;
}
else {
cout << i << "\t";
}
}
}
goto語句
作用:可以無條件跳轉語句
語法:goto 標記;
解釋:如果標記的名稱存在,執行到goto語句時,會跳轉到標記的位置
#include <iostream>
using namespace std;
int main() {
// goto
cout << "hello" << endl;
cout << "hello" << endl;
cout << "hello" << endl;
goto flag;
cout << "hello" << endl;
cout << "hello" << endl;
flag:
cout << "world";
}
陣列
概述
陣列:就是一個集合,裡面存放了相同型別的資料元素
特點
- 陣列中的每個資料元素都是相同的資料型別
- 陣列是由連續的記憶體位置組成的
一維陣列
定義方式
資料型別 陣列名[ 陣列長度 ];
陣列型別 陣列名[ 陣列長度 ] = {值1, 值2...};
陣列型別 陣列名[ ] = {值1, 值2...}
#include <iostream>
using namespace std;
int main() {
// 1. 資料型別 陣列名[ 陣列長度 ];
int arr[4];
arr[0] = 10; // 賦值操作
// 2. 陣列型別 陣列名[ 陣列長度 ] = {值1, 值2...};
int arr1[5] = { 2, 2, 10, 20 }; // 如果在初始化資料的時候,沒有全部填完,會用0來填補剩餘資料
cout << arr1[0] << endl; // 通過下標索引取值
// 利用迴圈取值
for (int i = 0; i < 5; i++) {
cout << arr1[i] << endl;
}
}
定義陣列的時候必須有一個初始的長度
陣列名的命名規範與變數名命名規範一致,不要和變數重名
陣列中下標是從0開始索引
陣列名
一維陣列名稱的用途:
- 可以統計整陣列在記憶體中的長度
- 可以獲取陣列在記憶體中的首地址
#include <iostream>
using namespace std;
int main() {
int arr[5] = { 2, 2, 10, 20 };
cout << "陣列所佔空間為" << sizeof(arr) << "\n" << "裡面有" << (sizeof(arr) / sizeof(arr[0])) << "個元素" << endl;
cout << "陣列的首地址為" << (int)arr << "\n每個元素所佔空間為" << sizeof(arr[0]) << "\n陣列中第一個元素的地址為" << (int)&arr[0] << endl;
}
陣列名是一個常量,不可以進行賦值的操作
案例
找出陣列中的最大的元素
#include <iostream>
using namespace std;
int main() {
//找出陣列中最大的數字
int max_nu = 0; // max_nu用於儲存最大值
int arr[5] = { 300, 350, 200, 400, 250 };
for (int i = 0; i < ((sizeof(arr) / sizeof(arr[0]))-1); i++) {
max_nu = arr[i] > arr[i + 1] ? arr[i] : arr[i + 1];
}
cout << max_nu << endl;
}
組元素逆置
將陣列中的元素首尾進行互換
#include <iostream>
using namespace std;
int main() {
// 陣列裡面的內容逆轉
int arr1[5] = { 300, 350, 200, 400, 250 };
int end = sizeof(arr1) / sizeof(arr1[0]); // 末尾下標
int start = 0; // 起始下標
while (start < end) {
int temp = arr1[start];
arr1[start] = arr1[end];
arr1[end] = temp;
start++;
end--;
}
for (int i = 0; i < (sizeof(arr1) / sizeof(arr1[0])); i++) {
cout << arr1[i] << endl;
}
}
氣泡排序
作用:最常用的排序演算法,對陣列內的元素進行排序
- 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個
- 對每一對相鄰元素做同樣的工作,執行完畢後,找到第一個最大值
- 重複以上的步驟,每次比較次數-1,直到不需要比較
排序 int arr = { 4, 2, 8, 0, 5, 7, 1, 3, 9};
#include <iostream>
using namespace std;
int main() {
// 利用氣泡排序,實現升序排序
int arr[ ] = {4, 2, 8, 0, 5, 7, 1, 3, 9};
cout << "排序前:";
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
cout << arr[i] << " ";
}
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0]) - 1); i++) { // 排序次數為元素個數減一
for (int j = 0; j < (sizeof(arr) / sizeof(arr[0]) - 1 - i); j++) { // 內層迴圈對比次數元素個數 - 排序次數 - 1
if (arr[j] > arr[j + 1]) { // 如果前一個數字比第二個數字大,交換順序
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
cout << "排序後:";
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
cout << arr[i] << " ";
}
}
二維陣列
二維陣列就是在以為陣列上,多加一個維度
定義方式
資料型別 陣列名 [ 行數 ] [ 列數 ];
資料型別 陣列名 [ 行數 ] [ 列數 ] = { { 資料1, 資料2 }, {資料3, 資料4}} ;
資料型別 陣列名 [ 行數 ] [ 列數 ] = {資料1, 資料2, 資料3, 資料4};
資料型別 陣列名 [ ] [ 列數 ] = {資料1, 資料2, 資料3, 資料4};
以上定義方式,利用第二種更加直觀,提高程式碼的可讀性
#include <iostream>
using namespace std;
int main() {
// 1. `資料型別 陣列名 [ 行數 ] [ 列數 ];`
int arr1[2][3];
// 2. `資料型別 陣列名[行數][列數] = { { 資料1, 資料2 }, {資料3, 資料4} }; `
int arr2[2][3] = {
{1, 2 ,3},
{4, 5, 6}
};
// 二次迴圈,外層迴圈列印行數,內層迴圈列印列數
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << arr2[i][j] << " ";
};
cout << endl;
};
// 3. `資料型別 陣列名[行數][列數] = { 資料1, 資料2, 資料3, 資料4 }; `
int arr3[2][3] = { 1, 2, 3, 4, 5, 6 };
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << arr2[i][j] << " ";
};
cout << endl;
};
// 4. `資料型別 陣列名[][列數] = { 資料1, 資料2, 資料3, 資料4 }; `
int arr3[2][3] = { 1, 2, 3, 4, 5, 6 };
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << arr2[i][j] << " ";
};
cout << endl;
};
}
陣列名
- 檢視二維陣列所佔記憶體空間
- 獲取二維陣列首地址
#include <iostream>
using namespace std;
int main() {
int arr2[2][3] = {
{1, 2 ,3},
{4, 5, 6}
};
// 檢視佔用記憶體
cout << "二維陣列佔用記憶體空間為:" << sizeof(arr2) << endl;
cout << "二維陣列第一行佔用記憶體為:" << sizeof(arr2[0]) << endl;
cout << "二維陣列第一個元素佔用的記憶體為:" << sizeof(arr2[0][0]) << endl;
cout << "二位陣列的一行的元素數量為:" << sizeof(arr2[0]) / sizeof(arr2[0][0]) << endl << "二維陣列的行數為:" << sizeof(arr2) / sizeof(arr2[0]) << endl;
// 檢視二維陣列的首地址
cout << "二維陣列首地址為:" << (int)arr2 << endl;
cout << "二維陣列第一行的首地址為:" << (int)arr2[0] << endl;
cout << "二維陣列第一個元素的首地址為:" << (int)&arr2[0][0];
}
案例
有一個陣列 int arr[3][3] = {{100, 100, 100}, {90, 50, 100}, {60, 70, 80}}
計算該陣列每一行的總和
#include <iostream>
using namespace std;
int main() {
// 求陣列中每一行內數字的總和
int arr[3][3] = {
{100, 100, 100},
{90, 50, 100},
{60, 70, 80}
};
// 二次迴圈,得到陣列中的每一個值
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
int sum = 0;
for (int j = 0; j < (sizeof(arr[0]) / sizeof(arr[0][0])); j++) {
sum += arr[i][j];
};
cout << "第" << (i + 1) << "行的和為:" << sum <<endl;
};
}
函式
概述
作用:將一段經常使用的程式碼進行封裝起來,減少重複程式碼;一個較大的程式,一般分為若干個程式塊,每個模組實現特定的功能
函式的定義
函式的定義一般主要有5個步驟
- 返回值型別
- 函式名
- 引數系列
- 函式體語句
- return表示式
語法
返回值型別 函式名 (引數列表)
{
函式體語句
return 表示式
}
實現一個加法的函式,傳入兩個整型數值,計算資料相加的結果,並且返回
#include <iostream>
using namespace std;
// 函式體
int add(int num1, int num2) {
return num1 + num2;
}
函式的呼叫
功能:使用定義好的函式
語法:函式名(引數)
#include <iostream>
using namespace std;
// 函式體
int add(int num1, int num2) { // 函式定義裡面的引數沒有實際值,稱為形參(形式引數)
return num1 + num2;
}
int main() {
cout << add(1, 2) << endl; // 在main函式中呼叫add函式,其中,1和2為實參(實際引數),位置要一一對應
}
值傳遞
- 所謂值傳遞,就是函式呼叫時實參將數值傳入給形參
- 值傳遞時,如果形參發生改變,不會影響實參
#include <iostream>
using namespace std;
/*
值傳遞
定義函式,實現兩個數字進行交換函式
如果函式不需要返回值宣告的時候可以寫void
*/
void swap(int num1, int num2) {
cout << "交換前的數字" << endl << "num1:" << num1 << "\tnum2:" << num2;
int temp = num1;
num1 = num2;
num2 = temp;
cout << "\n交換後的數字" << endl << "num1:" << num1 << "\tnum2:" << num2;
}
int main() {
int num1 = 10;
int num2 = 20;
cout << "未呼叫前的數字" << endl << "num1:" << num1 << "\tnum2:" << num2 << endl; // 當我們做值傳遞的時候,函式的形參發生改變,並不會影響形參
swap(num2, num1);
}
函式的常見樣式
常見的函式樣式有4種
- 有參無返
- 無參無返
- 無參有返
- 有參有返
#include <iostream>
#include <string>
using namespace std;
// 1. 有參無返
void test01(string str) {
cout << str << endl;
}
// 2. 無參無返
void test02() {
cout << "this is test02" << endl;
}
// 3. 無參有返
int test03() {
return 100;
}
// 4. 有參有返
int test04(int num1, int num2) {
return num1 * num2;
}
int main() {
// 1. 有參無返呼叫
test01("hello world");
// 2. 無參無返呼叫
test02();
// 3. 有參無返呼叫
cout << test03() << endl;
// 4. 有參有返呼叫
cout << test04(2, 3) << endl;
}
函式的宣告
作用:告訴編譯器函式名稱及如何呼叫函式.函式的實際主體可以單獨定義
- 函式宣告可以多次,但是函式的定義只能有一次
#include <iostream>
#include <string>
using namespace std;
// 函式宣告:提前告訴編譯器函式的存在
// 函式宣告-->如果沒有該宣告那麼函式將不會呼叫
int max(int num1, int num2);
int main() {
int a = 10;
int b = 20;
cout << max(a, b) << endl;
}
// 比較函式,實現兩個整型數字進行比較,返回較大的數字
int max(int num1, int num2) {
return num1 > num2 ? num1 : num2;
}
函式的分檔案編寫
作用:讓程式碼結構更加清晰
函式分檔案編寫一般有4個步驟
- 建立字尾名為.h的標頭檔案
- 建立字尾名為.cpp的原始檔
- 在標頭檔案中寫函式的宣告
- 在新的原始檔中寫函式的定義
/* 新建的原始檔中 */
#include "標頭.h"
// 比較函式,實現兩個整型數字進行比較,返回較大的數字,函式定義
int max(int num1, int num2) {
return num1 > num2 ? num1 : num2;
}
/* 新建的標頭檔案中(名稱為標頭.h) */
#include <iostream>
using namespace std;
int max(int num1, int num2);
/* 執行檔案中 */
#include "標頭.h"
int main() {
int a = 10;
int b = 20;
cout << max(a, b) << endl;
}
指標
基本概念
作用:可以通過指標間接訪問記憶體
- 記憶體編號是從0開始記錄的,一般用十六進位制數字表示
- 可以利用指標變數儲存地址
定義和使用
指標變數定義語法:資料型別 * 變數名
#include <iostream>
using namespace std;
int main() {
// 定義一個指標
int a = 10;
// 指標定義語法:資料型別 * 變數名
int * p;
// 讓指標記錄變數a的地址
p = &a; // & 取址符號
cout << "a的地址為:" << &a << endl;
cout << "指標p的值為:" << p << endl;
// 使用指標
// 可以通過解引用的方式來找到指標指向的記憶體
// 指標前加 * 代表解引用,找到指標指向的記憶體中的資料
*p = 100;
cout << "a等於:" << a << "\n*p等於" << *p << endl;
}
指標所佔的記憶體空間
#include <iostream>
using namespace std;
// 在32位作業系統下,指標佔4bit,不管是什麼資料型別
// 在64位作業系統下,指標佔8bit
int main() {
int a = 10;
int * p = &a;
cout << "int *:" << sizeof(int*) << endl;
cout << "char *:" << sizeof(char*) << endl;
cout << "p:" << sizeof(p) << endl;
}
空指標和隱指標
空指標:指標變數指向記憶體中編號為0的空間
用途:初始化指標變數
注意:空指標指向的記憶體是不可以被訪問的
野指標:指標變數指向非法的記憶體空間
#include <iostream>
using namespace std;
int main() {
// 空指標
// 空指標用於給指標物件初始化
int* p1 = NULL;
// 空指標不能被訪問,其被系統佔用
// 野指標
// 在程式中一定要避免野指標
int * p = (int *)0x1100;
}
const修飾指標
const修飾指標有三種情況
- const修飾指標 --常量指標
const int * p = &a
- 指標的指向可以修改,但是指向的值不可以修改
- const修飾常量 --指標常量
int * const p = &a
- 指標的指向不可以改,指標的值可以改
- const即修飾指標 ,又修飾常量
#include <iostream>
using namespace std;
int main() {
int a = 10;
int b = 10;
// 常量指標
const int* p = &a;
// 指標指向的值不可以改,指向的位置可以修改
// * p = 20; 錯誤
p = &b; // 正確
// 指標常量
int* const p1 = &a;
// 指標指向的值可以修改,指向的位置不可以修改
*p1 = 20; // 正確
// p = &b; 錯誤
}
記憶方法:看const右側緊跟的是指標還是常量,是指標就是常量指標,是常量就是指標常量
指標和陣列
作用:利用指標訪問陣列中的元素
#include <iostream>
using namespace std;
int main() {
// 指標和陣列
// 利用指標訪問陣列中的元素
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
cout << "第一個元素為:" << arr[0] << endl;
int* p = arr; // arr就是陣列的首地址
cout << "利用指標來訪問第一個元素:" << *p << endl;
p++; // 讓指標偏移4bit
cout << "利用指標訪問第二個元素:" << *p << endl;
// 利用指標來訪問陣列,也可以通過p1[索引值來訪問]
int* p1 = arr;
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
cout << *p1++ << " ";
}
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
cout << p1[i] << " ";
}
}
指標和函式
作用:利用指標做函式的引數,可以修改實參的值
#include <iostream>
using namespace std;
void swap(int* p1, int* p2) {
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main() {
// 函式和指標
// 地址傳遞
int a = 10;
int b = 30;
cout << "a:" << a << " b:" << b << endl;
swap(&a, &b);
cout << "after a:" << a << " b:" << b << endl; // 地址中的記憶體發生改變
}
指標、陣列、函式
封裝一個函式,利用氣泡排序,實現對整型陣列的升序排序
例如,陣列:int arr[] = { 4, 3, 6, 9, 1, 2, 10, 8, 7, 5 };
#include <iostream>
using namespace std;
// 氣泡排序函式
void sort(int * arr, int length) { // 引數為陣列的記憶體地址
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
// 列印陣列
void print(int* arr, int length) {
for (int i = 0; i < length; i++) {
cout << arr[i] << " ";
}
}
int main() {
int arr[] = { 4, 3, 6, 9, 1, 2, 10, 8, 7, 5 };
int length = sizeof(arr) / sizeof(arr[0]);
sort(arr, length);
print(arr, length);
}
結構體
基本概念
結構體屬於使用者自定義的資料型別,允許使用者儲存不同的資料型別
定義和使用
語法:struct 結構體名 { 結構體成員列表 }
通過結構體建立變數的方式有三種
struct 結構體名 變數名
struct 結構體名 變數名 = { 成員值1, 成員值2, ... }
- 定義結構體是順便建立變數
#include <iostream>
#include <string>
using namespace std;
// 建立學生的資料型別:包括(姓名、年齡、分數)
// 自定義資料型別,一些型別集合組成的一個資料型別
struct Student
{
// 成員列表
string name; // name
int age; // age
int score; // score
}s3; // 順便建立結構體變數
int main() {
// 通過學生型別建立具體學生
// struct Student s1
struct Student s1; // struct關鍵字可以省略,但是定義的時候不能省略
// 給s1屬性賦值,通過.訪問結構變數中的屬性
s1.name = "張三";
s1.age = 18;
s1.score = 90;
cout << "name:" << s1.name << " age:" << s1.age << " score:" << s1.score << endl;
// struct Stufent s2 = { ... }
struct Student s2 = { "李四", 18, 80 };
cout << "name:" << s2.name << " age:" << s2.age << " score:" << s2.score << endl;
// 在定義接哦古體是順便建立結構體變數
s3.name = "王五";
s3.age = 18;
s3.score = 85;
cout << "name:" << s3.name << " age:" << s3.age << " score:" << s3.score << endl;
}
結構體陣列
作用:將自定義的結構體放入到陣列中方便維護
語法:struct 結構體名 陣列名 [ 元素個數 ] = { {}, {}, ...{} }
#include <iostream>
#include <string>
using namespace std;
// 結構體陣列
// 定義結構體陣列
struct Student
{
string name;
int age;
int score;
};
int main() {
// 建立結構體陣列
struct Student stuArray[3] = { // 給結構體陣列賦值
{"zhangsan", 18, 100},
{"lisi", 19, 99},
{"wangwu", 20, 85}
};
// 修改值
stuArray[2].name = "lihua";
stuArray[2].age = 19;
stuArray[2].score = 89;
// 遍歷陣列
for (int i = 0; i < 3; i++) {
cout << "name:" << stuArray[i].name << " age:" << stuArray[i].age << " score:" << stuArray[i].score << endl;
};
}
結構體指標
作用:通過指標訪問結構體中的成員
- 利用操作符
->
可以通過結構體指標訪問結構體屬性
#include <iostream>
#include <string>
using namespace std;
// 結構體指標
// 定義學生的結構體
struct Student
{
string name;
int age;
int score;
};
int main() {
// 建立學生結構體變數
struct Student s = { "zhangsan", 18, 99 };
// 通過指標指向結構體變數
struct Student* p = &s;
// 通過指標指向訪問結構體變數中的資料
cout << "name:" << p->name << " age:" << p->age << " score:" << p->score << endl;
}
結構體巢狀結構體
作用:結構體中的成員可以是另一個結構體
例如:每個老師輔導一個學生,一個老師的結構體,記錄一個學生的結構體
#include <iostream>
#include <string>
using namespace std;
// 結構體指標
// 定義學生的結構體
struct Student
{
string name;
int age;
int score;
};
// 定義老師結構體
struct Treacher
{
int id;
string name;
int age;
struct Student stu; // 輔導學生
};
int main() {
// 結構巢狀結構體
// 建立老師物件
struct Treacher t;
t.id = 100000;
t.name = "老王";
t.age = 58;
t.stu.name = "小王";
t.stu.age = 16;
t.stu.score = 60;
cout << "tea_name:" << t.name << " tea_id:" << t.id << " tea_age:" << t.age << "\nstu_name:" << t.stu.name << " stu_age:" << t.stu.age << " stu_score:" << t.stu.score << endl;
}
結構體做函式引數
作用:將結構體作為引數向函式中傳遞
傳遞的方式有兩種
- 值傳遞
- 地址傳遞
#include <iostream>
#include <string>
using namespace std;
// 定義學生的結構體
struct Student
{
string name;
int age;
int score;
};
// 列印學生資訊的函式,值傳遞
void printStuInfo(Student stu) {
stu.age = 100;
cout << "name:" << stu.name << " age:" << stu.age << " score:" << stu.score << endl;
};
// 地址傳遞:形參修改會引起實參的改變
void printStudentInfo2(Student* p) {
cout << "name:" << p->name << " age:" << p->age << " score:" << p->score << endl;
};
int main() {
// 結構體做函式的引數
// 將學生傳入到一個引數中,列印學生身上的所有資訊
// 建立結構體變數
struct Student stu;
stu.name = "zhangsan";
stu.age = 20;
stu.score = 85;
cout << "值傳遞" << endl;
printStuInfo(stu);
cout << "地址傳遞" << endl;
printStudentInfo2(&stu);
}
結構體中const使用場景
作用:用const來防止五操作
#include <iostream>
#include <string>
using namespace std;
// 定義學生的結構體
struct Student
{
string name;
int age;
int score;
};
// 地址傳遞,節省空間
void printStudentInfo2(const Student* p) { // 加入const之後,一旦有修改的操作就會報錯,可以防止我們的誤操作
cout << "name:" << p->name << " age:" << p->age << " score:" << p->score << endl;
};
int main() {
// const使用場景
// 建立結構體變數
struct Student stu;
stu.name = "zhangsan";
stu.age = 20;
stu.score = 85;
printStudentInfo2(&stu);
}
結構體案例
案例一
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
// 定義學生的結構體
struct Student
{
string name;
int score;
};
// 老師結構定義
struct Teacher
{
string name;
Student stuArray[5];
};
// 給老師和學生賦值的函式
void allocateSpace(Teacher tArray[], int len) {
// 給老師賦值
string name = "abcde";
for (int i = 0; i < len; i++) {
tArray[i].name = "Teacher_";
tArray[i].name += name[i]; // 字串的取值
// 給每名學生賦值
for (int j = 0; j < 5; j++) {
tArray[i].stuArray[j].name = "Student_";
tArray[i].stuArray[j].name += name[j];
int random = rand() % 61 + 40; // 40-99
tArray[i].stuArray[j].score = random;
}
};
};
// 列印學生和老師的資訊
void printInfo(Teacher* tArray, int len) {
for (int i = 0; i < len; i++) {
cout << "teacher_name:" << tArray[i].name << endl;
for (int j = 0; j < 5; j++) {
cout << "stu_name:" << tArray[i].stuArray[j].name << " stu_score:" << tArray[i].stuArray[j].score << endl;
};
cout << "--------------------------------------------------------------------------------" << endl;
};
}
int main() {
// 隨機數種子
srand((unsigned int)time(NULL));
// 三名老師陣列
Teacher tArray[3];
// 通過函式給老師的資訊賦值,並給老師帶的學生資訊賦值
int len = sizeof(tArray) / sizeof(tArray[0]);
allocateSpace(tArray, len);
printInfo(tArray, len);
}
案例二
有五個學生,通過氣泡排序的方法,將陣列中的學生按照年齡進行升序排序,最終列印排序後的結果
{ {"stu1", 23}, {"stu2", 22}, {"stu3", 20}, {"stu4", 21}, {"stu5", 19} }
#include <iostream>
#include <string>
using namespace std;
// 定義學生的結構體
struct Student
{
string name;
int age;
};
// 排序
void sort(Student* stuArray, int len) {
for (int i = 0; i < len - 1; i++) {
for (int j = 0; j < len - i - 1; j++) {
if (stuArray[j].age > stuArray[j + 1].age) {
struct Student temp = stuArray[j];
stuArray[j] = stuArray[j + 1];
stuArray[j + 1] = temp;
};
};
};
};
// 輸出
void printInfo(const Student * stuArray, int len) {
for (int i = 0; i < len; i++) {
cout << "name:" << stuArray[i].name << " age:" << stuArray[i].age << endl;
};
};
int main() {
// 建立陣列存放五名學生
Student stuArray[] = {
{"stu1", 23},
{"stu2", 22},
{"stu3", 20},
{"stu4", 21},
{"stu5", 19}
};
int len = sizeof(stuArray) / sizeof(stuArray[0]);
sort(stuArray, len);
printInfo(stuArray, len);
};