1. 程式人生 > 實用技巧 >2020.12.c++基礎

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