C++ 高级数据类型(五)—— 数据结构

一个数据结构是组合到同一定义下的一组不同类型的数据,各个数据类型的长度可能不同。它的形式是:

struct model_name {
type1 element1;
type2 element2;
type3 element3;
.
.
} object_name;

这里model_name 是一个这个结构类型的模块名称。object_name 为可选参数,是一个或多个具体结构对象的标识。在花括号{ }内是组成这一结构的各个元素的类型和子标识。

如果结构的定义包括参数model_name (可选),该参数即成为一个与该结构等价的有效的类型名称。例如:

struct products {
char name [30];
float price;
};
products apple; 
products orange, melon;

我们首先定义了结构模块products,它包含两个域:name 和 price,每一个域是不同的数据类型。然后我们用这个结构类型的名称 (products) 来声明了 3个该类型的对象:apple, orange 和melon。

一旦被定义,products就成为一个新的有效数据类型名称,可以像其他基本数据类型,如int, char或 short 一样,被用来声明该数据类型的对象(object)变量。

在结构定义的结尾可以加可选项object_name ,它的作用是直接声明该结构类型的对象。例如,我们也可以这样声明结构对象apple, orange和melon:

struct products {
char name [30];
float price;
}apple, orange, melon;

并且,像上面的例子中如果我们在定义结构的同时声明结构的对象,参数model_name (这个例子中的products)将变为可选项。但是如果没有model_name,我们将不能在后面的程序中用它来声明更多此类结构的对象。

清楚地区分结构模型model和它的对象的概念是很重要的。参考我们对变量所使用的术语,模型model 是一个类型type,而对象object 是变量variable。我们可以从同一个模型model (type)实例化出很多对象objects (variables)。

在我们声明了确定结构模型的3个对象(apple, orange 和 melon)之后,我们就可以对它们的各个域(field)进行操作,这通过在对象名和域名之间插入符号点(.)来实现。例如,我们可以像使用一般的标准变量一样对下面的元素进行操作:

apple.name
apple.price
orange.name
orange.price
melon.name
melon.price

它们每一个都有对应的数据类型:apple.name, orange.name 和melon.name 是字符数组类型char[30],而apple.price, orange.price 和 melon.price 是浮点型float。

下面我们看另一个关于电影的例子:

// example about structures
#include ‹iostream.h›
#include ‹string.h›
#include ‹stdlib.h›

struct movies_t {
char title [50];
int year;
}mine, yours;

void printmovie (movies_t movie);

int main () {
char buffer [50];
strcpy (mine.title, "2001 A Space Odyssey");
mine.year = 1968;
cout << "Enter title: ";
cin.getline (yours.title,50);
cout << "Enter year: ";
cin.getline (buffer,50);
yours.year = atoi (buffer);
cout << "My favourite movie is:\n ";
printmovie (mine);
cout << "And yours:\n";
printmovie (yours);
return 0;
}

void printmovie (movies_t movie) {
cout << movie.title;
cout << " (" << movie.year << ")\n";
}
Enter title: Alien
Enter year: 1979
My favourite movie is:
2001 A Space Odyssey (1968)
And yours:
Alien (1979)

这个例子中我们可以看到如何像使用普通变量一样使用一个结构的元素及其本身。例如,yours.year 是一个整型数据int,而 mine.title 是一个长度为50的字符数组。

注意这里 mine 和 yours 也是变量,他们是movies_t 类型的变量,被传递给函数printmovie()。因此,结构的重要优点之一就是我们既可以单独引用它的元素,也可以引用整个结构数据块。

结构经常被用来建立数据库,特别是当我们考虑结构数组的时候。

// array of structures
#include ‹iostream.h›
#include ‹stdlib.h›

#define N_MOVIES 5

struct movies_t {
char title [50];
int year;
} films [N_MOVIES];

void printmovie (movies_t movie);

