c++基礎學習第三天(指針,結構體)
文章目錄
- 1、指針
- 1.1、指針的基本概念
- 1.2、指針變量的定義和使用
- 1.3、 指針所占內存空間
- 1.4、空指針和野指針
- 1.5、 const修飾指針
- 1.5.1、const修飾指針-常量指針
- 1.5.2、const修飾常量-指針常量
- 1.5.3、const即修飾指針,又修飾常量
- 2、結構體
- 2.1、結構體基本概念
- 2.2、結構體定義和使用
- 2.3、結構體數組
- 2.4、結構體指針
- 2.5、結構體嵌套結構體
- 2.6、結構體做函數參數
- 2.7、結構體中const使用場景
1、指針
1.1、指針的基本概念
指針的作用:可以通過指針間接訪問內存
- 內存編號是從0開始記錄的,一般用十六進制數字表示
- 可以利用指針變量保存地址
1.2、指針變量的定義和使用
指針變量定義語法:*數據類型 變量名;
//1、定義指針
int a1 = 10;
// 指針定義的語法:數據類型 * 指針變量名:
int *p;
// 讓指針記錄變量a的地址
p = &a1;
cout << "a的地址為:" << &a1 << endl;
cout << "指針p為:" << p << endl;
//2、使用指針
//可以通過解引用的方式來找到指針指向的內存,查看內存內容。
//指針前加 * 代表解引用,找到指針指向的內存中的數據
*p = 1000;
cout << "a1 = " << a1 << endl;
cout << "*p=" << *p << endl;
1.3、 指針所占內存空間
提問:指針也是種數據類型,那么這種數據類型占用多少內存空間?
在32位操作系統下:占用4個字節空間,64位下占8個字節。不管是什么數據類型
//指針所占內存空間
int a2 = 10;
//int p;
//p=&a:
int *p1 = &a2;
//在32位操作系統下,指針是占4個字節空間大小,***不管是什么數據類型***
//在64位操作系統下,指針是占8個字節空間大小
cout << "sizeof(int*)=" << sizeof(int*) << endl;
cout << "sizeof (float*)=" << sizeof(float*) << endl;
cout << "sizeof (double*)=" << sizeof(double*) << endl;
cout << "sizeof(char*)="<< sizeof(char*) << endl;
1.4、空指針和野指針
空指針:指針變量指向內存中編號為0的空間
用途:初始化指針變量
注意:空指針指向的內存是不可以訪問的
空指針
//1、空指針用于給指針變量進行初始化
int *p4 = NULL;
// 2、空指針(0號內存空間)是不可以進行訪問的
//0~255之間的內存編號是系統占用的,因此不可以訪問
//*p = 100;
野指針:指針變量指向非法的內存空間(不是自己申請的內存空間)
/野指針
//在程序中,盡量避免出現野指針
int *p = (int*)0x1100;
cout << * p << endl;
總結:空指針和野指針都不是我們申請的空間,因此不要訪問。
1.5、 const修飾指針
const修飾指針有三種情況:
1.5.1、const修飾指針-常量指針
const int *p=&a:
常量指針
特點:指針的指向可以修改,但是指針指向的值不可以改
*p=20;錯誤,指針指向的值不可以改
p=&b;正確,指針指向可以改
1.5.2、const修飾常量-指針常量
int * const p=&a:
指針常量
特點:指針的指向不可以改,指針指向的值可以改
*p=20;正確,指向的值可以改
p=&b;錯誤,指針指句不可以改
1.5.3、const即修飾指針,又修飾常量
const int * const p =a;
特點:指針的指向和指針指向的值都不可以改
*p=20;/錯誤
p=&b;/錯誤
//1、const修飾指針 常量(const)指針(*)
int a4 = 10;
int b4 = 10;
const int * p7 = &a4;
//指針指向的值(*P)不可以改,指針的指向(p)可以改
//*p=20:錯誤
p7 = &b4;//正確//2、const修飾常量 指針(*)常量(const)
//指針的指向(p2)不可以改,指針指向的值(*p2)可以改
int * const p5 = &a4;
*p5 = 100; // 正確的
//p2=&b:/錯誤,指針的指向不可以改// 3、const修飾指針和常量
const int * const p6 = &a4;
//指針的指向和指針指向的值都不可以改
//*p3=100;//錯誤
//b3 = &b; //錯誤
2、結構體
2.1、結構體基本概念
結構體屬于用戶自定義的數據類型,允許用戶存儲不同的數據類型
2.2、結構體定義和使用
語法:struct 結構體名 {結構體成員列表};
通過結構體創建變最的方式有三種:
- struct 結構體名 變量名
- struct 結構體名 變量名={成員1值,成員2值…}
- 定義結構體時便創建變星
通過學生類型創建具體學生
//2.1 struct Student sl
struct Student s1;
//給s1屬性賦值,通過.訪問結構體變量中的屬性
s1.name = "張三";
s1.age = 18;
s1.score = 100;
cout << "姓名:" << s1.name << " 年齡:" << s1.age << " 分數:" << s1.score << endl;
//2.2 struct Student s2 ={..};
struct Student s2 = { "李四",19,80 };
cout << "姓名:" << s2.name << " 年齡:" << s2.age << " 分數:" << s2.score << endl;
//2.3在定義結構體時順便創建結構體變量
struct Student1 {//成員列表// 姓名string name;// 年齡int age;//分數int score;
}s3;s3.name = "王五";
s3.age = 20;
s3.score = 60;
cout << "姓名:" << s3.name << " 年齡:" << s3.age << " 分數:" << s3.score << endl;
struct關鍵字可以省略(創建變量時),定義時struct關鍵字不可以省略。
總結1:定義結構體時的關鍵字是struct,不可省略
總結2:創建結構體變是時,關鍵字structi可以省略
總結3:結構體變量利用操作符"."訪門成員
2.3、結構體數組
作用:將自定義的結構體放入到數組中方便維護
語法:struct 結構體名 數組名[元素個數]={{},{},·{}};
//1、創建結構體數組
struct Student stuArray[3]{{"張三",18,100},{"李四",28, 99},{ "王五",38,66}
};
// 2、給結構體數組中的元素賦值
stuArray[2].name = "趙六";
stuArray[2].age = 80;
stuArray[2].score = 60;
// 3、遍歷結構體數組
for (int i = 0; i < 3; i++) {cout<< "姓名:"<<stuArray[i].name<<"年齡:"<<stuArray[i].age<< "分數:"<< stuArray[i].score<< endl;
}
2.4、結構體指針
作用:通過指針訪問結構體中的成員
利用操作符->可以通過結構體指針訪問結構體屬性
//1、創建學生結構體變量
struct Student s = { "張三",18,100};
//2、通過指針指向結構體變量
struct Student *p =&s;
//3、通過指針訪問結構體變量中的數據
cout << "姓名:" << p->name << "年齡:" << p->age << "分數:" << p->score << endl;
2.5、結構體嵌套結構體
作用:結構體中的成員可以是另一個結構體
例如:每個老師輔導一個學員,一個老師的結構體中,記錄一個學生的結構體
//定義學生結構體
struct student{string name; // 姓名int age;//年齡int score; // 分數
};//定義老師結構體
struct teacher {int id;//教師編號string name; // 教師姓名int age;//年齡struct student stu;//輔導的學生
};//結構體嵌套結構體
//創建老師
struct teacher t;
t.id = 10000;
t.name = "老王";
t.age = 50;
t.stu.name = "小王";
t.stu.age = 20;
t.stu.score = 60;
cout << "老師姓名:" << t.name << "老師編號:" << t.id << "老師年齡:" << t.age<< "老師輔導的學生姓名:" << t.stu.name << "學生年齡:" << t.stu.age<< "學生考試分數為:" << t.stu.score<<endl;
2.6、結構體做函數參數
作用:將結構體作為參數向函數中傳遞
傳遞方式有兩種:
- 值傳遞
- 地址傳遞
總結:如果不想修改主函數中的數據,用值傳遞反之用地址傳遞
2.7、結構體中const使用場景
作用:用const來防止誤操作
將函數中的形參改為指針,可以減少內存空間,而且不會復制新的副本出來
void printStudents(const student *s)防止函數修改屬性值
指針(地址傳遞)節省空間,值傳遞會復制一份給函數內的變量。