01 -- C++入門教程


01 -- C++基礎入門


作者:elfin   資料來源:黑馬程序員



1、C++初識

1.1 第一個C++程序

​ 創建一個HelloWorld程序

  • 01 項目創建

  • 02 創建文件

  • 03 編寫代碼

    示例:

    #include <iostream>
    using namespace std;
    
    int main()
    {
        cout << "hello, C++" << endl;
        
    	system("pause");
        
    	return 0;
    }
    
  • 04 運行程序

    點擊上方的綠色運行按鈕,運行項目:

Top  ---  Bottom


1.2 注釋

作用:在代碼塊中方便程序員閱讀代碼,起解釋、說明的功能。

兩種格式

  • 單行注釋// 注釋信息

    通常在代碼行的上方或者一條語句的末尾,對慈航代碼進行說明

  • 多行注釋/*注釋信息*/

    通常放在一段代碼的上方,對此段代碼做整體說明。

編譯器在編譯時會忽略注釋內容!

Top  ---  Bottom


1.3 變量

注意一個項目只能有一個main函數,這里先注釋之前的main函數,再創建 02 變量輸出.cpp

作用:給一段指定的內存空間起名,方便操作這段內存。

語法數據類型 變量名 = 初始值;

示例

#include <iostream>
using namespace std;

int main()
{
	// 測試變量
	int a = 5;

	cout << "a = " << a << endl;

	system("pause");

	return 0;
}

Top  ---  Bottom


1.4 常量

作用:用於記錄程序中不可更改的數據。

C++定義常量的兩種方式:

  • #define 宏變量#define 常量名 常數值

    通常在文件上方定義,表示一個常量。

  • const修飾的變量:const 數據類型 常量名 = 常數值

    通常在變量定義前加關鍵字const,修飾該變量為常量,不可修改!

示例

#include <iostream>
using namespace std;

// 常量的定義方式
// 1、#define 宏常量
// 2、const修飾的變量

// 1、定義宏常量
#define Day 7

int main()
{
	// 定義const修飾的常量
	const int month = 12;

	cout << "一年有 " << month << "月;每周有" << Day << "天" << endl;

	system("pause");

	return 0;
}

Top  ---  Bottom


1.5 關鍵字

關鍵字不能作為變量名!

關鍵字介紹查看:菜鳥教程

關鍵字介紹查看:博客資源

asm do if return typedef
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

Top  ---  Bottom


1.6 標識符命名規則

作用:C++規定給標識符(變量、常量)命名時。需遵守如下規則:

  • 標識符不能是關鍵字
  • 標識符只能由字母、數字、下划線組成
  • 第一個字符必須是字母或者下划線
  • 標識符區分大小寫

Top  ---  Bottom


2、數據類型

C++規定在創建一個變量或者常量時,必須指出相應的數據類型,否則無法給變量分配內存!

2.1 整型

作用:整型變量表示的是整數類型的數據!

數據類型 占用空間 取值范圍
short(短整型) 2字節 (-2^15, 2^15 - 1)
int(整型) 4字節 (-2^31, 2^31 - 1)
long(長整型) Windows為4字節,Linux32位為4字節,64為8字節 (-2^31, 2^31 - 1)
long long(長長整型) 8字節 (-2^63, 2^63 - 1)

示例:

#include <iostream>
using namespace std;

// 常量的定義方式
// 1、#define 宏常量
// 2、const修飾的變量

// 1、定義宏常量
#define Day 7

int main()
{
	// 定義const修飾的常量
	const int month = 12;
	long long elfin = 10;

	cout << "一年有 " << month << "月;每周有" << Day << "天" << endl;
	cout << "elfin今年" << elfin<< "歲" << endl;

	system("pause");

	return 0;
}

Top  ---  Bottom


2.2 sizeof關鍵字

作用:利用sizeof關鍵字可以統計數據類型所占的內存大小

語法sizeof(數據類型或變量)

示例

#include <iostream>
using namespace std;


int main()
{
	// 定義const修飾的常量
	short a1 = 10;
	long a2 = 10;
	long long a3 = 10;

	cout << "short的內存大小:" << sizeof(a1) << endl;
	cout << "int的內存大小:" << sizeof(int) << endl;
	cout << "long的內存大小:" << sizeof(a2) << endl;
	cout << "long long的內存大小:" << sizeof(a3) << endl;

	system("pause");

	return 0;
}

Top  ---  Bottom


2.3 實型

作用:用於表示小數

浮點型變量浮點型變量分為兩種:

  • 01 單精度float
  • 02 雙精度double

兩者的去吧在於表示的有效數字范圍不同。

數據類型 占用空間 有效數字范圍
float 4字節 7位有效數字(含整數部分)
double 8字節 15~16為有效數字

示例

#include <iostream>
using namespace std;

int main()
{
	// 定義float、double類型的常量
	float f1 = 12.036f;
	double d1 = 100.56;

	cout << "sizeof(f1): " << sizeof(f1) << endl;
	cout << "sizeof(d1): " << sizeof(d1) << endl;

	system("pause");

	return 0;
}

默認輸出六位有效數字!

Top  ---  Bottom


2.4 字符型

作用:字符型變量用於顯示單個字符

語法char ch = 'a'

注意1:在顯示字符型變量時,用單引號將字符括起來,不要用雙引號

注意2:單引號內只能有一個字符,不可以是字符串

  • C和C++中字符型變量只占用1個字符
  • 字符型變量並不是把字符本身放到內存中存儲,而是將相應的ASCII編碼放入到存儲單元

示例

