C++期末实践程序设计与数组作为参数的注意事项

目录

  • 小表弟发来的求助信号
  • 要点
  • 代码文件
    • 头文件Student.h
    • 源文件Student.cpp
    • main.c
    • 执行结果
  • c++数组特性以及数组做形参的特点
    • 数组试验
    • 数组特殊性质
      • 不允许拷贝和赋值
      • 数组是通常被转化成指针使用
    • 数组形参
  • 多种写法
    • 代理模式
    • MVC模式

小表弟发来的求助信号

在这里插入图片描述
并补充说要5种写法才算过关。

要点

先不说要几种写法,来说说这个实践的目的,也就是我们常常说的需求。
从题目本身说明是 面向对象程序设计 的考察;源文件和头文件分开,进一步说明是C++ 面向对象程序设计,同时也是C++程序设计的标准工程管理方式(头文件、源文件各自在一个文件中),只是在学习的时候往往一个文件将所有的代码放一个文件中。
类定义,实际上已经指明了类的属性以及需要具备的函数:
成绩要求用数组,是对数组的考察:

  1. 数组的初始、赋值、传递,别小看,容易掉坑里。
  2. 用自己的真实学号,就要求结合实际,可选用string或long类型
  3. 姓名已经明确是string,但对要求用中文其实是命题上的错误,不知道外国留学生是否都有一个中文姓名,唯一的提醒就是中文字符的编码问题,但仅仅在这个作业中还体现不了字符编码。
  4. const 自然是程序中要有用到const的地方
  5. 要求有构造函数,是对构造函数的考察
  6. 求平均数主要在于返回值和平均数的计算
  7. 打印学习成绩,和6一样,可以封装,分装的基础上再代理,后者以mvc的模式定义实体来实现,当然,这对于学生来说,可能稍显超标。

代码文件

不啰嗦了,先上个代码,不然看不到希望。

头文件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++语言中,指针和数组有非常紧密的联系。使用数组的时候编译器一般会把它转换成指针,通常情况下,使用取地址符来获取指向某个对象的指针,取地址符可以用于任何对象。
数组的元素也是对象,对数组使用下标运算符得到该数组指定位置的元素。再对该元素使用取地址符就能得到指向该元素的指针:

string nums[] = {"one", "two", "three"};  // 数组元素是string对象
string *p = &nums[0]; 
string *p1 = nums; 

在大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针

数组形参

因为不能拷贝数组,所以我们无法以 值传递 的方式使用数组参数。因为数组会被转换成指针,所以当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针。
虽然不能以值传递的方式传毒数组,但是可以把形参写成类似数组的形式:


//形式不同,但这三个print结果是等价的
//每个函数都有一个const int*类型的形参
void print(const int*);
void print(const int[]);
//这里的维度表示我们期望数组含有多少元素,实际不一定就是10
void print(const int[10]); 

所以,数组作为形参的函数也必须确保使用数组时不会越界。越界了之后自然就是不是我们预期的结果。

多种写法

前面的写法基于最朴实的面向对象和封装的思想。如果一定还要多种写法,那就变化一下。

代理模式

这种只是代理方式,因此只需要修改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

本文只是给出了模型示例,一般真实项目里面不会这么简单。学习课本可能很难理解后面这两种写法,就请先忽略吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558185.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sgm3157功能_SGM3157_SGM3157供应商_价格_Datasheet_pdf资料-IC资料网

SGM31574.5惟 Low Voltage SPDT Analog SwitchSGMICROSG Micro CorpLow Voltage SPDT Analog Switch in 6-Pin SC70SGMICROSG Micro Corp4.5惟 Low Voltage SPDT Analog SwitchSGMICROSG Micro CorpFLAT WASHERS NYLON FIBREetc2List of Unclassifed Manufacturers70 MHz Bandp…

windows 7远程桌面和被远程连接电脑启动远程桌面服务

目录远程桌面连接开启远程桌面服务&#xff08;被连电脑&#xff09;配置启动远程桌面服务远程桌面连接 这部分主要讲解如何通过一台windows 电脑的远程桌面程序连接"远程"电脑桌面。前提是被连的那台电脑已开启远程桌面服务。远程桌面服务开启之后&#xff0c;可以…

desktop docker 无法卸载_关于Docker:Docker – 无法移除死容器

我无法删除死容器&#xff0c;它在重新启动Docker服务后再次出现。docker ps -aCONTAINER ID STATUS11667ef16239 Dead然后docker rm -f 11667ef16239然后&#xff0c;当我运行docker ps -a时&#xff0c;没有Docker容器显示。docker ps -aCONTAINER ID …

git 命令详解和Android Studio代码管理工具

目录前言git命令上传项目一、核心操作二、解决冲突三、情景举例四、查看ssh密钥五、克隆远程项目六、回退某个操作七、和远程分支建立关联八、删除文件九、远程仓储十、多人协作十一、分支策略十二、其他Android Studio代码管理控制前言 相比SVN CVS的管理模式&#xff0c;git…

表单和字都居中_APP 分享 | 6 款黑科技工具,低调收藏,每一款都很强大!

iSlide 简单、高效地制作PPT使用环境: Windows使用要求: Office 2010 及以上版本授权状况: 无广告 有付费功能官网地址: www.islide.ccSlide是一款基于PowerPoint的插件工具,功能十分强大,高效做PPT必备利器一键优化:将PPT中不规则的字体,段落,色彩,参考线…

Android studio gradle task list 不显示问题

问题描述 新电脑安装android studio后&#xff0c;导入工程&#xff0c;各种配置都弄好变更好&#xff0c;出现了如下情况&#xff1a; 之前习惯的gradle task 不在列表中&#xff0c;好不习惯。 正常期望如下&#xff1a; 处理方法 快捷键Ctrl Alt S或者 file -> se…

