2020.12.c++基礎
c++筆記
一.運算子
1.三目運算子
- c=a>b?a:b ---------->如果a大 c=a;否則c=b
- a>b?a:b =100 ---------->如果a大 a=100;否則b=100
2.求餘以及除號的運用
一個三位數如(153),要求獲取它的個位數、十位數、百位數
- 個位:153%10=3
- 十位:153/10=15 15%10=5
- 百位:153/100=1
二.選擇語句
1.if 和switch語句的區別
- switch語句裡面的判斷只能是整型或者是字元型,不可以是一個區間。需要用到break
三.迴圈語句
1.while()與do....while()
- 格式 while(){.....}------->先執行再判斷
- 格式do{.....}while();------->先判斷再執行
2.break與continue
- break;跳出迴圈
- continue;跳出這次迴圈------>可以與if連用,進行篩選條件迴圈
四.陣列
1.格式與初始化
-
資料型別 陣列名[陣列長度];------------>自己手動賦值
-
資料型別 陣列名[陣列長度]={值1,值2......};----------------->沒有賦值完的,預設初始化填充為0
-
資料型別 陣列名[]={值1,值2......};------------------>長度由後面的值的多少決定
-
注意:定義陣列時,必須要有初始長度
2.一維陣列名稱的作用一:陣列的記憶體空間
- sizof(陣列名);------->整個陣列在記憶體空間的長度---->多少位元組
- sizof(陣列名[0]);------->某一個元素所佔的記憶體空間
- sizof(陣列名)/sizof(陣列名[0]);--------->陣列中元素的個數
- sizeof------->用來統計一個數據型別的記憶體空間的大小
- 注意:byte--1位元組,short---2位元組,int 型別所佔的記憶體空間是4位元組,long---8位元組,float--4位元組,double--8位元組,char--2位元組,boolean--1位
3.一維陣列名稱的作用二:檢視陣列首地址
- cout<<陣列名;----------->列印陣列的首地址
- &陣列名[0];------>陣列第一個元素的地址
- 注意:陣列的首地址就是陣列第一個元素的地址
- 注意:陣列名是一個常量,不可以進行賦值操作
4.找陣列的最大值
- 定義一個max=0;----->與陣列中的元素依次進行比較
5.陣列逆置
- 記錄起始位置的下標和末位的下標
- 兩個下標互換
- 起始下標++,末尾下標--
- 迴圈條件:Start<end
6.二維陣列
-
陣列名[行數] [列數];
-
陣列名[行數] [列數]={{}, {}, .....};
-
陣列名[行數] [列數]={1,2,3,4,5,6};
-
陣列名[ ] [列數]={1,2,3,4,5,6};
注意:可以省去行數但是不能省去列數
7.二維陣列名稱的作用一:陣列的記憶體空間
- sizeof(陣列名)------>二維陣列佔用記憶體空間
- sizeof(陣列名[0])------>二維陣列第一行佔用的記憶體
- sizeof(陣列名[0] [0])---->二維陣列第一個元素佔用記憶體
- sizeof(陣列名)/sizeof(陣列名[0])---->二維陣列的行數
- sizeof(陣列名[0])/sizeof(陣列名[0] [0])----->二維陣列的列數
8.一維陣列名稱的作用二:陣列的首地址
- cout<<陣列名;----->陣列的首地址
- cout<<陣列名[0];------>二維陣列第一行的首地址
- cout<<&陣列名[0] [0];----->二維陣列第一個元素的地址
- 注意:三種地址都一樣
五.函式
1.函式的定義
返回值型別 函式名(引數列表){
//引數列表----->需要傳入的東西
....
函式體語句;
....
return 表示式;
}
注意1:如果不需要返回值,則返回值型別為void,此時可以不用寫return +返回值;或者只寫return;
注意2:定義函式時,這裡的引數列表中的引數,是沒有真實資料的,是形式引數
2.函式的呼叫
函式名(引數);
注意:這裡的引數是實參,當呼叫函式時 ,實參的值會傳遞給形參
3.值傳遞
所謂的值傳遞就是:實參的值會傳遞給形參
當呼叫函式時,實參的值傳給形參,形參改變,但是原先的實參是不變的------->形參無法改變實參
4.常見的函式樣式
-
無參無返------->常用來列印
-
有參無返-------->用來列印這個引數
-
無參有返---------->呼叫函式時得到的就是這個返回值
int test(){
....
return 1000;
}
-
有參有返,可以返回這個引數,return 引數;
5.函式的宣告
- 函式的宣告可以多次,但是函式的定義只能有一次
- 函式的宣告的格式:返回值型別 函式名(引數列表);
- 函式宣告的作用,告訴執行程式自己要呼叫這個函式,如果main函式寫在前,防止無法識別。
6.函式的分檔案編寫
函式分檔案編寫的主要步驟
- 1)建立.h字尾名的標頭檔案
需要加#include <iostream.h>
using namespace std;
這是框架。
-
2)建立.cpp字尾的原始檔
需要加#include “標頭檔案名”
-
3)在標頭檔案中寫函式的宣告
-
4)在原始檔中寫函式的定義
-
5)在運用時,就include這個函式的標頭檔案就好了
7.有特點的的函式:獲取隨機數
rand()函式得到0~32767之間的隨機數
rand()%100得到0~99之間的隨機數
rand()%100+1得到1~100之間的隨機數
注意:可以新增隨機數種子,利用當前系統的時間生成隨機數,防止每次生成的隨機數是一樣的
# include <ctime>//時間系統標頭檔案
srand((unsigned int)time(NULL));
六.指標
1.定義指標
- 指標定義的語法:
資料型別 *指標變數名
eg: int *p;
int a=10;
p=&a;
指標p就是a的地址
2.使用指標
可以通過解引用的方式找到指標所指向的記憶體
指標前面加*代表解引用,找到指標指向記憶體的資料
eg: *p=1000; //修改了指標所指的內容
3.指標所佔的記憶體空間
-
在32位作業系統下,佔用4位元組
-
在64位作業系統下,佔用8位元組
eg: int * p=&a;
*int 是指標的資料型別
cout<<sizeof(int *);與cout<<sizeof(p);等價
-
**不管是什麼資料型別的指標都遵循上述規律,float 、int 、double * 都是一樣的資料空間
4.空指標
-
int *p;-------->指標變數p指向的記憶體空間的編號為0的空間 也可寫做 int *p =NULL;
-
空指標是不能進行訪問的
要是後續程式碼中 未給指標初始化 而出現了 *p=100;或者列印 *p 的操作,都是不行的,因為記憶體編號從0~255為系統佔用的記憶體,不允許使用者訪問
5.野指標
-
避免使用 如 int *p=(int *)0x1100;
將數字轉換成指標型別(地址)然後賦給指標,當你利用解引用*p時,是沒有許可權訪問該內容的。
6.const 修飾指標的三張情況
- 1)const 修飾指標------->常量指標
const int * p=&a;
或者
int const * p=&a;
特點:指標的指向可以修改,但是指標的值不可以修改
原因:const修飾的是*p,是一個值
- 2)const 修飾常量------->指標常量
int* const p=&a;//指標常量
特點:指標的指向不可以修改,但是指標的值可以修改
原因:const修飾的是p,是一個指標
- 3)const 即修飾指標,也修飾常量
const int * const p=&a;
特點:指標的指向不可以修改,但是指標的值也不可以修改
怎麼讀:看定義式,const為常量,*為指標
7.指標和陣列
陣列名就是指標的首地址
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int *p=arr;//arr就是陣列的首地址
cout<<*P<<endl;//列印首地址的元素
p++;//指標偏移四個位元組,因為int*是4位元組的記憶體空間
cout<<*P<<endl;//列印下一地址的元素
8.指標和函式(值傳遞和地址傳遞)
- 1)值傳遞(見上面五.3的內容)-------->形參不可以修飾實參
- 2)地址傳遞----->形參可以修飾實參
#include <iostream>;
using namespace std;
void swap(int m,int n) {
int temp = m;
m = n;
n = temp;
cout << "swap:a =" << m << endl;
cout << "swap:b =" << n << endl;
}
void swap2 (int* m, int* n) {
int temp = *m;
*m = *n;
*n = temp;
cout << "swap2:a =" << *m << endl;
cout << "swap2:b =" << *n << endl;
}
int main() {
int a = 10;
int b = 20;
//swap(a,b)
swap2(&a, &b);
cout<<"a ="<< a<<endl;
cout<<"b ="<< b<<endl;
}
/*
結果(使用swap(a,b)):
swap:a =20
swap:b =10
a =10
b =20
結果(使用swap2(&a,&b)):
swap2:a =20
swap2:b =10
a =20
b =10
*/
總結:如果不想修改實參,就用值傳遞;如果想修改實參,就用地址傳遞;
9.指標和陣列和函式
#include <iostream>;
using namespace std;
void bubbleSort(int *arr,int length) {
for (int i = 0; i < length-1; i++) {
for (int j = 0; j < length - 1 - i; j++) {
if (arr[j] < arr[j + 1]) {
int temp = arr[j+1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
}
void printArray(int *arr,int length) {
for (int i = 0; i < length; i++) {
cout << arr[i]<<endl;
}
}
int main() {
int arr[10] = { 5,6,3,4,2,10,9,1,8,7};
int len = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr,len);
printArray(arr, len);
}
/*
結果:
10
9
8
7
6
5
4
3
2
1
*/
七.結構體
1.結構體的基本概念
結構體屬於使用者自定義的資料型別,允許使用者儲存不同資料型別
2.結構體的定義和使用
1)結構體定義語法:struct 結構體名{結構體成員列表};
2)建立結構體的一個變數
- struct 結構體名 變數名
- struct 結構體名 變數名={成員1值,成員2值...}
- 定義結構體時順便建立變數
//struct結構體的使用
#include <iostream>;
#include <String>;
using namespace std;
struct Student {
string name;
int age;
float score;
}s3;
int main() {
//通過學生類建立一個具體的學生
//方法一
struct Student s1;
s1.name = "aaa";
s1.age = 10;
s1.score = 99;
//方法二
struct Student s2{"bbb",11,89 };
//方法三:直接在構造體後建立
s3.name = "ccc";
s3.age = 9;
s3.score = 95;
cout << s1.age << s1.name << s1.score << endl;
cout << s2.age << s2.name << s2.score << endl;
cout << s3.age << s3.name << s3.score << endl;
}
/*結果:
10aaa99
11bbb89
9ccc95
*/
定義結構體時的關鍵字是struct,不可省略
建立結構體時的關鍵字是struct,可以省略
3.結構體陣列
1)作用:將自定義的結構體放入到陣列中方便維護
2)語法:struct 結構體名 陣列名[元素個數]={{},{},......{}}
//結構體陣列
#include <String>;
#include <iostream>
using namespace std;
struct Student {
string name;
int age;
float score;
};
int main() {
//建立結構體陣列,並賦值
struct Student studentArray[3]
{
{ "aaa",10,99},
{ "bbb",11,89},
{ "ccc",9,95}
};
//給結構體陣列中的元素賦值
studentArray[2].age = 20;
studentArray[2].name ="ddd" ;
studentArray[2].score =100;
//遍歷元素
for (int i = 0; i <= 2; i++) {
cout << studentArray[i].age
<< studentArray[i].name
<< studentArray[i].score<<endl;
}
}
/*
結果:
10aaa99
11bbb89
20ddd100
*/
4.結構體指標
//結構體指標
#include <String>;
#include <iostream>
using namespace std;
struct Student {
string name;
int age;
float score;
};
int main() {
//1.建立結構體變數(struct可以省略)
struct Student s1 = { "aaa",10,99 };
//2.通過指標指向結構體變數(struct可以省略)
struct Student* p = &s1;
//3.通過指標訪問結構體變數的資料
//通過結構體指標 訪問的結構體的屬性,需要利用“->”符號
cout << p->age << p->name << p->score << endl;
}
/*
結果:10aaa99
*/
5.結構體巢狀另外一個結構體
在結構體中可以定義另外一個結構體作為成員,(被巢狀的也就是另一個)結構體需要定義在前
//結構體巢狀結構體
#include <String>;
#include <iostream>
using namespace std;
struct Student {
string name;
int age;
float score;
};
//新定義一個結構體用來巢狀上面的結構體成員
struct Teacher {
string name;
int age;
struct Student s1;//子結構體中的學生s1
//此處的struct 可以省略(建立一個子結構體的成員)
};
int main() {
struct Teacher t1;
t1.age = 30;
t1.name = "hhh";
t1.s1.age = 10;
t1.s1.name ="aaa" ;
t1.s1.score=99;
cout << "老師姓名: " << t1.name << endl;
cout<<"老師年齡: " << t1.age << endl;
cout << "輔導學生姓名: " << t1.s1.name << endl;
cout << "輔導學生年齡: " << t1.s1.age << endl;
cout<<"輔導學生成績: "<<t1.s1.score<< endl;
}
/*結果:
老師姓名: hhh
老師年齡: 30
輔導學生姓名: aaa
輔導學生年齡: 10
輔導學生成績: 99
*/
6.結構體作為函式引數(值/地址傳遞)
結論同上:如果不想修改實參,就用值傳遞;如果想修改實參,就用地址傳遞;
//結構體作為函式引數(值傳遞/地址傳遞)
#include <String>;
#include <iostream>
using namespace std;
struct Student {
string name;
int age;
float score;
};
void printStudent1(struct Student s) {
s.age = 100;
cout <<"printStudent1值傳遞下形式引數:"<< s.age << s.name << s.score << endl;
}
void printStudent2(struct Student* p) {
p->age = 200;
cout << "printStudent2地址傳遞下形式引數:" << p->age << p->name << p->score << endl;
}
//!!!要求:結構體作為函式引數,將創建出來的成員作為函式的引數
//實現列印這個成員的屬性的函式
int main() {
struct Student s1 = { "aaa",10,99 };
printStudent1(s1);
//printStudent2(&s1);
cout << "main函式下實際引數:" << s1.age << s1.name << s1.score << endl;
}
/*結果:使用printStudent1(struct Student s) 值傳遞
printStudent1值傳遞下形式引數:100aaa99
main函式下實際引數:10aaa99
結果:使用printStudent2(struct Student s)地址傳遞
printStudent2地址傳遞下形式引數:200aaa99
main函式下實際引數:200aaa99
*/
注意1:當結構體作為函式引數時,常使用的形式引數是指標。原因是指標的記憶體空間是4位元組,可以節省記憶體空間,而且不會複製出全部的資訊出來
注意2:但是使用指標作為形式引數,是地址傳遞,為了防止 誤操作(修改形參的值)常運用const----> const Student * s
7.結構體例題排序
//設計一個英雄結構體,包括姓名,年齡和性別。
//建立結構體陣列,陣列中存放5名英雄
//通過氣泡排序演算法,按照年齡進行排序,最終列印結果
#include <String>;
#include <iostream>
using namespace std;
struct Hero {
string name;
int age;
string sex;
};
void Bubblesort(struct Hero heroArray[],int length){
for (int i = 0; i < length - 1; i++) {
for(int j=0;j<length-j-1;j++)
if (heroArray[j].age> heroArray[j + 1].age) {
Hero temp = heroArray[j];
heroArray[j ] = heroArray[j+1];
heroArray[j+1] = temp;
}
}
}
void Printfarray(Hero heroArray[], int length) {
for (int i = 0; i < length; i++)
{
cout << "姓名:" << heroArray[i].name << " 年齡: " << heroArray[i].age
<< " 性別: " << heroArray[i].sex << endl;
}
}
int main() {
//建立結構體陣列
struct Hero heroArray[5]{
{"aaa",15,"男"},
{"bbb",10,"女"},
{"ccc",5,"男"},
{"ddd",20,"男"},
{"eee",25,"女"},
};
int len = sizeof(heroArray) / sizeof(heroArray[0]);
Bubblesort(heroArray, len);//這裡的heroArray是陣列的首地址
Printfarray(heroArray, len);
}