#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{
	// 字符型創建方式
	char ch = 'd';
	// 字符型變量所占的內存大小
	cout << "字符型變量所占的內存大小sizeof(ch): " << sizeof(ch) << endl;
	
	// 字符型變量常見錯誤
	// char ch2 = "b"; // 創建字符型變量,必須使用單引號
	char ch3 = 'dc'; // 語法沒有報錯,但是鼠標移動到dc上顯示 int 25699
	cout << "ch3: " << ch3 << endl;
	cout << "ch3: " << typeid(ch3).name() << endl;

	// 字符變量對應的ASCII編碼
	char ch4 = 'a';
	cout << "ch4: " << (int)ch4 << endl;

	system("pause");

	return 0;
}

注意這里ch3輸出的並不是‘dc’

Top  ---  Bottom


2.5 轉義字符

作用:用於一些不能表達出來的ASCII字符

先階段常用的轉義字符有: \n \\ \t

示例

轉義字符 意義 ASCII碼值(十進制)
\a 響鈴(BEL) 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 空字符(NUL) 000
\ddd 1到3位八進制數所代表的任意字符 三位八進制
\xhh 十六進制所代表的任意字符 十六進制

Top  ---  Bottom


2.6 字符串類型

作用:用於表示一串字符

語法

  • C風格字符串char 變量名[] = "字符串值"
  • C++風格字符串string 變量名 = "字符串值"

注意C風格的字符串要用雙引號!

示例

#include <iostream>
#include <string> // 使用C++類型的字符串
using namespace std;

int main()
{
	// C風格字符串
	char ch[] = "dc";
	cout << "ch: " << ch << endl;

	// C++風格字符串
	string ch2 = "hello world";
	cout << "ch2: " << ch2 << endl;

	system("pause");

	return 0;
}

Top  ---  Bottom


2.7 布爾數值類型

作用:表示真、假

語法bool 變量名 = true/false

布爾類型只占一個字節的內存空間!

Top  ---  Bottom


2.8 數據的輸入

作用用於從鍵盤獲取數據

關鍵字cin

語法cin >> 變量

示例

#include <iostream>
#include <string> // 使用C++類型的字符串
using namespace std;

int main()
{
	// 整型輸入
	int a = 0;
	cout << "請輸入整型變量:" << endl;
	cin >> a;
	cout << "a:" << a << endl;

	// 浮點型輸入
	double d = 0;
	cout << "請輸入浮點型變量:" << endl;
	cin >> d;
	cout << "d:" << d << endl;

	// 字符型輸入
	char ch = 'a';
	cout << "請輸入字符型變量:" << endl;
	cin >> ch;
	cout << "ch:" << ch << endl;

	// 字符串型輸入
	string ch2 = "world";
	cout << "請輸入字符串型變量:" << endl;
	cin >> ch2;
	cout << "ch2:" << ch2 << endl;

	// 布爾型輸入
	bool b = 0;
	cout << "請輸入布爾型變量:" << endl;
	cin >> b;
	cout << "b:" << b << endl;

	system("pause");

	return 0;
}

Top  ---  Bottom


3、運算符

作用:用於執行代碼的運算

運算符類型 作用
算術運算符 處理四則運算
賦值運算符 用於將表達式的值賦給變量
比較運算符 用於表達式的比較,並返回一個真值或假值
邏輯運算符 用於根據表達式的值返回真值或假值

3.1 算術運算符

假設變量 A 的值為 10,變量 B 的值為 20,則:

運算符 描述 實例
+ 把兩個操作數相加 A + B 將得到 30
- 從第一個操作數中減去第二個操作數 A - B 將得到 -10
* 把兩個操作數相乘 A * B 將得到 200
/ 分子除以分母;
這里如果分子分母都是整數,則結果也是整數
B / A 將得到 2
% 取模(取余)運算符,整除后的余數 B % A 將得到 0
++ 自增運算符,整數值增加 1 A++ 將得到 11
-- 自減運算符,整數值減少 1 A-- 將得到 9
  • 前置遞增:如b = ++a是先對變量a遞增再賦值;
  • 后置遞增:如b = a++是先對變量b賦值在遞增;
  • 遞減與遞增一樣!

示例

#include <iostream>
using namespace std;

int main()
{
	int a = 21;
	int c;

	// a 的值在賦值之前不會自增
	c = a++;
	cout << "Line 1 - Value of a++ is :" << c << endl;

	// 表達式計算之后,a 的值增加 1
	cout << "Line 2 - Value of a is :" << a << endl;

	// a 的值在賦值之前自增
	c = ++a;
	cout << "Line 3 - Value of ++a is  :" << c << endl;
	return 0;
}

Top  ---  Bottom


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*=3; a=6;
/= 除等於 a=6; a/=2; a=3;
%= 模等於 a=3; a%=2; a=1;

Top  ---  Bottom


3.3 比較運算符

作用:用於表達式的比較,並返回一個真值或假值

比較運算符有以下符號:

示例

運算符 術語 示例 結果
== 相等於 4==2; 0
!= 不等於 4!=3; 1
< 小於 4<3; 0
> 大於 3>2; 1
<= 小於等於 2<=3; 1
>= 大於等於 3>=1; 1

Top  ---  Bottom


3.4 邏輯運算符

作用:用於根據表達式的值返回真值或假值

邏輯運算符有以下符號:

示例

運算符 術語 示例 結果
! !a 如果a為真,!a為假,即取反
&& a && b 當且僅當a、b都為真a && b才是真
|| a||b a、b中有一個為真,a || b就為真

Top  ---  Bottom


4、程序流程控制

C/C++支持最基本的程序運行結構:順序結構選擇結構循環結構

  • 順序結構:程序按順序執行,不發生跳轉
  • 選擇結構:依據條件是否滿足,有選擇的執行相應功能
  • 循環結構:依據條件是否滿足,循環多次執行某段代碼

4.1 選擇結構

4.1.1 if語句

作用:執行滿足一傲嬌的語句

