C++基礎語法
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);
};