1、找到config.json,在配置文件中新增水印效果 /* 上傳圖片配置項 */ "imageWater": "true",/*******************新增圖片水印設置 這裡是新增*/ "imageActionName": "uploadsimage", /* 執行上傳圖片的acti ...
最簡單的C++程式
#include <iostream>
using namespace std;
int main()
{
cout << "hello C++" << endl;
system("pause");
return 0;
}
使用C語言第三方庫
在C++中如何使用C語言打包好的庫函數
extern "C"
{
#include <libjpeg.h>
}
記憶體分配
空間分配原則是以“連續空閑”為核心的
-
運行某個程式後,一定會向記憶體申請空間
-
分配記憶體時,記憶體空間一定是連續的
-
分配出來的空間,是不確定位置的
註釋
單行註釋:
//一行的註釋內容
多行註釋:(模塊化註釋)
/*
多行的註釋內容
多行的註釋內容
*/
變數
作用:申請一段記憶體空間,給其取一個變數名,方便我們管理記憶體空間
數據類型 變數名 = 初始值
示例: int i
官方含義:在記憶體中申請連續的4個位元組,由變數i去間接訪問這塊4位元組的記憶體
全局變數/局部變數
-
全局變數是定義在函數之外,局部變數定義在函數之內;
-
全部變數在編譯時分配空間,局部變數在運行時才分配空間;
常量
作用:指的是那些不可被更改的數據
兩種表示方法:
1、#define 巨集常量
#define 常量名 常量值
2、const修飾的變數
const 數據類型 常量名 = 常量值
關鍵字
作用:C++中被已經被用掉的標識符
註意事項:自定義標識符的時候,不要用到C++用到的關鍵字
標識符
標識符命名規則:
-
不能是關鍵字
-
只有由字母、數字、下劃線組成
-
第一個字元不能是數字
-
區分大小寫
擴展規則:(也就是按實際情況去取捨)
-
儘可能包含更多信息
-
儘可能讓名字更有意義
-
儘可能不要太長
建議:命名標識符的時候,儘量做到見名知意,方便閱讀
數據類型
在創建變數或者常量的時候,必須指明相應的數據類型,否則無法成功分配記憶體。
整型
作用:給數據分配相對應的記憶體空間。
四種整型類型:
數據類型 |
記憶體大小 |
取值範圍 |
---|---|---|
int(整型) |
4個位元組 |
-2^31 ~ 2^31-1 |
short(短整型) |
2個位元組 |
-2^15 ~ 2^15-1 |
long(長整型) |
4個位元組(window環境下) |
-2^31 ~ 2^31-1 |
long long(長長整型) |
8個位元組 |
-2^63 ~ 2^63-1 |
實型(浮點型)
作用:用來表示小數
兩種分類:
數據類型 |
記憶體大小 |
取值範圍 |
---|---|---|
float(單精度) |
4個位元組 |
小數點後7位有效數字 |
double(雙精度) |
8個位元組 |
小數點後16位有效數字 |
字元型
作用:用來顯示單個字元
語法:char ch = ‘a’
記憶體空間:C/C++ 只占用1個位元組
註意事項:字元型變數不是把字元本身放到記憶體空間中,放進去的是字元對應的ASCII編碼
字元串型
作用:用於顯示一串字元
兩種語法表示方法:
1、C語言風格
char 變數名 [] = “一串字元串”;
2、C++風格字元串
string 變數名 = “一串字元串”;
sizeof
作用:統計數據類型記憶體大小。
語法:sizeof ( 數據類型 或者 變數 )
例子:
sizeof( short )
sizeof( int )
sizeof( long )
sizeof( long long )
布爾類型
作用:代表真或者假
記憶體空間:只占1個位元組
bool只有兩個數值:
-
true/.真 (實際上是1)
-
flase/假 (實際上是0)
註意事項:只要是非 0 的數值,都代表1
轉義字元
作用:用於顯示一些不能正常顯示的字元
現階段最常用的轉義字元有:\n \\ \t
所有的轉義字元和對應的意義:
數據的輸入
作用:用於從鍵盤獲取數據
關鍵字:cin
cin >> 變數
例子:
//1、整型
int a = 0;
cout << "請給整型變數a賦值:"<<endl;
cin >> a;
cout << "整型變數a = "<< a << endl;
//2、實型(浮點型)
float f = 3.14f;
cout << "請給浮點型變數f賦值:"<<endl;
cin >> f;
cout << "浮點型變數f = "<< f << endl;
//3、字元型
int ch = 'a';
cout << "請給字元型變數ch賦值:"<<endl;
cin >> ch;
cout << "字元型變數ch = "<< ch << endl;
//4、字元串型
#include<string> //記得加上字元串頭文件
string str = "hello";
cout << "請給字元串str賦值:"<<endl;
cin >> str;
cout << "字元串str = "<< str << endl;
//5、布爾型
bool flag = flase;
cout << "請給布爾型flag賦值:"<<endl;
cin >> flag;
cout << "布爾型flag = "<< flag << endl;
運算符
算術運算符
作用:用於處理四則運算
算術運算符包括以下符號:
運算符 |
術語 |
示例 |
結果 |
---|---|---|---|
+ |
加 |
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; |
賦值運算符
作用:用於表達式中給變數賦值
賦值運算符包括以下幾個字元:
運算符 |
術語 |
示例 |
結果 |
---|---|---|---|
= |
賦值 |
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; |
比較運算符
作用:用於表達式的比較,並返回一個真值或者假值。
比較運算符有以下符號:
運算符 |
術語 |
示例 |
結果(0:假,1:真) |
---|---|---|---|
== |
相等於 |
4==3 |
0 |
!= |
不等於 |
4!=3 |
1 |
< |
小於 |
4<3 |
0 |
> |
大於 |
4>3 |
1 |
<= |
小於等於 |
4<=3 |
0 |
>= |
大於等於 |
4>=3 |
1 |
邏輯運算符
作用:用於根據表達式的值返回真值或者假值。
邏輯運算符有以下符號:
運算符 |
術語 |
示例 |
結果 |
---|---|---|---|
&& |
與 |
a && b |
如果a和b都為真,則結果為真;否則為假 |
|| |
或 |
a || b |
如果a和b有一個為真,則結果為真;二者為假,結果為假。 |
! |
非 |
!a |
a為假,結果為真;a為真,結果為假; |
程式流程結構
C++支持的最基本的三種程式運行結構:
-
順序結構:程式按順序執行,不發生跳轉;
-
選擇結構:判斷條件是否滿足,有選擇性的執行相應的程式;
-
迴圈結構:判斷條件是否滿足,迴圈多次執行某一段程式;
程式流程結構——順序結構
這沒啥好說的,程式從上往下順序執行。
程式流程結構——選擇結構
if語句
作用:執行滿足條件的語句
if語句的三種形式:
-
單行格式if結構:if
-
多行格式if結構:if - else
-
多條件的if結構:if - else if - else
-
嵌套if結構:if { if { if } }
1、單行格式的if語句:if
語法:
if(關係表達式/條件)
{
滿足條件後執行的語句體;
}
2、多行格式的if語句:if - else
語法:
if(關係表達式/條件)
{
滿足條件後執行的語句體;
}
else
{
不滿足條件執行的語句體;
}
3、多條件的if結構:if - else if - else
語法:
if(關係表達式1/條件1)
{
滿足條件1後執行的語句體;
}
else if(關係表達式2/條件2)
{
滿足條件2後執行的語句體;
}
else
{
都不滿足時執行的語句體;
}
4、嵌套if語句:if { if { if } }
這是從前三種結構中延生出來的,在if語句中,可以嵌套其他的if語句
語法:
if(關係表達式1/條件1)
{
if(關係表達式2/條件2)
{
if(關係表達式3/條件3)
{
語句體;
}
}
}
switch語句
作用:執行多條見分支語句;
語法1:判斷結果是整型或者字元型
switch(關係表達式)
{
case 結果1:執行語句;
break;
case 結果2:執行語句;
break;
···
defaylt:執行語句;
break;
}
語法2:判斷結果是一個區間
switch(關係表達式)
{
case:結果1 ... 結果2: 執行語句;
break;
case:結果1 ... 結果2: 執行語句;
break;
default:執行語句;
break;
}
使用規範:
-
使用時在兩個數之間加“...”,且“...”兩邊必須有空格
-
判斷的表達式的值必須是整型
-
判斷時包含區間兩端的數值;
-
此語句不一定在所有編譯器下有效
程式流程結構——迴圈結構
作用:只要迴圈條件為真,就可以執行迴圈語句
while語句
特點:先判斷,在迴圈;
語法:
while(迴圈條件)
{
迴圈語句
}
do-while語句
特點:先迴圈一次,再判斷;
語法:
do
{
迴圈語句;
}
while(迴圈條件);
for語句
特點:結構清晰,代碼簡潔
語法:
for(起始表達式; 條件表達式; 末尾迴圈體)
{
迴圈語句;
}
break
作用:用於跳出選擇結構或者迴圈結構
使用規範:
-
出現在switch中,終止case並且跳出switch
-
出現在迴圈語句中,跳出當前迴圈體
-
出現在嵌套語句中,跳出最近的內層迴圈體
continue語句
作用:在迴圈語句中,跳過本次迴圈,接著下一次迴圈
goto語句
作用:無條件跳轉語句。標記符存在的話,執行到goto語句會跳轉到標記的位置;
語法:
goto 標記符;
標記符;
使用規範:
-
goto語句只能在同一個函數內跳轉
-
不能從一段複雜的執行狀態中跳轉到外面,比如不能從多重嵌套中跳轉出去
為什麼不建議使用goto語句:
-
goto可以被其他程式結構比如選擇結構替代
-
goto降低可讀性,goto太多,哪兒哪兒都是標記,跳來跳去,讓人讀程式容易混亂
數組
數組,就是一個集合,裡面存放了很多相同類型的數據元素
特點:
-
數組是由連續的記憶體位置組成的
-
數組中每個元素都是相同類型的
示例: int a[100]
官方含義:在記憶體中連續申請400個位元組,並且使用變數a間接訪問這片記憶體
一維數組
三種定義方式:
-
數據類型 數組名[ 數組長度 ];
-
數據類型 數組名[ 數組長度 ] = { 值1,值2,值3 ····};
-
數據類型 數組名 [ ] = { 值1,值2,···· };
數組名的用途:
-
獲取數組在記憶體中的首地址
-
可以統計整個數組所占記憶體空間
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
1、獲取數組在記憶體中的首地址
cout << "元素首地址:" << (int)arr << endl;
cout << "數組中第一個元素的地址:" << (int)&arr[0] << endl;
cout << "數組中第一個元素的地址:" << (int)&arr[1] << endl;
//2、可以統計整個數組在記憶體空間長度
cout << "獲取數組記憶體空間長度:" << sizeof(arr) << endl;
cout << "每個元素所占的記憶體空間:" << sizeof(arr[n]) << endl;
cout << "數組的元素個數:" << sizeof(arr)/sizeof(arr[0]) << endl;
二維數組
二維數組就是在一維數組的基礎上多加了一個維度
四種定義方式:
-
數據類型 數組名[ 行數 ][ 列數 ];
-
數據類型 數組名[ 行數 ][ 列數 ] = { 值1,值2,值3,值4 };
-
數據類型 數組名[ 行數 ][ 列數 ] = { (值1,值2),(值3,值4) };
-
數據類型 數組名[ ][ 列數 ] = { 值1,值2,值3,值4 };
數組名的用途:
-
獲取二維數組在記憶體中的首地址
-
獲取整個二維數組所占記憶體空間
int arr[2][3] = {
(1,2,3),
(3,4,5)
};
// 1、獲取二維數組在記憶體中的首地址
cout << "二維數組首地址" << arr << endl;
cout << "二維數組第一行地址" << arr[0] << endl;
cout << "二維數組第二行地址" << arr[1] << endl;
cout << "二維數組第一個元素地址" << &arr[0][0] << endl;
cout << "二維數組第二個元素地址" << &arr[0][1] << endl;
// 2、獲取整個二維數組所占記憶體空間
cout << "二維數組大小:" << sizeof(arr) << endl;
cout << "二維數組一行大小:" << sizeof(arr[0]) << endl;
cout << "二維數組元素大小:" << sizeof(arr[0][0]) << endl;
cout << "二維數組行數:" << sizeof(arr)/sizeof(arr[0]) << endl;
cout << "二維數組列數:" << sizeof(arr[0])/sizeof(arr[0][0]) << endl;
函數
函數,又叫介面或者API
作用:講一段常用的代碼封裝起來,減少代碼重覆量
使用場景:通常是將一段複雜冗長的代碼,封裝成一個一個模塊
函數的定義
定義:有5個步驟:
-
返回值類型
-
函數名
-
參數列表
-
函數體語句
-
return表達式
語法:
返回值類型 函數名 (參數列表)
{
函數體語句;
return;
}
註意事項:函數的定義只能出現一次,不然會出現重覆定義的錯誤。
函數名命名規則:(跟變數命名規則一樣)
-
不能是關鍵字
-
只有由字母、數字、下劃線組成
-
第一個字元不能是數字
-
區分大小寫
函數的調用
作用:將定義好的函數拿出來使用
語法:
函數名 (參數);
值傳遞
-
所謂值傳遞,就是再函數調用的時候,將實參傳入到形參
-
值傳遞的時候,形參不會影響實參
函數的常見樣式
常見的樣式有4種:
-
有參有返
-
有參無返
-
無參有返
-
無參無返
語法:
//1、有參有返
數據類型 函數名 (數據類型 變數)
{
函數體;
return x;
}
//2、有參無返
void 函數名(數據類型 變數)
{
函數體;
}
//3、無參有返
數據類型 函數名()
{
函數體;
return x;
}
//4、無參無返
void 函數名()
{
函數體;
}
函數的聲明
作用:告訴編譯器有這個函數的名稱,可以拿去調用
函數的聲明可以多次,但是函數的定義只有一次。
函數的分文件編寫
作用:如果所有的代碼都寫在一個文件種,會非常麻煩,分文件編寫可以讓代碼結構更加清晰
分文件編寫的4個步驟:
-
創建.h頭文件
-
創建.cpp的源文件
-
在頭文件種寫函數聲明
-
在源文件種寫函數定義和主函數
指針
作用:通過指針間接訪問記憶體
-
可以用指針變數保存地址信息
-
記憶體編號是從0開始記錄的,一般用十六進位數字表示
指針的定義
語法:
數據類型 * 變數名
引用與解引用
引用:用指針記錄地址信息
int a = 10;
int *p;
p = &a;
//用指針p保存變數a的地址信息
解引用:找到指針指向的記憶體地址
指針前面加“ * ”代表解引用,代表找到指針指向的記憶體中的數據
*p = 1000; //找到了指針p指向的記憶體數據,並將其數據修改成1000
指針所占記憶體空間
在32位操作系統下,占用4個位元組,與數據類型無關
在64位操作系統下,占用8個位元組,與數據類型無關
空指針
定義:指針變數指向記憶體中編號位0的空間
作用:用來初始化指針變數
註意事項:
-
空指針指向的記憶體是不允許訪問的
-
記憶體編號0~255之間的記憶體都是系統占用的,不允許訪問
示例:
//這就是空指針,指向了NULL,用來給指針變數初始化用的,但是不允許訪問
int *p = NULL;
*p = 1000; //錯誤,空指針不允許訪問
野指針
定義:指針變數指向非法的記憶體空間
一般都是訪問那些還沒有申請的地址,就是野指針
示例:
int *p = NULL; //這是空指針,是合法的
int *p = (int *)0x1100; //這是野指針,因為地址空間0x1100還沒有申請。直接拿來用是非法的
const修飾指針
const修飾的指針,一般有3種情況:
-
const修飾指針 —— 常量指針
-
const修飾常量 —— 指針常量
-
const既修飾指針,又修飾常量
1、const修飾指針 —— 常量指針
修飾的是指針,所以指針指向的地址中的數據不可變,指向的地址可以變
const int *p1 = &a;
p1 = &b; //正確,地址可變
*p1 = 100; //錯誤,數據不可變
2、const修飾常量 —— 指針常量
修飾的是常量,所以指針指向的地址不可變,指向的地址中的數據可以變
int * const p2 = &a;
p2 = &b; //錯誤,地址不可變
*p2 = 100;//正確,數據可變
3、const既修飾指針,又修飾常量
既修飾指針,又修飾地址,所以指針指向的地址不可變,地址中的數據也不可變
const int * const p3 = &a;
p3 = &b; //錯誤,地址不可變
*p3 = 100; //錯誤,數據不可變