if語句的三種形式:

  • 單行格式if語句
  • 多行格式if語句
  • 多條件的if語句
  1. 單行格式if語句if(條件){條件滿足執行的語句}

    st=>start: 開始框
    op=>operation: 執行語句
    cond=>condition: 判斷條件框(是或否?)
    e=>end: 結束框
    st->cond
    cond(yes)->op->e
    cond(no)->e
    
  2. 多行格式if語句if(條件){滿足條件時執行的語句}else{不滿足條件時執行的語句}

    st=>start: 開始框
    op1=>operation: 執行語句1
    op2=>operation: 執行語句2
    cond=>condition: 判斷條件框
    e=>end: 結束框
    st->cond
    cond(yes)->op1->e
    cond(no)->op2->e
    
    if(a>=1){
        cout << "a大於等於1" << endl;
    }
    else{
        cout << "a不大於1" << endl;
    }
    
  3. 多條件的if語句

    st=>start: 開始框
    op1=>operation: 執行語句1
    op2=>operation: 執行語句2
    op3=>operation: ……
    op4=>operation: 執行語句n
    op5=>operation: 執行語句n+1
    cond=>condition: 判斷條件1
    cond1=>condition: 判斷條件2
    cond2=>condition: ……
    cond3=>condition: 判斷條件n
    e=>end: 結束框
    st->cond
    cond(yes)->op1->e
    cond(no)->cond1(yes)->op2->e
    cond(no)->cond1(no)->cond2(yes)->op3->e
    cond(no)->cond1(no)->cond2(no)->cond3(yes)->op4->e
    cond(no)->cond1(no)->cond2(no)->cond3(no)->op5->e
    
    if(a>5)
    {
        cout >> "a > 5" >> endl;
    }
    else if(a >= 3)
    {
        cout >> "3 <= a <=5" >> endl;
    }
    else
    {
        cout >> "a不滿足要求" >> endl;
    }
    
  4. 嵌套if語句:在if語句中,可以嵌套使用if語句,達到更精確的條件判斷!

    案例需求:

    • 提示用戶輸入一個高考考試分數,根據分數做如下判斷
    • 分數如果大於600分視為考生一本,大於500分考上二本,大於400考上三本,其余視為未考上本科
    • 在一本分數中,大於700分考上北大,大於650分考上清華,大於600分考上人大
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	int score = 0;
    	cout << "請輸入你的高考成績:" << endl;
    	cin >> score;
    
    	if (score > 600) {
    		cout << "恭喜你考上一本:" << endl;
    		if (score > 700) {
    			cout << "恭喜你考上北大……" << endl;
    		}
    		else if (score > 650) {
    			cout << "恭喜你考上清華……" << endl;
    		}
    		else{
    			cout << "恭喜你考上人大……" << endl;
    		}
    	}
    	else if (score > 500) {
    		cout << "恭喜你考上二本……" << endl;
    	}
    	else if (score > 400) {
    		cout << "恭喜你考上三本……" << endl;
    	}
    	else {
    		cout << "抱歉,你未考上本科……" << endl;
    	}
    	system("pause");
    	return 0;
    }
    

4.1.2 三目運算符

c = (a>b?a:b);

如果a大於b,則返回a,否則返回b。

在C++中,三目運算符返回的是變量可以賦值:

int a = 10
int b = 20
(a > b ? a : b) = 100

此時b=100

python中一般使用:條件為真的結果 if 條件 else 為假時的返回


Top  ---  Bottom

4.1.3 switch語句

作用:執行多條件的分支語句

語法

switch{
    case 結果1: 執行語句;break;
    case 結果1: 執行語句;break;
    ……
    default:執行語句;break;
}

示例

#include <iostream>
using namespace std;

int main()
{
	char a = 'a';
	cout << "請輸入字符:s或者c" << endl;
	cin >> a;
	switch (a)
	{
	case 's':
		cout << "case:s input>>" << a << endl;
	case 'c':
		cout << "case:c input>>" << a << endl;
	default:
		break;
	}
}

Top  ---  Bottom

4.2 循環結構

讓代碼重復地去執行

4.2.1 while循環

作用:滿足循環條件,執行循環語句

語法while(循環條件){循環語句}

示例

#include <iostream>
using namespace std;

int main()
{
	int num = 0;
	while (num < 10)
	{
		cout << "輸出num=" << num << endl;
		num++;
	}
	system("pause");
	return 0;
}

注意不要寫死循環!


Top  ---  Bottom

4.2.2 do-while循環語句

作用:滿足循環條件,執行循環語句

語法do{循環語句}while(循環條件)

示例

#include <iostream>
using namespace std;

int main()
{
	int num = 0;
	do
	{
		cout << "輸出num=" << num << endl;
		num++;
	}
    while (num < 10)
	system("pause");
	return 0;
}

do-while不滿足條件也會先執行一次!,即后判斷條件!


Top  ---  Bottom

4.2.3 for循環結構

作用:滿足循環條件,執行循環語句

語法for(循環條件){循環語句}

示例

using namespace std;

int main()
{
	for (int i = 0; i < 10; i++)
	{
		cout << "輸出i=" << i << endl;
	}
	system("pause");
	return 0;
}

注意for后面的三個語句不是必須寫在括號里的,但是i++必須放在判斷條件后!


Top  ---  Bottom

4.2.4 嵌套循環

嵌套循環與嵌套選擇結構類似

4.2.5 跳轉結構 break、continue、goto

break:跳出當前循環;

continue:跳出本次循環執行下一次;

goto:無條件跳轉到標記的位置;

#include <iostream>
using namespace std;

int main()
{
	cout << "輸出  1" << endl;
	goto FLAG;
	cout << "輸出  2" << endl;
	flag:
	cout << "輸出  3" << endl;
	FLAG:
	cout << "輸出  4" << endl;
	goto flag;
	cout << "輸出  5" << endl;
	
	system("pause");
	return 0;
}

注意上面的代碼是死循環,需要說明的是一般不要使用goto,使用的時候也不要將goto放置在標記后面,不然會容易成為死循環!