python flask高级编程之restful_python Flask实现restful api service

一直在用node.js做后端&#xff0c;要逐步涉猎大数据范围&#xff0c;注定绕不过python&#xff0c;因此决定把一些成熟的东西用python来重写&#xff0c;一是开拓思路、通过比较来深入学习python&#xff1b;二是有目标&#xff0c;有动力&#xff0c;希望能持之以恒的坚持下去…

Android Studio Gradle输出信息乱码

在更换android studio 版本之后&#xff0c;一般windows 版本在项目构建过程中&#xff0c;gradle 相关的信息输出&#xff0c;会出现乱码&#xff0c;基本上明知是字符编码的问题&#xff0c;但看着就是不爽&#xff0c;例如下面这的情形&#xff1a; ע: ijЩ&#xfffd;&am…

python tkinter布局混用_python tkinter布局界面如何实现?

当我们自己走入一个互联网窗口里&#xff0c;寻找内容&#xff0c;清晰而明朗&#xff0c;这就是涉及了一个页面布局的知识&#xff0c;不只是一个站点&#xff0c;一个网页&#xff0c;设置是一个窗体都是有清晰的布局&#xff0c;语言的编写&#xff0c;就是为了效率执行而存…

Edge 修改字符编码(详细图文)

Microsoft Edge 版本 97.0.1072.62 (官方内部版本) (64 位) 前言 如下图&#xff0c;在访问页面时出现乱码&#xff0c;而且一直返回的内容编码是UTF-8&#xff0c;但Edge没找快捷的编码方式选择 方法一 Internet Explorer 模式加载 打开Edge浏览器 点击Edge右上角三点 点…

json tcl_确定TCL中变量的类型

Tcl的变量没有类型(除了他们是否真的变量的关联数组 - 即使用$foo(bar)语法 - FO r你使用array exists)但Tcl的值。好吧&#xff0c;有点。 Tcl可以在不同类型之间进行变异&#xff0c;因为它认为合适&#xff0c;并且不公开这些信息[*];你所能做的就是检查一个值是否符合特定的…

【Android】Unresolved reference: databinding

检查配置 对应module的build.gradle是否添加了databinding配置 buildFeatures {viewBinding true } // 或者 dataBinding {enabled true }检查包名(特别注意) 报错的包名是否和app包名一致。 例如app包名是 com.xxx.app 而报错的代码中binding的包名路径不在app包名下&…

水塔清洗机器人_最全的中央空调清洗流程

一、施工方案和技术措施项目总体施工纲要积极主动与客户沟通协调。做好现场的勘查工作&#xff1a;严密、详细、周全。掌握客户的动态&#xff0c;不断完善施工进度表。分项目制定严密的施工方案、计划和管理措施。制定详尽的突发事件应急预案。建立安全责任制&…

【Android】ConstraintLayout中RecyclerView 的底部数据显示不全以及覆盖其他View

文章目录xml布局内容预览画面(看着没毛病)&#xff1a;实际画面&#xff1a;解决办法说明xml布局内容 <?xml version"1.0" encoding"utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android"http://schemas.android.com/a…

python中forward的作用_基于numpy的前馈神经网络(feedforward neural network)

***这几天在上Andrew Ng教授开的Coursera系列课程Deep Learning&#xff0c;总觉得光是看视频和做作业还不够&#xff0c;还是得自己动手写写代码&#xff0c;亲自实现课程里提到的算法内容&#xff0c;于是便有了这篇博客&#xff0c;作为自己入门深度学习的里程碑吧。前馈神经…

Charles抓取HTTPS Windows Android iOS 图文详细

文章目录背景操作原理windows 安装CharlesCharles配置第一步&#xff1a;配置HTTP代理&#xff0c;这步与抓取HTTP请求是一样第二步&#xff1a;配置SSL代理第三步 &#xff1a;为手机配置代理iPhone 代理配置Android 代理配置第四步&#xff1a;安装根证书iPhone 安装charles证…

css线条伸缩_CSS3弹性伸缩布局之box布局

CSS3弹性伸缩布局简介2009年&#xff0c;W3C提出了一种崭新的方案----Flex布局(即弹性伸缩布局)&#xff0c;它可以简便、完整、响应式地实现各种页面布局&#xff0c;包括一直让人很头疼的垂直水平居中也变得很简单地就迎刃而解了。但是这个布局方式还处于W3C的草案阶段&#…

Android代码安装apk程序

文章目录一、高低版本兼容代码及配置1.java代码2.AndroidManifest.xml 配置ContentProvider3.paths xml 配置二、老版本代码三、可能出的问题及处理一、高低版本兼容代码及配置 高版本提高了sdcard、 app文件空间的访问权限&#xff0c;高低版本的系统api有一定区别&#xff0…

Android adb 安装apk程序

文章目录ADB简单介绍安装命令安装失败情况adb 安装测试包adb 安装卸载的所有命令摘要前言多数情况下&#xff0c;用户都是从应用商店或某网页下载apk后从手机上直接安装apk文件&#xff0c;在调试或下载到电脑上时候&#xff0c;我们就可以直接通过adb安装到手机。在测试小伙伴…

XML十六进制无效的字符(0x0b 0x0c 0x02)

文章目录解决方法ASCII“字符”1、ASCII 打印字符2、ASCII 非打印控制字符3、扩展 ASCII 打印字符4、ASCII 之外ASCII 字符输入方法与常用地方1、在文档中插入 ASCII 字符2、输入方法前言xml 中包含了非打印字符的情况下&#xff0c;即使是放在cdata 中&#xff0c;在不同平台上…