int main () {
char buffer [50];
int n;
for (n=0; n<N_MOVIES; n++) {
cout << "Enter title: ";
cin.getline (films[n].title,50);
cout << "Enter year: ";
cin.getline (buffer,50);
films[n].year = atoi (buffer);
}

cout << "\nYou have entered these movies:\n";
for (n=0; n<N_MOVIES; n++) {
printmovie (films[n]);
return 0;
}

void printmovie (movies_t movie) {
cout << movie.title;
cout << " (" << movie.year << ")\n";
}
Enter title: Alien
Enter year: 1979
Enter title: Blade Runner
Enter year: 1982
Enter title: Matrix
Enter year: 1999
Enter title: Rear Window
Enter year: 1954
Enter title: Taxi Driver
Enter year: 1975

You have entered these movies:
Alien (1979)
Blade Runner (1982)
Matrix (1999)
Rear Window (1954)
Taxi Driver (1975)

结构指针(Pointers to structures)

就像其它数据类型一样,结构也可以有指针。其规则同其它基本数据类型一样:指针必须被声明为一个指向结构的指针:

struct movies_t {
char title [50];
int year;
};
movies_t amovie;
movies_t * pmovie;

这里 amovie 是一个结构类型movies_t 的对象,而pmovie 是一个指向结构类型movies_t 的对象的指针。所以,同基本数据类型一样,以下表达式正确的:

pmovie = &amovie;

下面让我们看另一个例子,它将引入一种新的操作符:

// pointers to structures
#include ‹iostream.h›
#include ‹stdlib.h›

struct movies_t {
char title [50];
int year;
};

int main () {
char buffer[50];

movies_t amovie;
movies_t * pmovie;
pmovie = & amovie;

cout << "Enter title: ";
cin.getline (pmovie->title,50);
cout << "Enter year: ";

cin.getline (buffer,50);
pmovie->year = atoi (buffer);

cout << "\nYou have entered:\n";
cout << pmovie->title;
cout << " (" << pmovie->year << ")\n";

return 0;
}
Enter title: Matrix
Enter year: 1999

You have entered:
Matrix (1999)

上面的代码中引入了一个重要的操作符:->。这是一个引用操作符,常与结构或类的指针一起使用,以便引用其中的成员元素,这样就避免使用很多括号。例如,我们用:

pmovie->title

来代替:

(*pmovie).title

以上两种表达式pmovie->title 和 (*pmovie).title 都是合法的,都表示取指针pmovie 所指向的结构其元素title 的值。我们要清楚将它和以下表达区分开:

*pmovie.title

它相当于

*(pmovie.title)

表示取结构pmovie 的元素title 作为指针所指向的值,这个表达式在本例中没有意义,因为title本身不是指针类型。

下表中总结了指针和结构组成的各种可能的组合:

表达式描述等价于
pmovie.title结构pmovie 的元素title 
pmovie->title指针pmovie 所指向的结构其元素title 的值(*pmovie).title
*pmovie.title结构pmovie 的元素title 作为指针所指向的值*(pmovie.title)

结构嵌套(Nesting structures)

结构可以嵌套使用,即一个结构的元素本身又可以是另一个结构类型。例如:

struct movies_t {
char title [50];
int year;
}

struct friends_t {
char name [50];
char email [50];
movies_t favourite_movie;
} charlie, maria;

friends_t * pfriends = &charlie;

因此,在有以上声明之后,我们可以使用下面的表达式:

charlie.name
maria.favourite_movie.title
charlie.favourite_movie.year
pfriends->favourite_movie.year

(以上最后两个表达式等价)



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

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

相关文章

ubuntu 手动安装mysql

申请了一台云主机&#xff0c;需要手动安装所有环境&#xff0c;今天将mysql安装过程记下。 安装mysqla. 下载不了gcc, 需要先运行apt-get updateb. cmake报错&#xff0c;每次要先删除cmakeCache.txt&#xff0c;再重新跑cmakec. apt-get install ncurses找不到对应包&#xf…

C++ 高级数据类型(六)—— 自定义数据类型

前面我们已经看到过一种用户&#xff08;程序员&#xff09;定义的数据类型&#xff1a;结构。除此之外&#xff0c;还有一些其它类型的用户自定义数据类型&#xff1a; 定义自己的数据类型 (typedef) C 允许我们在现有数据类型的基础上定义我们自己的数据类型。我们将用关键字…

JSF 2.0/2.1 生命周期简介

2019独角兽企业重金招聘Python工程师标准>>> 标准的生命周期划分为六个阶段&#xff1a;恢复视图、应用请求值、验证、更新模型值、调用应用程序、渲染响应&#xff0c;每一个阶段都可以直接跳转到最后一个阶段或者结束。 转载于:https://my.oschina.net/koulikoro/…

C++ 面向对象(一)—— 类(Classes)

类(class)是一种将数据和函数组织在同一个结构里的逻辑方法。定义类的关键字为class &#xff0c;其功能与C语言中的struct类似&#xff0c;不同之处是class可以包含函数&#xff0c;而不像struct只能包含数据元素。 类定义的形式是&#xff1a; [cpp] view plaincopy class cl…

Oracle C#处理时间类型的Insert

首先如果直接parm.ValueDateTime.Now;insert into table (TheTime)Value(parm);执行sql就会报错 --------------ORA-01861: 文字与格式字符串不匹配ADO.NET并没做到oracle转换。。所以oracle不兼容。解决方案&#xff1a;//先把时间转换为stirngparm.ValueDateTime.Now.ToStrin…

C++ 面向对象(二)—— 操作符重载

C 实现了在类(class)之间使用语言标准操作符&#xff0c;而不只是在基本数据类型之间使用。例如&#xff1a; int a, b, c; a b c;是有效操作&#xff0c;因为加号两边的变量都是基本数据类型。然而&#xff0c;我们是否可以进行下面的操作就不是那么显而易见了&#xff08;…

Seen.js – 使用 SVG 或者 Canvas 渲染 3D 场景

Seen.js 渲染3D场景为 SVG 或者 HTML5 画布。Seen.js 包含对于 SVG 和 HTML5 Canvas 元素的图形功能的最简单的抽象。所有这个库的其它组件都是不用关心将要渲染的上下文的类型。 您可能感兴趣的相关文章你见过吗&#xff1f;9款超炫的复选框&#xff08;Checkbox&#xff09;效…

C++ 面向对象(三)—— 类之间的关系

友元函数(Friend functions) 在前面的章节中我们已经看到了对class的不同成员存在3个层次的内部保护&#xff1a;public&#xff0c; protected 和 private。在成员为 protected 和 private的情况下&#xff0c;它们不能够被从所在的class以外的部分引用。然而&#xff0c;这个…

Oracle 之 用户与权限

1.创建用户create user zhu identified by "123456";#刚创建的新用户权限为空&#xff0c;所以不能连接数据库 grant create session to zhu;#赋予create session才可以连接到数据库2.修改用户的密码SQL> conn zhu/123456; Connected. SQL> show user; USER i…

C++ 面向对象(四)—— 多态 (Polymorphism)

基类的指针(Pointers to base class) 继承的好处之一是一个指向子类(derived class)的指针与一个指向基类(base class)的指针是type-compatible的。 本节就是重点介绍如何利用C的这一重要特性。例如&#xff0c;我们将结合C的这个功能&#xff0c;重写前面小节中关于长方形rect…

五年后存储会是什么样子

原文&#xff1a;http://chucksblog.emc.com/chucks_blog/2013/06/what-storage-might-look-like-in-five-years.html注明&#xff1a;本文内容基于 VMware VSAN beta 版本撰写&#xff0c;请访问http://www.vmware.com/products/virtual-san/获得有关正式版本的更新信息。有时…

C++ 标准函数库 —— 文件的输入输出 (Input/Output with files)

C 通过以下几个类支持文件的输入输出&#xff1a; ofstream: 写操作&#xff08;输出&#xff09;的文件类 (由ostream引申而来)ifstream: 读操作&#xff08;输入&#xff09;的文件类(由istream引申而来)fstream: 可同时读写操作的文件类 (由iostream引申而来) 打开文件(Ope…

java.lang.NoClassDefFoundError: javax/transaction/Synchronization (jUnit测试报错)

测试hibernate报错原因项目缺少包在 hibernate 解压目录下找到 jta.jar 文件往项目中添加该 jar 包&#xff0c;即可解决添加方法&#xff1a;【右击项目】-->【构建路径】....来自为知笔记(Wiz)转载于:https://www.cnblogs.com/zhanyao/p/3711322.html

C++ 高级篇(五)—— 预处理指令

预处理指令是我们写在程序代码中的给预处理器(preprocessor)的 命令&#xff0c;而不是程序本身的语句。预处理器在我们编译一个C程序时由编译器自动执行&#xff0c;它负责控制对程序代码的第一次验证和消化。 所有这些指令必须写在单独的一行中&#xff0c;它们不需要加结尾的…

yarn oom问题一例

线上部分job运行失败&#xff0c;报OOM的错误:因为是maptask报错&#xff0c;怀疑是map数量过少&#xff0c;导致oom&#xff0c;因此调整参数&#xff0c;增加map数量&#xff0c;但是问题依然存在。看来和map的数量没有关系。通过jobid查找jobhistory中对应的日志信息&#x…

C++ 高级篇(三)—— 出错处理

本节介绍的出错处理是ANSI-C 标准引入的新功能。如果你使用的C 编译器不兼容这个标准&#xff0c;则你可能无法使用这些功能。 在编程过程中&#xff0c;很多时候我们是无法确定一段代码是否总是能够正常工作的&#xff0c;或者因为程序访问了并不存在的资源&#xff0c;或者由…

kickStart脚本

kickstart是什么 许多系统管理员宁愿使用自动化的安装方法来安装红帽企业 Linux.为了满足这种需要,红帽创建了kickstart安装方法.使用kickstart,系统管理员可以创建一个文件,这个文件包含了在典型的安装过程中所遇 到的问题的答案. Kickstart文件可以存放于单一的…

C++ 高级篇(二)—— 名空间 (Namespaces)

通过使用名空间(Namespaces)我们可以将一组全局范围有效的类、对象或函数组织到一个名字下面。换种说法&#xff0c;就是它将全局范围分割成许多子域范围&#xff0c;每个子域范围叫做一个名空间(namespaces). 使用名空间的格式是&#xff1a; namespace identifier{namespace-…

32位CentOS系统安装kernel-PAE支持4g以上内存

转载自http://hi.baidu.com/yinhuama/item/31e572bb0a38f2ea4ec7fd7f 32位centos系统默认安装i386的内核不支持4g的内存 用yum安装kernel-PAE yum -y install kernel-PAE>vim /boot/grub/grub.conf修改设置为默认启动&#xff0c;default1改为default0 重启服务器 reboot再执…

C++ 高级篇(一)—— 模板(Templates)

模板(Templates)是ANSI-C 标准中新引入的概念。如果你使用的 C 编译器不符合这个标准&#xff0c;则你很可能不能使用模板。 函数模板( Function templates) 模板(Templates)使得我们可以生成通用的函数&#xff0c;这些函数能够接受任意数据类型的参数&#xff0c;可返回任意类…