Top  ---  Bottom

5、數組

5.1 概述

所謂數組,就是一個集合,里面存放了相同類型的數據元素

特點1:數組中的每個數據元素都是相同的數據類型

特點2:數組是由連續的內存位置組成的


5.2 一維數組

5.2.1 一維數組定義方式

一維數組定義的三種方式:

  1. 數據類型 數組名[數組長度];
  2. 數據類型 數組名[數組長度] = {值1, 值2, ……};
  3. 數據類型 數組名[ ] = {值1, 值2, ……};

示例

#include <iostream>
using namespace std;


int main()
{
	// 數據類型  數組名[數組長度];
	int arr[5];
	arr[0] = 20;
	arr[1] = 50;
	arr[2] = 45;
	arr[3] = 7;
	arr[4] = 0;
	cout << "輸出  arr[3] = " << arr[3] << endl;

	// 數據類型  數組名[數組長度] = {值1, 值2, ……};
	// 初始化如果沒有全部賦值,會使用0填充
	int arr2[5] = {25, 32, 1, 36, 5};
	cout << "輸出  arr2[2] = " << arr2[3] << endl;

	// 數據類型  數組名[數組長度] = {值1, 值2, ……};
	int arr3[] = { 25, 32, 1, 36, 5, 36};
	cout << "輸出  arr3[2] = " << arr3[3] << endl;
	system("pause");
	return 0;
}

Top  ---  Bottom

5.2.2 數組名的用途

  1. 統計數組在內存中的長度 sizeof(arr)
  2. 可以獲取數組在內存中的首地址

示例

#include <iostream>
using namespace std;


int main()
{
	// 數組名用途
	// 1、可以通過數組名統計整個數組占用內存大小
	int arr2[5] = { 25, 32, 1, 36, 5 };
	cout << "整個數組占用的內存空間為: " << sizeof(arr2) << endl;
	cout << "每個元素占用的內存空間為: " << sizeof(arr2[0]) << endl;
	cout << "數組中元素個數為: " << sizeof(arr2) / sizeof(arr2[0]) << endl;
	// 2、可以通過數組名查看數組首地址
	cout << "數組的首地址為: " << (int)arr2 << endl;
	cout << "數組第一個元素的地址為: " << (int)arr2[0] << endl;
	cout << "數組第二個元素的地址為: " << (int)arr2[1] << endl;
	// 數組名不可修改
	system("pause");
	return 0;
}

元素逆置:

#include <iostream>
using namespace std;


int main()
{
	// 數組逆置
	// 1、創建數組
	int arr2[5] = { 1, 2, 3, 4, 5 };
	cout << "數組逆置前: " << endl;
    for (int i = 0; i < 5; i++)
    {
        cout << arr2[i] << endl;
    }
    // 2、實現逆置:記錄起始、結束的下標位置;互換起始結束下標的位置;
    // 起始位置,結束位置分別++、--;循環執行,直到起始位置大於等於結束位置
    int start = 0; //起始下標
    int end = sizeof(arr2) / sizeof(arr2[0]) -1; //結束下標
    while (start < end)
    {
        //實現元素互換
        int temp = arr2[start];
        arr2[start] = arr2[end];
        arr2[end] = temp;
        //下標更新
        start++;
        end--;
    }
    //輸出逆置后的元素
    cout << "數組逆置后: " << endl;
    for (int i = 0; i < 5; i++)
    {
        cout << arr2[i] << endl;
    }
    
	system("pause");
	return 0;
}

Top  ---  Bottom

5.2.3 冒泡排序

作用:最常用的排序算法,對數組內元素進行排序

  1. 比較相鄰的元素,如果第一個比第二個大,就交換他們兩個。
  2. 對每一對相鄰元素做同樣的工作,執行完畢后,找到第一個最大值。
  3. 重復以上的步驟,每次比較次數-1,直到不需要比較。

示例:將數組{4,2,8,0,5,7,1,3,9}進行升序排列

裝逼版:后面有純凈版的代碼

#include <iostream>
#include <Windows.h>
using namespace std;

void COLOR_PRINT(const char* s, int color)
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
	printf(s);
	SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | 7);
}

int main()
{
	// 創建需要排序的數組
	int arr[9] = {4,2,8,0,5,7,1,3,9};
	// 輸出排序前的數組元素
	printf("排序前的數組:%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d", 
		arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8]);
	printf("\n正在排序中……\n");
	for (int i = 0; i < 9 - 1; i++)
	{
		for (int j = 0; j < 8 - i; j++)
		{
			printf("排序中的數組:");
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
				

				for (int k = 0; k < 9; k++)
				{
					if (k == j || k == j + 1)
					{
						printf("\033[33m%-4d\033[0m", arr[k]);
					}
					else
					{
						printf("%-4d", arr[k]);
					}
				}
				printf("\r");
				Sleep(1000);
			}
			else
			{
				for (int k = 0; k < 9; k++)
				{
					if (k == j || k == j + 1)
					{
						printf("\033[33m%-4d\033[0m", arr[k]);
					}
					else
					{
						printf("%-4d", arr[k]);
					}
				}
				printf("\r");
				Sleep(1000);
			}
		}
	}
	printf("\n排序結束……\n");

	printf("排序后的數組:%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d",
		arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8]);
	system("pause");
	return 0;
}

純凈版:

#include <iostream>
#include <Windows.h>
using namespace std;

int main()
{
	// 創建需要排序的數組
	int arr[9] = {4,2,8,0,5,7,1,3,9};
	// 輸出排序前的數組元素
	printf("排序前的數組:%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d", 
		arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8]);
	printf("\n正在排序中……\n");
	for (int i = 0; i < 9 - 1; i++)
	{
		for (int j = 0; j < 8 - i; j++)
		{
			printf("排序中的數組:");
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
				
				printf("排序后的數組:%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d",
					arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8]);
				printf("\r");
				Sleep(1000);
			}
		}
	}
	printf("\n排序結束……\n");

	printf("排序后的數組:%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d",
		arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8]);
	system("pause");
	return 0;
}

