C++基礎 VS快捷鍵 Ctrl +或- 跳轉到上次滑鼠焦點位置 Ctrl K F 按住Ctrl 然後按K 然後按F Ctrl J 代碼提示 變數 聲明方式:數據類型 變數名 = 變數初始值 #include <iostream> using namespace std; int main() { ...
C++基礎
VS快捷鍵
Ctrl +或- 跳轉到上次滑鼠焦點位置
Ctrl K F 按住Ctrl 然後按K 然後按F
Ctrl J 代碼提示
變數
聲明方式:數據類型 變數名 = 變數初始值
#include <iostream>
using namespace std;
int main()
{
int a = 1;
char b = 'b';
}
常量
#define 巨集常量
聲明方式:#define 常量名 常量值
通常在文件上方定義
#include <iostream>
using namespace std;
#define day 7
int main()
{
cout << "一周有" << day <<"天" << endl;
}
const修飾的變數
聲明方式:const 數據類型 變數名 = 變數值
#include <iostream>
using namespace std;
int main()
{
const int day = 7;
cout << "一周有" << day <<"天" << endl;
}
命名規則
- 標識符不能是關鍵字
- 標識符只能有字母,數字,下劃線
- 第一個字元必須為字母或下劃線
- 區分大小寫
數據類型
整型
- short 2位元組
- int 4位元組
- long windows 4位元組 Linux32位 4位元組 Linux64位 8位元組
- long long 8位元組
sizeof關鍵字
- 用來獲取數據類型所占用記憶體大小
- 語法: sizeof( 數據類型 / 變數 )
#include <iostream>
using namespace std;
int main()
{
int a = 1;
long b = 1;
long long c = 1;
cout << "int類型占用:" << sizeof(int) << endl;
cout << "int變數占用:" << sizeof(a) << endl;
cout << "long類型占用:" << sizeof(long) << endl;
cout << "long變數占用:" << sizeof(b) << endl;
cout << "long long類型占用:" << sizeof(long long) << endl;
cout << "long long變數占用:" << sizeof(c) << endl;
}
輸出結果(我使用的是windows 所以long類型也是4位元組大小):
int類型占用:4
int變數占用:4
long類型占用:4
long變數占用:4
long long類型占用:8
long long變數占用:8
浮點型
- double 8位元組 有效數字範圍15-16位
- float 4位元組 有效數字範圍7位
需要註意的一點是:當我們聲明一個float類型的帶小數的變數時,編輯器會預設認為是double類型,準確指出類型需要在變數值最後加F
#include <iostream>
using namespace std;
int main()
{
float a = 1.1F;
float b = 1.1;
}
上面兩種都可
字元型
語法: char c='a'
- 字元類型只能使用單引號,而不是雙引號
- 只能是單個字元,不能是字元串
- c/c++中字元類型只占用
1位元組
- 字元類型並不是把字元本身放到記憶體中存儲,而是轉換為對應的ASCll碼存放
#include <iostream>
using namespace std;
int main()
{
char a = 'h';
char b = 'e';
cout << "變數a:" << a << endl;
cout << "變數b:" << b << endl;
}
輸出char類型變數的ascll碼
強轉為int類型輸出即可
#include <iostream>
using namespace std;
int main()
{
char a = 'h';
char b = 'e';
cout << "變數a:" << (int)a << endl;
cout << "變數b:" << (int)b << endl;
}
轉義字元
就寫幾個常用的
- \n 換號
- \t 一個table的位置
- \\ 代表一個\
字元串類型
C風格字元串
聲明方式: char 變數名[] = "字元串值"
#include <iostream>
using namespace std;
int main()
{
char s[] = "hello world";
cout << s << endl;
}
C++風格字元串
聲明方式:string 變數名="字元串值"
如果使用不了string 需要導入頭文件
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "hello world";
cout << s << endl;
}
Bool類型
表示真和假,只有兩個值
- false 0
- true 1
bool類型只占用一個位元組大小
#include <iostream>
#include <string>
using namespace std;
int main()
{
bool b = true;
cout << b << endl;
}
數據的輸入
用於獲取鍵盤的輸入
關鍵詞:cin
語法: cin>>變數
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 1;
cin >> a;
cout << a << endl;
}
運算符
- 算數運算符 處理四則運算
- 賦值運算符 將表達式賦值給變數
- 比較運算符 表達式的比較並返回一個bool值
- 邏輯運算符 用於根據表達式的值返回true或false
算數運算符
運算符 | 術語 | 示例 | 結果 |
---|---|---|---|
+ | 正號 | +3 | 3 |
- | 負號 | -3 | -3 |
+ | 加號 | 10+5 | 15 |
- | 減號 | 10-5 | 5 |
* | 乘號 | 10*5 | 50 |
/ | 除號 | 10/5 | 2 |
% | 取模(取餘) | 10%3 | 1 |
++ | 前置自增 | a=2;b=++a; | a=3;b=3; |
++ | 後置自增 | a=2;b=a++; | a=3;b=2; |
-- | 前置自減 | a=2;b=--a; | a=1;b=1; |
-- | 後置自減 | a=2;b=a--; | a=1,b=2 |
tips: 兩數相除,除數不能為0
兩數取餘,第二個數也不能為0;
兩個小數是不能做取餘操作
int main()
{
int a = 2;
int b = a++;
//其他操作也基本類似,就不粘代碼了
cout << a << endl;
cout << b << endl;
}
賦值運算符
運算符 | 術語 | 示例 | 結果 |
---|---|---|---|
= | 賦值 | a=2; | a=2; |
+= | 加等於 | a=2; a+=1; | a=3; |
-= | 減等於 | a=2;a-=1; | a=1; |
*= | 乘等於 | a=2;a*=2; | a=4; |
/= | 除等於 | a=4;a/=2; | a=2; |
%= | 模等於 | a=3;a%=2; | a=1; |
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 1;
a += 1;
// a = a + 1; 等同於這段代碼 其他操作類似
cout << a << endl;
}
比較運算符
運算符 | 術語 | 示例 | 結果 |
---|---|---|---|
== | 相等於 | 1==1 | 1 (true) |
!= | 不等於 | 1!=1 | 0 (false) |
< | 小於 | 1<1 | 0 (false) |
<= | 小於等於 | 1<=1 | 1 (true) |
> | 大於 | 1>1 | 0 (false) |
>= | 大於等於 | 1>=1 | 1 (true) |
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << (1<=1) << endl;
}
邏輯運算符
運算符 | 術語 | 示例 | 結果 |
---|---|---|---|
! | 非(取反) | !a | 如果a為假,則!a為真 反之亦然 |
&& | 與 (並且) | a&&b | 如果ab都為真,則結果為真,其中一個為假,則整體為假 |
|| | 或 (或者) | a||b | 只要其中一個為真,則結果為真,都為假則結果為假 |
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 10;
cout << !a << endl;
/*
結果為0 因為邏輯運算符會把變數當成bool類型來操作,bool中只有0和非0
那麼10作為非0的數值被當成true,取反為false, 而false的int類型數值為0
所以結果為0
*/
cout << !!a << endl;
/*
結果為1 原因如上,當第一個!走完後結果已經為0了,而bool值只有0和非0
非零預設值是1,所以兩次取反後結果為1
*/
//加幾個!沒有限制,可以無限加
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 10;
int b = 0;
cout << (a && b) << endl;
/*
結果為0 (false)
*/
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 10;
int b = 0;
cout << (a|| b) << endl;
/*
結果為1 (true)
*/
}
程式流程結構
選擇結構
if
#include <iostream>
#include <string>
using namespace std;
int main(){
int a = 10;
int b = 0;
if (a) {
cout << "a" << endl;
}
else if (b){
cout <<"b" << endl;
}
else {
cout << "else" << endl;
}
}
三目運算符
語法:條件?為true返回的:否則返回的
例如a=1;b=2;
a>b?a:b
a大於b嗎?是的返回a,否則返回b
#include <iostream>
#include <string>
using namespace std;
int main() {
int a = 10;
int b = 0;
int c = a > b ? a : b;
cout << c << endl;
/*
結果10
*/
}
#include <iostream>
#include <string>
using namespace std;
int main() {
int a = 10;
int b = 0;
//返回變數並賦值
( a > b ? a : b)=50;
cout << a << endl;
cout << b << endl;
/*
結果a=50
b=0;
*/
}
不僅可以返回變數,也可以在三目中進行賦值操作等
#include <iostream>
#include <string>
using namespace std;
int main() {
int a = 10;
int b = 0;
int c;
a > b ? c = 10 : c = 20;
cout << c << endl;
//結果c=10;
}
switch
#include <iostream>
#include <string>
using namespace std;
int main() {
char a = 's';
switch (a)
{
case 's':
cout << "s" << endl;
break;
case 'h':
cout << "h" << endl;
break;
default:
cout << "default" << endl;
break;
}
//結果 s
}
#include <iostream>
#include <string>
using namespace std;
int main() {
int a = 3;
switch (a)
{
case 1:
cout << "1" << endl;
break;
case 2:
cout << "2" << endl;
break;
default:
cout << "default" << endl;
break;
}
//結果 default
}
tips : 如果一個case沒有break,則會繼續執行下麵的case直到結束 default也會執行
迴圈結構
while
語法:while(條件){迴圈語句}
#include <iostream>
#include <string>
using namespace std;
int main() {
int a = 1;
while (a < 10) {
cout << ++a << endl;
}
//一直迴圈到10結束
}
do..while
語法: do{迴圈語句} while(條件)
#include <iostream>
#include <string>
using namespace std;
int main() {
bool eat = false;
do {
cout << "吃個漢堡,還要吃嗎?"<< endl;
cin >> eat;
} while (eat);
/*
結果:
吃個漢堡,還要吃嗎?
1
吃個漢堡,還要吃嗎?
1
吃個漢堡,還要吃嗎?
0
程式結束
*/
}
for
語法:for(起始變數;迴圈條件;迴圈結束執行代碼){迴圈語句}
#include <iostream>
#include <string>
using namespace std;
int main() {
char my_name[] = "jame";
for (int i = 0; i < sizeof(my_name); i++)
{
cout << my_name[i] << endl;
}
/*
sizeof可以獲取到占用的記憶體大小,就是char的個數 一個char占一位元組 那麼sizeof(my_name)結果就是4
每次迴圈輸出具體下標的內容就可以完成遍歷了
結果:
j
a
m
e
*/
}
小練習:列印乘法表
#include <iostream>
#include <string>
using namespace std;
int main() {
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
cout << i << "*" << j << "=" << (i*j) << " ";
}
cout << "\n";
}
}
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
跳轉語句
語法: break
使用的時機:
- 在switch中,終止case並跳出switch
- 迴圈中跳出當前迴圈
上面的乘法表中使用
#include <iostream>
#include <string>
using namespace std;
int main() {
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
if (j == i)
{
break;
}
cout << i << "*" << j << "=" << (i*j) << " ";
}
cout << "\n";
}
}
2*1=2
3*1=3 3*2=6
4*1=4 4*2=8 4*3=12
5*1=5 5*2=10 5*3=15 5*4=20
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72
當i==j的時候直接跳出迴圈了,所以看不到1乘1,2乘2這樣類似的輸出
contiune
當在迴圈中出現contiune時,直接進行下次迴圈
#include <iostream>
#include <string>
using namespace std;
int main() {
for (int i = 1; i <= 9; i++)
{
if (i % 2 == 0)
{
continue;
}
cout << i;
}
}
//結果133579
goto
無條件跳轉
語法:goto 標記
如果標記的位置存在,則執行到goto時會直接跳轉到標記的位置
#include <iostream>
#include <string>
using namespace std;
int main() {
for (int i = 1; i <= 9; i++)
{
if (i == 8)
{
goto END;
}
cout << i;
}
END:
cout << "結束啦";
}
不光是往下麵跳,還能往上跳
#include <iostream>
#include <string>
using namespace std;
int main() {
int b = 0;
RESTART:
if (b > 0) {
cout << "b!" << endl;
}
for (int i = 1; i <= 9; i++)
{
if (i == 8 && b == 0)
{
b = 10;
goto RESTART;
}
cout << i ;
}
}
/*
結果
1234567b!
123456789
*/
使用goto向上面跳時一定要註意結束的判斷,避免死迴圈
數組
特點1:同個數組內的每個元素都相同類型的
特點2:數組是記憶體中一塊連續記憶體地址組成的
定義數組
int main() {
int a[10];
int b[10] = { 1,2,3 }; //如果標記長度為10,但是只初始化3個值,那麼剩下的預設值都是0
int c[] = { 1,2,3 };
}
三種定義數組的方式
訪問數組
int main() {
int a[10];
a[1] = 1;
a[2] = 100;
}
數組名用途
- 可以獲取整個數組在記憶體中的長度
- 可以獲取記憶體中數組的首地址
#include <iostream>
#include <string>
using namespace std;
int main() {
int a[10] = { 1,2,3 };
cout << "數組占用總大小" << sizeof(a) << endl;
cout << "每個元素占用大小" << sizeof(a[0]) << endl;
cout << "數組中有多少個元素" << sizeof(a)/sizeof(a[0]) << endl;
}
數組占用總大小40
每個元素占用大小4
數組中有多少個元素10
tips: 數組中有多少個元素 這裡使用a[0] 而不是其他a[1],a[2]...的原因 首先數組的特性1,每個元素都是相同類型的,也就是所有的元素大小都是一樣的,使用那個都可以
那麼也可以使用a[1],a[2]... 但是需要註意的是下標不能超過定義的最大長度
int main() {
int a[10] = { 1,2,3 };
cout << "數組首地址"<< a << endl;
cout << "數組第一個元素的首地址"<< &a[0] << endl;
}
tips: &在變數前是獲取元素的地址
二維數組
定義:
#include <iostream>
#include <string>
using namespace std;
int main() {
int a[3][3]; //聲明一個三行三列的數組
int b[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; //聲明三行三列,同時賦初始值
int c[3][3] = { 1,2,3,4,5,6,7,8,9 }; //聲明三行三列 同時全部賦值 三個為一行
int d[][3] = { 1,2,3,4,5,6 }; //聲明一個兩行三列 同時賦值
}
數組名稱
#include <iostream>
#include <string>
using namespace std;
int main() {
int b[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; //聲明三行三列,同時賦初始值
cout << "二維數組首地址:" << b << endl;
cout << "二維數組一行大小:" << sizeof(b[0]) << endl;
cout << "二維數組元素大小:" << sizeof(b[0][0]) << endl;
}
二維數組遍歷
#include <iostream>
#include <string>
using namespace std;
int main() {
int b[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; //聲明三行三列,同時賦初始值
for (int i = 0; i < (sizeof(b)/sizeof(b[0])); i++)
{
for (int j = 0; j < (sizeof(b[0])/sizeof(b[0][0])); j++)
{
cout << b[i][j];
}
}
}
函數(方法)
一個函數包含以下內容:
- 返回值類型
- 函數名稱
- 參數列表
- 函數體
- return
//返回值類型和函數名稱,參數為空
int main() {
//函數體
cout << "hello world";
//return值
return 0;
}
函數的調用
int sum(int number1, int number2) {
return number1 + number2;
}
int main() {
cout << sum(1,2);
return 0;
}
tips: C++和JAVA不一樣,被調用的函數必須在調用函數的方法前聲明
值傳遞
值傳遞是指當實參傳遞給形參後,當形參發生改變,實參並不會發生變化
int test(int number1) {
number1 += 1;
return 0 ;
}
int main() {
int a = 1;
test(a);
cout << a;
return 0;
}
當調用完test函數後a的值輸出還是1,或者我們輸出number1
和a
的地址,也會發現不同,說明test的參數只是值傳遞
int test(int number1)
{
number1 += 1;
cout << &number1 << endl;
return 0 ;
}
int main()
{
int a = 1;
test(a);
cout << &a<<endl;
return 0;
}
/*
000000FF976FF550
000000FF976FF574
*/
函數常見樣式
-
有參有返
int sum(int a,int b) { return a+b; }
-
有參無返
void print_number(int number) { cout << number; }
-
無參有返
int get_one() { return 1; }
-
無參無返
void print_hello(){ cout << "hello"; }
函數的聲明
在函數的開始篇有個tips 說使用的被調用的函數必須聲明在調用的函數前,而函數聲明就可以讓被調用的函數聲明在調用的函數之後
#include <iostream>
#include <string>
using namespace std;
int main() {
int a = 1;
print(a);
return 0;
}
void print(int a) {
cout << a;
}
我們這麼寫編譯是沒有問題,但是當運行起來後就會報錯:print找不到標識符
調換個位置就可以正常運行
void print(int a) {
cout << a;
}
int main() {
int a = 1;
print(a);
return 0;
}
而函數的聲明就是提前聲明我有這個函數
語法:返回類型 函數名(參數);
一個函數可以被聲明多次,但是只能定義一次
#include <iostream>
#include <string>
using namespace std;
void print(int a); //提前聲明存在print函數
int main() {
int a = 1;
print(a);
return 0;
}
void print(int a) {
cout << a;
}
函數分文件編寫
將相同功能的函數單獨放在一個文件中,使結構更加清晰
- 創建尾碼為
.h
的頭文件 - 創建尾碼為
.cpp
的源文件 - 在頭文件中寫函數聲明
- 在源文件中寫函數實現
myHead.h
#include <iostream>
using namespace std;
void print(int a);
myHead.cpp
#include "myHead.h";
void print(int a) {
cout << a;
}
主文件
#include "myHead.h";
int main() {
int a = 1;
print(a);
return 0;
}
我們在.h頭文件中引入了iostream
也使用了std
那麼只要導入myHead.h
文件的都可以使用
咋說呢,有點像java的介面?哈哈哈
指針
指針的作用:可以通過指針直接訪問記憶體
- 記憶體編號從0開始,一般為16進位數字表示
- 可以使用
指針變數
保存地址
指針的定義和使用
語法:數據類型* 變數名
int main() {
int a = 1;
int* a_pointer = &a;//將a的地址存放到指針中
*a_pointer = 100;//將100賦值給指針指向的地址中 指針前加*代表解引用 找到指針指向記憶體中的數據
cout << a << endl;
cout << "a的地址" << &a<<endl;
cout << "a指針的數據"<<a_pointer << endl;
}
指針占用的記憶體
int main() {
cout << sizeof(int *) << endl;
cout << sizeof(short *) << endl;
cout << sizeof(float *) << endl;
cout << sizeof(double *) << endl;
cout << sizeof(long *) << endl;
cout << sizeof(long long *) << endl;
}
32位中都是4位元組 64位中都是8位元組
空指針和野指針
空指針:指針變數指向記憶體中編號為0的空間
用途: 初始化指針
註意: 空指針的記憶體是不可訪問的
int main() {
int* a = NULL;
cout << *a << endl;
//*a = 100; 或者這段代碼
}
//都會報一個訪問許可權的異常
野指針:指針變數指向非法的記憶體空間
int main() {
int* a = (int*)0x10000; //(int * 強制轉換為指針類型)
*a = 100;
}
//也會報一個訪問許可權的異常
tips: 空指針和野指針都不是我們申請的空間,因此不要訪問
const修飾指針
const有三種情況
- 修飾指針:常量指針
- 修飾常量:指針常量
- 即修飾指針,又修飾常量
常量指針
int main() {
int a = 10;
int b = 20;
/*
* 常量指針
* 指針指向的值不可修改,但是可以修改指向
*/
const int* p = &a;
//*p = 10; 修改指向的值 錯誤
p = &b;//修改指向 可以
}
指針常量
int main() {
int a = 10;
int b = 20;
/*
* 指針常量
* 指針指向的值不可修改,但是可以修改指向
*/
int* const p = &a;
*p = 10; //修改指向的值 可以
//p = &b;//修改指向 錯誤
}
即修飾指針,又修飾常量
int main() {
int a = 10;
int b = 20;
/*
* 即修飾指針,也修飾常量
* 指針指向的值不可修改,但是可以修改指向
*/
const int* const p = &a;
//*p = 10; //修改指向的值 錯誤
//p = &b;//修改指向 錯誤
}
指針和數組
利用指針訪數組中的元素
int main() {
int a[5] = { 1,2,3,4,5 };
int* p = a;
cout << *p;
p++;
cout << *p;
}
tips: 指針類型++ 加的是sizeof(指針類型) 的值, int加4位元組正好是下個元素的地址 然後*p解引用取值也就是下個元素的值
指針和函數
利用指針作為函數的參數,從而修改實參的值,也就是常說的值傳遞和引用傳遞,而當使用指針作為參數傳遞時,就是引用傳遞
void add(int* num1) {
(*num1)++;
}
int main() {
int a = 10;
add(&a);
cout << a;
}
當執行完後a的值為11
tips: 括弧標明是先去獲取指針指向的值,然後自增1,如果不加可能以為是指針值++然後取值
指針數組和函數
小練習 冒泡
int* arr接收數組的地址,可以當做數組使用
void golugolu(int* arr ,int lenght)
{
for (int i = 0; i < lenght; i++)
{
for (int j = 0; j < lenght - i- 1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j]=arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
int a[5] = { 2,3,1,4,5 };
golugolu(a,5);
for (int i = 0; i < 5; i++)
{
cout << a[i];
}
}
結構體
結構體屬於用戶自定義的數據類型,允許用戶存儲不同的數據類型
語法: struct 結構體名 {結構體成員列表}
;
tpis:
註意! 結構體結束}後面需要加一個;結尾
通過結構體創建變數的方式有三種:
- struct 結構體名 變數名
- struct 結構體名 變數名={成員1值,成員2值}
- 定義結構體時同時設置變數
方式1
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
};
int main()
{
struct Student student; //struct可以省略
student.age = 10;
student.name = "張三";
student.score = 90;
cout << student.age << endl;
}
方式2
#include <iostream>
#include <string> //如果string類型報錯則導入該頭文件
using namespace std;
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
};
int main()
{
struct Student student = { "張三",90,18 }; //struct可以省略
cout << student.name << endl;
}
類似於有參構造,每個變數的順序就是在結構體中聲明的順序
方式3
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
} oldStudnet; //標明一個結構體
int main()
{
//可以使用上面兩種來進行填充數據
oldStudnet = { "we",1,1 };
oldStudnet.age = 199;
cout << oldStudnet.name << endl;
cout << oldStudnet.age << endl;
}
結構體數組
語法:struct 結構體名 數組名[個數]={{},{},{},...{}
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
};
int main()
{
struct Student arr[3] =
{
{"張三",1,1},
{"李四",2,2},
{"王五",3,3}
};
//整個數組長度除以每個元素長度獲取到多少個元素
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
//在迴圈中就可以將arr[i]當成具體的struct
arr[i].age = 10;
cout << arr[i].name;
}
}
結構體指針
語法: 可以通過->
來訪問結構體中的屬性
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
};
int main()
{
//創建結構體變數
struct Student studnet = { "張三",1,1 };
//創建指針變數,同時指向student變數
struct Student* p = &studnet;
//使用-> 操作符操作變數age
p->age = 100;
cout << p->age;
}
結構體嵌套結構體
struct Dog {
string name;
int age;
};
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
struct Dog dog;
};
int main()
{
struct Dog dog = { "旺財",4 };
//將dog設置到student中
struct Student student = { "小明",90,10,dog };
//先獲取學生的指針
struct Student* student_p = &student;
//之後通過指針在獲取到學生內部的狗的地址賦值給狗指針
struct Dog* dog_p = &student_p->dog;
//通過狗指針獲取狗age
cout << dog_p->age;
}
結構體做函數參數
有兩種:值傳遞和引用傳遞
struct Dog {
string name;
int age;
};
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
struct Dog dog;
};
//值傳遞
void set_value(struct Student s1) {
s1.age = 100;
s1.dog.age = 10;
}
//引用傳遞
void set_value2(struct Student* s1) {
//設置學生年齡
s1->age = 100;
//設置狗的年齡
s1->dog.age = 10;
//這種也可以,通過指針操作
//struct Dog* dog_p = &(s1->dog);
//dog_p->age = 10;
}
int main()
{
struct Dog dog = { "旺財",4 };
struct Student student = { "小明",90,18,dog };
set_value2(&student);
cout << student.dog.age << endl;
cout << student.age << endl;
}
結構體中使用const
struct Dog {
string name;
int age;
};
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
struct Dog dog;
};
struct Dog dog = { "旺財",4 };
void print(const struct Student* s) {
struct Student student = { "老明",90,18,dog };
s = &student;
//s->name = "2";報錯
cout << s->name;
}
int main()
{
struct Student student = { "小明",90,18,dog };
print(&student);
}
tpis: 形參接收struct 例如 void print(const struct Student* s)
你這個Student拼寫錯了是不會報錯的,需要註意拼寫,或者直接省略
struct
關鍵字
//定義結構體
struct Student
{
//聲明結構體中的成員
string name;
int score;
int age;
struct Dog dog;
};
struct Dog dog = { "旺財",4 };
void print(struct Student* const s) {
struct Student student = { "老明",90,18,dog };
//s = &student; 報錯
s->name = "王哈哈";
cout << s->name;
}
int main()
{
struct Student student = { "小明",90,18,dog };
print(&student);
}
結構體const和修飾普通的指針一樣
const struct Student* s
形參裡面的值不能改變 但是指向的地址可以改變
struct Student* const s
形參裡面值可以改變,但是指向不能改變
const struct Student* const s
兩個都不能變