C++期末实践程序设计与数组作为参数的注意事项
目錄
- 小表弟發來的求助信號
- 要點
- 代碼文件
- 頭文件Student.h
- 源文件Student.cpp
- main.c
- 執行結果
- c++數組特性以及數組做形參的特點
- 數組試驗
- 數組特殊性質
- 不允許拷貝和賦值
- 數組是通常被轉化成指針使用
- 數組形參
- 多種寫法
- 代理模式
- MVC模式
小表弟發來的求助信號
并補充說要5種寫法才算過關。
要點
先不說要幾種寫法,來說說這個實踐的目的,也就是我們常常說的需求。
從題目本身說明是 面向對象程序設計 的考察;源文件和頭文件分開,進一步說明是C++ 面向對象程序設計,同時也是C++程序設計的標準工程管理方式(頭文件、源文件各自在一個文件中),只是在學習的時候往往一個文件將所有的代碼放一個文件中。
類定義,實際上已經指明了類的屬性以及需要具備的函數:
成績要求用數組,是對數組的考察:
代碼文件
不啰嗦了,先上個代碼,不然看不到希望。
頭文件Student.h
內容如下:
#ifndef STUDENT_H_ #define STUDENT_H_ #include <iostream> using namespace std; class Student{ private:string name;string no;float scores[3]={0,0,0}; public:Student(const string name,const string no,const float scores[3]);~Student();float Average();void SetName(const string name);void SetNo(const string no);void SetScore(const float scores[3]);void Print(); }; #endif源文件Student.cpp
內容如下:
#include <iostream> #include "Student.h" //不行的話,這里換成<Student.h> using namespace std;Student::Student(const string name,const string no,const float scores[3]) {this->name = name;this->no = no;SetScore(scores); };Student::~Student(){}; float Student::Average() {float total = 0;if(this->scores){for(int i = 0;i < 3;i++){total += scores[i];}}return total/3; };void Student::SetName(const string name) {this->name = name; };void Student::SetNo(const string no) {this->no = no; };void Student::SetScore(const float scores[3]) {for(int i = 0; i < 3 ; i++){this->scores[i] = *scores;scores++;} };void Student::Print() {cout<<"姓名:"<<name<<endl;cout<<"學號:"<<no<<endl;cout<<"成績"<<endl;cout<<"語文:"<<scores[0]<<endl;cout<<"數學:"<<scores[1]<<endl;cout<<"英語:"<<scores[2]<<endl;cout<<"平均成績:"<<Average()<<endl; };main.c
程序入口,根據需要調用
#include <iostream> #include "Student.h" //不行的話,這里換成<Student.h> using namespace std; int main() {float scores[] = {78,88,98};Student stu("john","8989898989",scores);stu.Print();return 0; }代碼在線測試
執行結果
$g++ -o main *.cpp
$main
姓名:john
學號:8989898989
成績
語文:78
數學:88
英語:98
平均成績:88
至此代碼可以拿走了。
c++數組特性以及數組做形參的特點
這里主要說明一下題目要求使用數組,實際上呢是對數組的一個特點、特性、指針做一個真實的鞏固。
數組試驗
#include<iostream> using namespace std;int GetSize(int data[]) {return sizeof(data);//特別注意這里 } int main() {int array[] = {1,2,3,4,5};int arraySize = sizeof(array);int *pointer = array;int pointerSzie = sizeof(pointer );int size = GetSize(array);cout<<"數組大小sizeof "<<arraySize <<" 指針sizeof "<<pointerSzie <<" 形參sizeof "<<size<<endl;return 0; }執行結果
$g++ -o main .cpp
main.cpp: In function ‘int GetSize(int)’:
main.cpp:5:23: warning: ‘sizeof’ on array function parameter ‘data’ will return size of ‘int*’ [-Wsizeof-array-argument]
return sizeof(data);//特別注意這里
^
main.cpp:4:22: note: declared here
int GetSize(int data[]) {
^
$main
數組大小sizeof 20 指針sizeof 8 形參sizeof 8
- 數組大小sizeof 20 指針sizeof 8 形參sizeof 8: 大小都是指字節(byte),其中一個int 占4個字節,數組一共5個元素,因此sizeof(array) 是20;
- int型的指針,是一個內存地址,內存地址一般與計算機系統有關,與 指向的類型沒有關系(例如 string *str ,str的sizeof也是8),如果是32位系統,內存尋址大小是4個字節(32bit),64位系統,內存尋址大小8個字節(64bit)。上面結果足以表明測試站點后端的執行系統是64位的,sizeof(pointer )是8;
- 剛好有個warning ‘data’ will return size of ‘int*’ [-Wsizeof-array-argument],說明 形參數組 將會作為對應類型的指針使用,是指針,sizeof自然就是8。
數組特殊性質
不允許拷貝和賦值
不能將數組的內容拷貝給其他數組作為其初始值,也不能用數組為其他數組賦值。
int a[] = {0,1,2}; // 含有三個整數的數組 int a2[] = a; // 錯誤:不允許使用一個數組初始化另一個數組 a2 = a;簡而言之就是數組之間不能用等號來做賦值操作
數組是通常被轉化成指針使用
在C++語言中,指針和數組有非常緊密的聯系。使用數組的時候編譯器一般會把它轉換成指針,通常情況下,使用取地址符來獲取指向某個對象的指針,取地址符可以用于任何對象。
數組的元素也是對象,對數組使用下標運算符得到該數組指定位置的元素。再對該元素使用取地址符就能得到指向該元素的指針:
在大多數表達式中,使用數組類型的對象其實是使用一個指向該數組首元素的指針 。
數組形參
因為不能拷貝數組,所以我們無法以 值傳遞 的方式使用數組參數。因為數組會被轉換成指針,所以當我們為函數傳遞一個數組時,實際上傳遞的是指向數組首元素的指針。
雖然不能以值傳遞的方式傳毒數組,但是可以把形參寫成類似數組的形式:
所以,數組作為形參的函數也必須確保使用數組時不會越界。越界了之后自然就是不是我們預期的結果。
多種寫法
前面的寫法基于最樸實的面向對象和封裝的思想。如果一定還要多種寫法,那就變化一下。
代理模式
這種只是代理方式,因此只需要修改main文件
#include <iostream> #include "Student.h" //不行的話,這里換成<Student.h> using namespace std;float average(Student *stu){return stu->Average(); }void print(Student * stu){stu->Print(); }int main() {float scores[] = {78,88,98};Student stu = Student("john","8989898989",scores);cout<<"平均成績:"<<average(&stu)<<endl;cout<<"打印:"<<endl;print(&stu);return 0; }輸出結果:
$g++ -o main *.cpp
$main
平均成績:88
打印:
姓名:john
學號:8989898989
成績
語文:78
數學:88
英語:98
平均成績88
納里,這有什么不一樣嗎,反而還多了兩個函數。是的就是多了兩個函數,在面向過程的思維前提下,這反而是增加了代碼量,但這在實際應用當中很有用,有多個Student的子類的話,這就體現出作用了。
MVC模式
這種模式下 Student 只定義屬性,并且有Get和Set函數。沒有Print 、Averager函數,這些函數是定義在類之外的,此處還是寫在main 之前,合理做法應該是另外再定義一個類。
Student頭文件
#include<iostream> using namespace std; class Student{ private:string name;string no;float scores[3]={0,0,0}; public:Student(const string name,const string no,const float scores[3]);~Student();void SetName(const string name);string GetName();void SetNo(const string no);string GetNo();void SetScore(const float scores[3]);float* GetScores() ;//float Average(); 此類不計算了//void Print(); 此類也不做打印 };Student源文件
#include<iostream> using namespace std; Student::Student(const string name,const string no,const float scores[3]){this->name = name;this->no = no;SetScore(scores); };Student::~Student(){ };void Student::SetName(const string name){this->name = name; };string Student::GetName(){return this->name; } void Student::SetNo(const string no){this->no = no; };string Student::GetNo(){return this->no; }float * Student::GetScores(){return scores; }void Student::SetScore(const float scores[3]) {for(int i = 0; i < 3 ; i++){this->scores[i] = *scores;scores++;} };main.cpp
#include <iostream> #include "Student.h" //不行的話,這里換成<Student.h> using namespace std;float average(Student *stu){return (stu->GetScores()[0]+stu->GetScores()[1]+stu->GetScores()[2])/3; };void print(Student * stu){cout<<"姓名:"<<stu->GetName()<<endl;cout<<"學號:"<<stu->GetNo()<<endl;cout<<"成績"<<endl;cout<<"語文:"<<stu->GetScores()[0]<<endl;cout<<"數學:"<<stu->GetScores()[1]<<endl;cout<<"英語:"<<stu->GetScores()[2]<<endl;cout<<"平均成績"<<average(stu)<<endl;};int main() {float scores[] = {78,88,98};Student stu = Student("john","8989898989",scores);cout<<"平均成績:"<<average(&stu)<<endl;cout<<"打印:"<<endl;print(&stu);return 0; }輸出結果:
$g++ -o main *.cpp
$main
平均成績:88
打印:
姓名:john
學號:8989898989
成績
語文:78
數學:88
英語:98
平均成績88
本文只是給出了模型示例,一般真實項目里面不會這么簡單。學習課本可能很難理解后面這兩種寫法,就請先忽略吧。
總結
以上是生活随笔為你收集整理的C++期末实践程序设计与数组作为参数的注意事项的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JDBC——编程式事务的实现逻辑
- 下一篇: python转换窗口无响应_Tkinte