這里相鄰元素判斷時,else實際上沒有什么用,裝逼版的代碼僅僅是為了,動態顯示排序的過程!


Top  ---  Bottom

5.3 二維數組

二維數組就是在一維數組上,多加一個維度。

5.3.1 二維數組定義方式

二維數組定義的四種方式:

  1. 數據類型 數組名[行數][列數];
  2. 數據類型 數組名[行數][列數] = {{數據1, 數據2}, {數據3, 數據4}};
  3. 數據類型 數組名[行數][列數] = {數據1, 數據2, 數據3, 數據4};
  4. 數據類型 數組名[][列數] = {數據1, 數據2, 數據3, 數據4};

建議:以上4種定義方式,利用第二種更加直觀,提高代碼的可讀性

#include <iostream>
using namespace std;

int main()
{
	// 創建需要的數組
	// int arr[2][2];
	int arr1[2][2] = {1,2,3,4};
	// int arr2[2][2] = { {4,2},{8,0}};
	// int arr3[][2] = { {4,2},{8,0}};
	// 外層循環打印行數,內層循環打印列數
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 2; j++)
		{
			cout << arr1[i][j]<< endl;
		}
	}
	
	system("pause");
	return 0;
}

5.3.2 二維數組數組名

  • 查看二維數組所占內存空間
  • 獲取二維數組首地址
#include <iostream>
#include <Windows.h>
using namespace std;


int main()
{
	// 創建需要的數組
	// int arr[2][2];
	int arr1[2][2] = { 1,2,3,4 };
	// 可以查看占用內存空間大小
	cout << "二維數組大小:" << sizeof(arr1) << endl;
	cout << "二維數組一行大小:" << sizeof(arr1[0]) << endl;
	cout << "二維數組元素大小:" << sizeof(arr1[0][0]) << endl;
	cout << "二維數組的行數:" << sizeof(arr1) / sizeof(arr1[0]) << endl;
	cout << "二維數組的列數:" << sizeof(arr1[0]) / sizeof(arr1[0][0]) << endl;
	// 可以查看二維數組的首地址
	cout << "二維數組首地址為:" << int(arr1) << endl;
	cout << "二維數組第一行首地址為:" << int(arr1[0]) << endl;
	cout << "二維數組第二行首地址為:" << int(arr1[1]) << endl;
	// 這里可以發現二維數組的內存也是連續的!

	system("pause");
	return 0;
}

Top  ---  Bottom

6、函數

6.1 函數的定義

函數的定義一般有5個步驟:

  • 1、返回值類型
  • 2、函數名
  • 3、參數列表
  • 4、函數體語句
  • 5、return表達式

語法

返回值類型 函數名(參數列表)
{
    函數體語句;
    return 表達式;
}

示例

#include <iostream>
#include <Windows.h>
using namespace std;

// num1、num2是形參,實際傳入的時候是實參
int add(int num1, int num2)
{
	int num = num1 + num2;
	return num;
}

int main()
{
	// 函數調用
	int num = add(2, 6);

	cout << "num=" << num << endl;
	system("pause");
	return 0;
}

Top  ---  Bottom

6.2 函數的值傳遞

作用:所謂值傳遞就是函數調用時實參將值傳入給形參

值傳遞時,如果形參發生變化,並不會影響實參

示例

#include <iostream>
using namespace std;

// 值傳遞
// 定義函數,實現兩個數字進行交換函數

//如果函數不需要返回值,聲明的時候可以寫void
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;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	// 函數調用,當我們值傳遞時,函數的形參發生改變並不會影響實參
	swap(2, 6);
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	system("pause");
	return 0;
}

Top  ---  Bottom

6.3函數的聲明

作用:告訴編譯器函數名稱及如何調用函數。函數的實際主體可以單獨定義。

  • 函數的聲明可以多次,但是函數的定義只能有一次

示例

main函數放在被調用的函數之前,被調用的函數必須提前聲明!

#include <iostream>
using namespace std;

// 函數的聲明
// 比較函數,實現兩個整數的比較,返回較大的值

// 提前告訴編譯器函數的存在,可以利用函數的聲明
// 函數的聲明,聲明可以有多次,但是定義只能有一次
int my_max(int num1, int num2);

int main()
{
	int a = 10;
	int b = 20;
	cout << my_max(a,b) << endl;
	system("pause");
	return 0;
}

// 定義
int my_max(int num1, int num2)
{
	return num1 > num2 ? num1 : num2;
}

Top  ---  Bottom

6.4 函數的分文件編寫

作用:將部分對象單獨寫一個文件,讓代碼結構更加清晰

函數分文件編寫一般4個步驟:

  • 1、創建后綴為.h的頭文件
  • 2、創建后綴名為.cpp的源文件
  • 3、在頭文件中寫函數的聲明
  • 4、在源文件中寫函數的定義

示例1 – 創建頭文件

#include <iostream>
using namespace std;

void swap(int num1, int num2);

示例2 – 創建源文件

#include "swap.h"

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
}

示例3 – 其他源文件調用

#include <iostream>
using namespace std;
#include "swap.h"


int main()
{
	int a = 10;
	int b = 20;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	// 函數調用,當我們值傳遞時,函數的形參發生改變並不會影響實參
	swap(2, 6);
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	system("pause");
	return 0;
}

Top  ---  Bottom

7、指針

7.1 指針的基本概念

作用:可以通過指針間接訪問內存

  • 內存編號是從零開始記錄的,一般采用十六進制數字表示
  • 可以利用指針變量保存內存地址

7.2 指針變量的定義和使用

指針變量的語法數據類型 * 變量名;

