C++基礎

来源:https://www.cnblogs.com/sunankang/archive/2022/10/23/16818151.html
-Advertisement-
Play Games

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;
}

運算符

  1. 算數運算符 處理四則運算
  2. 賦值運算符 將表達式賦值給變數
  3. 比較運算符 表達式的比較並返回一個bool值
  4. 邏輯運算符 用於根據表達式的值返回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;
	
}

數組名用途

  1. 可以獲取整個數組在記憶體中的長度
  2. 可以獲取記憶體中數組的首地址
#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];
		}
	}

}

函數(方法)

一個函數包含以下內容:

  1. 返回值類型
  2. 函數名稱
  3. 參數列表
  4. 函數體
  5. 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,或者我們輸出number1a的地址,也會發現不同,說明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;
}

函數分文件編寫

將相同功能的函數單獨放在一個文件中,使結構更加清晰

  1. 創建尾碼為.h 的頭文件
  2. 創建尾碼為.cpp的源文件
  3. 在頭文件中寫函數聲明
  4. 在源文件中寫函數實現

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有三種情況

  1. 修飾指針:常量指針
  2. 修飾常量:指針常量
  3. 即修飾指針,又修飾常量

常量指針

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: 註意! 結構體結束}後面需要加一個;結尾

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

  1. struct 結構體名 變數名
  2. struct 結構體名 變數名={成員1值,成員2值}
  3. 定義結構體時同時設置變數

方式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 兩個都不能變


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 正則表達式02 5.4正則表達式語法02 5.4.6捕獲分組 詳見5.3.3 例子 package li.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; //演示分組 public class RegEx ...
  • Lists,提供了很多api方便操作。例如:Lists.partition(List list,int size) Lists.partition(List list,int size)將list集合進行切割然後填充到一個List集合里。官方介紹 使用場景: 比如記憶體中有大量數據,需要迴圈調用某個方 ...
  • 緩存概述 解決不同設備間速度不匹配問題。 互聯網分層架構:降低資料庫壓力,提升系統整體性能,縮短訪問時間。 高併發問題 緩存併發(擊穿):緩存過期後將嘗試從後端資料庫獲取數據 緩存穿透:不存在的 key,請求直接落庫查詢 緩存雪崩:緩存大面積失效,請求直接落庫查詢 需求說明 通過在方法上增加緩存註解 ...
  • 文章配合圖文詳細的講解瞭如何在使用VSCode或者PHPStorm進行php的斷點調試。相關的配置內容,和需要的插件,一些要註意的點都有介紹到。說簡單挺簡單的,但是可能少了某一步就是斷點不了,讓人很頭疼。主要是瀏覽器插件可能沒裝,導致不能配合刷新瀏覽器進行斷點。希望這篇文章能對你配置php斷點能有所... ...
  • 1、依賴 <!-- swagger 核心 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependenc ...
  • 參考文檔 COM Coding Practices Audio File Format Specifications Core Audio APIs Loopback Recording #include <iostream> #include <fstream> #include <vector> ...
  • 抽象基類 ​ 現有如下代碼: class Abstract_base { public: virtual ~Abstract_base() = 0; virtual void interface() const = 0; virtual const char* mumble() const { re ...
  • 一、導入相關依賴 <dependencies> <!--文件上傳--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</versi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...