示例

#include <iostream>
using namespace std;

int main()
{
	// 1、定義一個指針
	int a = 10;
	cout << "a=" << a << endl;
	// 指針定義的語法:數據類型 * 指針變量名
	int* p;
	// 讓指針記錄變量a的地址
	p = &a;
	cout << "a的地址為:" << &a << endl;
	cout << "指針p為:" << p << endl;

	// 2、使用指針
	// 可以通過“解引用”的方式來找到指針指向的內存
	// 指針前加 * 代表解引用,找到指針指向的內存中的數據
	*p = 1000;
	cout << "a=" << a << endl;
	cout << "*p=" << *p << endl;
	
	system("pause");
	return 0;
}

Top  ---  Bottom

7.3 指針所占的內存空間

指針表示了一個內存地址,內存地址編號的存儲:

  • 32位操作系統,占用四個字節
  • 64位占用8個字節
cout << "sizeof (int *) = " << sizeof(int *) << endl;
cout << "sizeof (int *) = " << sizeof(p) << endl;

Top  ---  Bottom

7.4 空指針和野指針

空指針

空指針:指針變量指向內存中編號為0的空間

用途:初始化指針變量

注意:空指針指向的內存是不可以訪問的

示例1:空指針

#include <iostream>
using namespace std;

int main()
{
    // 空指針
    // 1、空指針用於給指針變量初始化
    // 指針變量p指向內存地址編號為0的空間
    int* p = NULL;

    //2、空指針是不能進行訪問的
    // 內存編號為0~255的內存編號是系統占用的,因此不能訪問、更改
    // *p = 100;  // 訪問空指針會報錯
    system("pause");
    return 0;
}

野指針

作用:指針變量指向非法的內存空間

示例2:野指針

#include <iostream>
using namespace std;

int main()
{
    // 野指針
    // 1、指向了0x1100內存,但是我們沒有申請這塊空間,所以野指針不能進行操作
    int * p = (int *)0x1100; // 語法能夠通過,但是不能進行操作!

    //2、野指針是不能進行訪問的
    // cout << *p << endl; 運行會報錯
    system("pause");
    return 0;
}

總結:空指針與野指針都不是我們申請的空間,所以不要訪問!


Top  ---  Bottom

7.5 const修飾指針

const修飾指針有三種情況;

  • 1、const修飾指針 ---> 常量指針
  • 2、const修飾常量 ---> 指針常量
  • 3、const既修飾指針又修飾常量

示例

#include <iostream>
using namespace std;

int main()
{
    // 1、常量指針
    // 指針的指向可以修改,指向的值不能修改
    int a = 10;
    const int * p1 = &a; // 常量指針



    //2、指針常量
    // const修飾常量時,是指針常量,不能修改指針的指向,可以修改指向的值
    int b = 20;
    int * const p2 = &b; // 指針常量


    // 3、既修飾指針又修正常量
    // 指針的指向與指針指向的值都不能修改
    int c = 2;
    const int * const p3 = &c;
    cout << *p3 << endl;
    system("pause");
    return 0;
}

總結

  • 按照const、*出現的順序命名;
  • const + * 標識常量指針
  • * + const 標識指針常量

Top  ---  Bottom

7.6 指針和數組

作用:利用指針訪問數組中的元素

指針的類型決定了使用p++時的自增字節數,如int、float在Windows下都是自增4,而double類型是自增8,這樣恰好和我們的數據類型對應上。

示例

#include <iostream>
using namespace std;

int main()
{
    //指針和數組
    //利用指針訪問數組中的元素

    // 創建數組
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    const int * p = arr; // 指向數組的指針

    cout << "第一個元素:" << arr[0] << endl;
    cout << "指針訪問第一個元素:" << *p << endl;

    for (int i = 0; i < 9; i++)
    {
        // 利用指針遍歷數組
        cout <<  *p << endl;
        p++; // ++會向后偏移4個字節,因為本來就是int類型的指針
        cout << "指針的指向內存地址:" << (int)&*p << endl;
    }

    // 其他類型的指針++也是增加4個字節嗎?
    double arr2[] = { 2.36, 2.14, 3.56 };
    double* p1 = arr2;
    for (int i = 0; i < 3; i++)
    {
        // 利用指針遍歷數組
        cout << *p1 << endl;
        p1++; // ++會向后偏移8個字節,因為指針是double類型
        cout << "double指針的指向內存地址:" << (int)&*p1 << endl;
    }


    system("pause");
    return 0;
}

Top  ---  Bottom

7.7 指針和函數

作用:地址傳遞可以改變實參的值

:如果不想修改實參就用值傳遞,如果想修改實參就使用地址傳遞!

示例

#include <iostream>
using namespace std;
void swap01(int num1, int num2);
void swap02(int * num1, int * num2);

int main()
{
    //指針和函數
    //之前我們使用形參、實參實現函數內外的值傳遞;
    //如果在函數里面修改形參的值,函數體外的實參也想對應發生變化怎么辦?

    //1、值傳遞
    int a = 12;
    int b = 24;
    cout << "值傳遞前的a=" << a << endl;
    cout << "值傳遞前的b=" << b << endl;
    swap01(a, b);
    cout << "值傳遞后的a=" << a << endl;
    cout << "值傳遞后的b=" << b << endl;

    //2、地址傳遞
    cout << "地址傳遞前的a=" << a << endl;
    cout << "地址傳遞前的b=" << b << endl;
    swap02(&a, &b);
    cout << "地址傳遞后的a=" << a << endl;
    cout << "地址傳遞后的b=" << b << endl;
    system("pause");
    return 0;
}

void swap01(int num1, int num2)
{
    int temp = num1;
    num1 = num2;
    num2 = temp;
    cout << "swap01的a=" << num1 << endl;
    cout << "swap01的b=" << num2 << endl;
}

void swap02(int * num1, int * num2)
{
    int temp =  *num1;
    *num1 = *num2;
    *num2 = temp;
    cout << "swap02的a=" << * num1 << endl;
    cout << "swap02的b=" << * num2 << endl;
}

Top  ---  Bottom

7.8 指針使用案列

案列描述:封裝一個函數,利用冒泡排序,實現對整型數組的升序排序

例如數組:int arr[6] = { 10, 2, 65, 22, 41, 9 };

示例

#include <iostream>
using namespace std;

void bubbleSort(int * arr, int len)
{
	for (int i = 0; i < len - 1; i++) 
	{
		for (int j = 0; j < len - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}

void printArray(int* arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << endl;
	}
}

int main()
{
	// 1、先創建數組
	int arr[6] = { 10, 2, 65, 22, 41, 9 };

	// 數組長度
	int len = sizeof(arr) / sizeof(arr[0]);

	// 2、創建函數,實現冒泡排序
	bubbleSort(arr, len);

	// 3、打印排序后的數組
	printArray(arr, len);

	system("pause");
	return 0;
}

Top  ---  Bottom

8、 結構體

8.1 結構體的基本概念

結構體屬於用戶自定義的數據類型,允許用戶存儲不同的數據類型

8.2 結構體定義和使用

語法struct 結構體名{結構體成員列表};

通過結構體創建變量的方式有三種:

  • struct 結構體名 變量名
  • struct 結構體名 變量名 = {成員值1, 成員值2…}
  • 定義結構體時順便創建變量

示例:創建學生類型的結構體

#include <iostream>
#include <string>
using namespace std;

// 定義結構體
struct student
{
	// 配置名字
	string name;
	// 配置年齡
	int age;
	// 配置得分
	float score;
}s3;

int main()
{
	// 通過學生數據類型,創建學生
	// 1、struct  結構體名   變量名
	struct student s1; // 創建變量時,struct關鍵字可以省略
	s1.name = "elfin";
	s1.age = 23;
	s1.score = 98.5;
	cout << "  姓名:\t" << s1.name 
		 << "\t年齡:\t" << s1.age 
		 << "\t分數:\t" << s1.score << endl;
	// 2、struct  結構體名   變量名 = {成員值1, 成員值2…}
	struct student s2 = { "嬴政", 12, 60 };
	cout << "  姓名:\t" << s2.name
		 << "\t年齡:\t" << s2.age
		 << "\t分數:\t" << s2.score << endl;
	// 3、定義結構體時順便創建變量(不建議使用)
	// 即在創建結構體時,在結構體的"}"后書寫變量名
	s3.name = "吳正天";
	s3.age = 28;
	s3.score = 100;
	cout << "  姓名:\t" << s3.name
		 << "\t年齡:\t" << s3.age
		 << "\t分數:\t" << s3.score << endl;

	system("pause");
	return 0;
}

運行結果:

總結:創建結構體時關鍵字struct是必須要寫的,在創建結構體變量時這個關鍵字可以省略!


Top  ---  Bottom

8.3 結構體數組

作用:將自定義的結構體放入到數組中方便維護(實際和數組里面放int類型數據一樣)

語法struct 結構體名 數組名[元素個數] = { {}, {}, … ,{}}

這里的創建方式是和數組創建方式是一樣的!

示例

#include <iostream>
#include <string>
using namespace std;

// 定義結構體
struct student
{
	string name;
	int age;
	float score;
}s3;

int main()
{
	// 創建結構體數組
	// 創建結構體數組時,struct可以省略
	struct student arr[3] = {
		{"elfin", 23, 89.5},
		{"嬴政", 12, 90},
		{"吳正天", 28, 100},
	};
	arr[2].name = "武則天";

	// 遍歷結構體數組
	for (int i = 0; i < 3; i++)
	{
		cout << "姓名:" << arr[i].name
			 << "\t年齡:" << arr[i].age
			 << "\t分數:" << arr[i].score << endl;
	}
	
	system("pause");
	return 0;
}

運行結果:

總結:結構體數組變量和普通的數組變量是一樣的,只是結構體數組變量的元素是一個自定義數據類型,元素會包含一些自定義的屬性變量!(成員)


Top  ---  Bottom

8.4 結構體指針

作用:通過指針訪問結構體中的成員

語法p->name 指針p使用“->”后面接結構體屬性就可以訪問該屬性了!

示例

#include <iostream>
#include <string>
using namespace std;

// 定義結構體
struct student
{
	string name;
	int age;
	float score;
};

int main()
{
	// 創建結構體數組
	// 創建結構體數組時,struct可以省略
	struct student arr[3] = {
		{"elfin", 23, 89.5},
		{"嬴政", 12, 90},
		{"吳正天", 28, 100},
	};
	arr[2].name = "武則天";

	// 通過指針指向結構體變量
	student* p = &arr[2];
	// 通過指針訪問結構體的屬性
	cout << "姓名:" << p->name
		<< "\t年齡:" << p->age
		<< "\t分數:" << p->score << endl;

	// 通過結構體數組的指針訪問結構體元素的屬性
	struct student* p1 = arr;
	for (int i = 0; i < 3; i++)
	{
		cout << "姓名:" << p1->name
			<< "\t年齡:" << p1->age
			<< "\t分數:" << p1->score << endl;
		p1++;
	}
	
	system("pause");
	return 0;
}

運行結果:


Top  ---  Bottom

8.5 結構體嵌套結構體

作用:結構體的成員可以是另一個結構體

例如:每個老師單獨輔導一個學生,一個老師的結構體中,記錄一個學生的結構體

示例

#include <iostream>
#include <string>
using namespace std;

// 定義結構體
struct student
{
	string name;
	int age;
	float score;
};

struct teacher
{
	string name;
	int age;
	student s1;
};

int main()
{
	// 創建嵌套結構體變量
	struct teacher t1;
	t1.name = "elfin";
	t1.age = 45;
	t1.s1 = { "白天", 12, 60 };
    cout << "姓名:" << t1.name
		<< "\t年齡:" << t1.age
		<< "\t學生姓名:" << t1.s1.name 
		<< "\t學生年齡:" << t1.s1.age 
		<< "\t學生得分:" << t1.s1.score
		<< endl;
	system("pause");
	return 0;
}

Top  ---  Bottom

8.6 結構體做函數參數

作用:將結構體作為參數想函數中傳遞

傳遞方式有兩種:

  • 值傳遞 (形參改變不改變實參)
  • 地址傳遞 (形參改變會改變實參)

示例

#include <iostream>
#include <string>
using namespace std;


// 定義結構體
struct student
{
	string name;
	int age;
	float score;
};

// 打印學生信息的函數
// 值傳遞
void printStudent1(struct student s)
{
	s.age = 24;
	cout << "\n值傳遞的   姓名:" << s.name
		<< "\t年齡:" << s.age
		<< "\t得分:" << s.score
		<< endl;
}

// 地址傳遞
void printStudent2(struct student * s)
{
	s->age = 12;
	cout << "\n地址傳遞的 姓名:" << s->name
		<< "\t年齡:" << s->age
		<< "\t得分:" << s->score
		<< endl;
}

int main()
{
	// 結構體做函數參數
	// 將學生傳入到一個參數中,打印學生的所有信息

	struct student t1 = {"elfin", 18, 100};
	cout << "main函數中 姓名:" << t1.name
		<< "\t年齡:" << t1.age
		<< "\t得分:" << t1.score
		<< endl;
	printStudent1(t1);
	cout << "\nmain函數中 姓名:" << t1.name
		<< "\t年齡:" << t1.age
		<< "\t得分:" << t1.score
		<< endl;
	printStudent2(&t1);
	cout << "\nmain函數中 姓名:" << t1.name
		<< "\t年齡:" << t1.age
		<< "\t得分:" << t1.score
		<< endl;
	system("pause");
	return 0;
}

Top  ---  Bottom

8.7 結構體中const的使用場景

作用:用const防止誤操作

語法:哪里不想修改就給哪個加const,如在地址傳遞時,形參的變化會引起實參的變化,而我們不想實參發生變化,那么就給形參加const!

示例

#include <iostream>
#include <string>
using namespace std;

// 定義結構體
struct student
{
	string name;
	int age;
	float score;
};

void printStudent1(struct student s)
{
	cout << "\n值傳遞的   姓名:" << s.name
		<< "\t年齡:" << s.age
		<< "\t得分:" << s.score
		<< endl;
}

// 將函數中的形參改為指針,可以減少內存開銷而且不會復制新的副本出來
// 地址傳遞有隱患,如果內部修改屬性了外側也會修改,防止被修改,可以給形參加const,防止誤操作
void printStudent2(const struct student* s)
{
	cout << "\n地址傳遞的 姓名:" << s->name
		<< "\t年齡:" << s->age
		<< "\t得分:" << s->score
		<< endl;
}

int main()
{
	// 創建結構體變量
	struct student s = { "張三", 15, 80 };
	// 通過函數打印結構體的信息
	printStudent1(s); // 值傳遞
	printStudent2(&s); 
	system("pause");
	return 0;
}

Top  ---  Bottom

8.8 結構體案例

案例描述

  • 設計一個英雄的結構體,包括成員姓名、年齡、性別;

  • 創建結構體數組,數組中存放5名英雄;

  • 通過冒泡排序的算法,將數組中的英雄按照年齡進行降序排列,最終打印排序后的結果。

  • 英雄信息如下:

    {"貂蟬", 19, "女"},
    {"張飛", 20, "男"},
    {"關羽", 22, "男"},
    {"趙雲", 21, "男"},
    {"劉備", 23, "男"}
    

示例

#include <iostream>
#include <string>
using namespace std;

// 定義結構體
struct hero
{
	string name;
	int age;
	string sex;
};

void printHero(struct hero s[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << "\t姓名:" << s[i].name
			<< "\t年齡:" << s[i].age
			<< "\t性別:" << s[i].sex
			<< endl;
	}
	
}

void bubbleSort(struct hero s[], int len, string order)
{
	for (int i = 0; i < len - 1; i++)
	{
		// 降序排列
		if (order == "descending")
		{
			for (int j = len - 1; j > i; j--)
			{
				if (s[j].age > s[j - 1].age)
				{
					hero temp = s[j];
					s[j] = s[j - 1];
					s[j - 1] = temp;
				}
			}
		}
		// 升序排列
		else
		{
			for (int j = 0; j < len -  i - 1; j++)
			{
				if (s[j].age > s[j + 1].age)
				{
					hero temp = s[j];
					s[j] = s[j + 1];
					s[j + 1] = temp;
				}
				
			}
		}
		
	}
	// 打印排序后的結構體數組
	if (order == "descending")
	{
		cout << "結構體數組降序排列:" << endl;
	}
	else
	{
		cout << "結構體數組升序排列:" << endl;
	}
	printHero(s, len);
}


int main()
{
	// 創建結構體數組變量
	struct hero arr[5] = {
		{"貂蟬", 19, "女"},
		{"張飛", 20, "男"},
		{"關羽", 22, "男"},
		{"趙雲", 21, "男"},
		{"劉備", 23, "男"}
	};
	// 通過函數打印結構體的信息
	int len = sizeof(arr) / sizeof(arr[0]);
	cout << "打印原始的結構體數組信息:" << endl;
	printHero(arr, len);
	// 將結構體數組降序輸出
	bubbleSort(arr, len, "descending");

	// 將結構體數組升序輸出
	bubbleSort(arr, len, "scending");
	
	system("pause");
	return 0;
}

Top  ---  Bottom


完!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM