C++学习(八)入门篇——复合类型
数组(需要声明以下三点):
(1)存储在每个元素中值的类型
(2)数组名
(3)数组中的元素数
声明数组的通用格式如下:
typeName arrayName[arraySize];arraySize不能是变量;
float loans[20]表示loans数组是使用float类型创建的,C++数组从0开始编号。
编译器不会检查使用的下标是否有效,如果将一个值赋给不存在的元素months[101]编译器不会指出错误,但会引发问题,破坏数据或代码或使程序异常终止。
程序清单4. arrayone.cpp
//arrayone.cpp - - small arrays of integers
#include<iostream>
int main()
{
using namespace std;
int yams[];
yams[] = ;
yams[] = ;
yams[] = ;
int yamcosts[] = { , , }; //只要提供一个用逗号分隔的值列表,并用花括号括起来即可 cout << "Total yams = ";
cout << yams[] + yams[] + yams[] << endl;
cout << "The package with " << yams[] << " yams costs ";
cout<<yamcosts[]<< " cents per yam.\n";
int total = yams[] * yamcosts[] + yams[] * yamcosts[] + yams[] * yamcosts[];
total = total + yams[] * yamcosts[];
cout << "The total yam expense is " << total << " cents.\n"; cout << "\nSize of yams array = " << sizeof yams; //整个数组字节数
cout << " bytes.\n";
cout << "Size of one elements = " << sizeof yams[]; //一个元素字节数
cout << "bytes.\n";
cin.get(); }
得到:

1.数组的初始化规则
只有在定义数组时才能初始化
int cards[4] = {3,6,8,10};
int hand [4];
hand [4] = {5,6,7,9}; 不允许
hand =cards; 不允许
初始化数组时,提供的值可以少于数组的元素数目,其他元素将被设置为0,将数组所以元素都初始化为0,只要让第一个元素为0即可
long totals[500] = {0};
如果初始化数组时方括号为空,C++编译器将计算元素个数
short things[] ={1,5,3,8}
编译器将使things数组包含4个元素
如果主要关心的是程序,而不是自己知道数组的大小,可以这样做
short things [ ] ={1,5,3,8};
int num_elements = sizeof things / sizeof (short);
C++初始化新增了一些新功能
比如省略=
double earning[4] {1.2e4, 1.6e4, 1.1e4,1.7e4};
其次可不在大括号里包含任何东西,这将把所有元素都设置为零
unsigned int counts [10] = { };
float balances [100] { };
第三,列表初始化禁止缩窄转换
long plifs [ ] ={25,92,3.0}; 不行,因为浮点数转化为整型是缩窄
char slifs [4] {'h','i',1122011, '\0'}; 不行,因为1122011超过了char的取值范围
char tlifs [4] {'h','i',112,'\0'}; 可以
2.字符串
C++处理字符串的方式有两种,C风格字符串和基于string类库的方法。
C字符串具有一种特殊的性质,以空字符结尾,空字符被写作\0,ASCII码为0,用来标记字符串的结尾。
看以下两个声明:
char dog[8] = {‘b’,‘e’,‘a’,‘u’,‘x’,‘ ’,‘I’,‘I’}; 是字符串
char cat[8] ={'f ', 'a', 't', 'e', 's' , 's', 'a', '\0'}; 不是字符串
空字符对C风格字符串至关重要,用cout显示cat字符串,将显示前7个字符,遇到空格后停止,而dog将打印8个,并接着将内存中随后各个字节解释为要打印的字符,知道遇到空字符为止。
也可以使用以下方法:
char bird[11] ="Mr.Cheeps";
char fish[ ] ="Bubbles";
用引号括起的字符串隐式的包括结尾的空字符
在确定存储字符串所需的最短数组时,别忘了将结尾的空字符计算在内。
注意:字符串常量(使用双引号)不能与字符常量(使用单引号)互换
'S'只是字符串编码的简写方式,在ASCII只是83的另一种写法
char shirt_size =‘S’;
将83赋给了shirt_size
“S”不是字符常量,而是S和\0组成的字符串,“S”实际表示字符串所在的内存地址
char shirt_size = "S";
将一个内存地址赋给shirt_size。
由于地址在C++中属于一个独立的类型,C++编译器不允许这种不合理的做法
C++允许拼接字符串字面值,即将两个用引号括起的字符串合并为一个。
任何两个由空白(空格、制表符、换行符)分隔的字符串常量都将拼接成一个(不考虑\0)
3.在数组中使用字符串
最常用的两个方法——将数组初始化为字符串常量,将键盘或文件输入读入到数组中。
标准头文件cstring提供了该函数以及很多与字符串相关的其他函数的声明
程序清单4. string.cpp
//strings.cpp - - storing strings in an array
#include<iostream>
#include<cstring>
int main()
{
using namespace std;
const int Size = ;
char name1[Size];
char name2[Size] = "C++owboy"; cout << "Howdy!I'm " << name2;
cout << "! What's your name?\n";
cin >> name1;
cin.get();
cout << "Well, " << name1 << ",your name has ";
cout << strlen(name1) << " lettrs and is stored\n";
cout << "in an array of " << sizeof(name1) << " bytes.\n";
cout << "Your initial is " << name1[] << ".\n";
name2[] = '\0';
cout << "Here are the first 3 characters of my name:";
cout << name2 << endl;
cin.get();
}
输出:

sizeof运算符指的是整个数组的长度,而strlen函数返回的是存储在数组中的字符串的长度,而且是突然类只计算可见的字符,不把空字符计算在内
程序清单4. instr1.cpp
//instr1.cpp - - reading more than one string
#include<iostream>
int main()
{
using namespace std;
const int ArSize = ;
char name[ArSize];
char dessert[ArSize]; cout << "Enter your name:\n";
cin >> name;
cout << "Enter your favorite dessert:\n";
cin >> dessert;
cin.get();
cout << "I have some delicious " << dessert;
cout << " for you, " << name <<".\n";
cin.get(); }
得到输出:

可以看到,这个程序有个小缺陷,cin使用空白(空格、制表符和换行符)来确定字符串的结束位置。意味着cin在获取字符数组输入时只读取一个单词,并在结尾自动添加空字符。
采用每次读取一行字符串输入来解决(需要面向行而不是面向单词)
面向行的类成员函数:get()和getline()
这两个函数都读取一行输入,直到到达换行符,getline()将丢弃换行符,get()将换行符保留在输入序列中
这里先讨论getline()
通过回车键输入的换行符来确定结尾,cin.getline(name,20)第一个存储输入行的数组名称,第二个是要读取的字符数
如果参数为20,则函数最多读取19个字符,余下空间用来存储自动在结尾处添加的空字符
程序清单4. instr2.cpp
//instr2.cpp - - reading more than one word with getline
#include<iostream>
int main()
{
using namespace std;
const int ArSize=;
char name[ArSize];
char dessert[ArSize]; cout<<"Enter your name:\n";
cin.getline(name, ArSize);
cout << "Enter your favorite dessert:\n";
cin.getline(dessert, ArSize);
cout << "I have some delicious " << dessert;
cout << " for you, " << name << " .\n";
cin.get();
}
输出结果:

cin.getline()读取字符串并将换行符替换成空字符,不保存换行符
如果使用get()输入
连续两次调用get()时,第一次调用后,换行符将留在输入队列中,第二次调用时遇到第一个字符就是换行符,那么get()认为已到达行尾,无法读取任何内容。
因此采用以下的方式:
cin.get(name,ArSize); //要将一个字符串放入数组中
cin.get(); //处理换行符,读取一个字符
cin.get(dessert,ArSize);
另一种使用get()方式将两个类成员函数拼接起来
cin.get(name,ArSize).get();返回一个cin对象,随后被用来调用get()函数,处理掉换行符
cin.getline(name1,ArSize).getline(name2,ArSize);调用效果与两次调用cin.getline()相同
程序清单4. instr3.cpp
//instr3.cpp - - reading more than one word with get()&get()
#include<iostream>
int main()
{
using namespace std;
const int ArSize = ;
char name[ArSize];
char dessert[ArSize]; cout << "Enter your name:\n";
cin.get(name, ArSize).get();
cout << "Enter your favorite dessert:\n";
cin.get(dessert, ArSize).get();
cout << "I have some delicious " << dessert;
cout << " for you, " << name << ".\n";
cin.get();
}
得到输出:

get()和getline()相比,输入更仔细,它可以根据查看下一个字符是换行符或者不是来判断,停止读取的原因是已经读取了整行而不是数组已填满。
当get()读取空行侯江设置失效位,意味着接下来的输入将被阻断,可用以下命令恢复:
cin.clear();
当输入字符串比分配空间长,则getline()和get()将余下的字留在输入队列中,而getline还会设置失效位,并关闭后面的输入。
当混合输入数字和面向行的字符串会导致问题
程序清单4. numstr.cpp
//numstr.cpp - - following number input with line input
#include<iostream>
int main()
{
using namespace std;
cout << "What year was your house built?\n";
int year;
cin >> year;
cout << "What is its street address?\n";
char address[];
cin.getline(address, );
cout << "Year built: " << year << endl;
cout << "Address: " << address << endl;
cout << "Done!\n";
cin.get();
}
得到结果为:

当cin读取年份,将回车键生成的换行符留在了输入队列中,后面的cin.getline()看到换行符后认为是一个空行
所以在读取地址之前应该先丢弃换行符
可以在
cin >> year;后加
cin.get();
或者(cin.year).get();
则可以正常工作

C++学习(八)入门篇——复合类型的更多相关文章
- Swift入门篇-基本类型(2)
现在我也在学习Swift语言,常常去逛很多苹果社区和论坛,看到了圈子很多奇怪的现象,发现很多人都赶忙去翻译 Swift书籍 和 发布Swift的视频 .他们这种对新知识的探索精神我本人是很佩服的.但是 ...
- PHP学习笔记 - 入门篇(5)
PHP学习笔记 - 入门篇(5) 语言结构语句 顺序结构 eg: <?php $shoesPrice = 49; //鞋子单价 $shoesNum = 1; //鞋子数量 $shoesMoney ...
- PHP学习笔记 - 入门篇(3)
PHP学习笔记 - 入门篇(3) 常量 什么是常量 什么是常量?常量可以理解为值不变的量(如圆周率):或者是常量值被定义后,在脚本的其他任何地方都不可以被改变.PHP中的常量分为自定义常量和系统常量 ...
- Java工程师学习指南 入门篇
Java工程师学习指南 入门篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都 ...
- Elasticsearch学习记录(入门篇)
Elasticsearch学习记录(入门篇) 1. Elasticsearch的请求与结果 请求结构 curl -X<VERB> '<PROTOCOL>://<HOST& ...
- PHP学习笔记 - 入门篇(4)
PHP学习笔记 - 入门篇(4) 什么是运算符 PHP运算符一般分为算术运算符.赋值运算符.比较运算符.三元运算符.逻辑运算符.字符串连接运算符.错误控制运算符. PHP中的算术运算符 算术运算符主要 ...
- PHP学习笔记--入门篇
PHP学习笔记--入门篇 一.Echo语句 1.格式 echo是PHP中的输出语句,可以把字符串输出(字符串用双引号括起来) 如下代码 <?php echo "Hello world! ...
- netty深入学习之一: 入门篇
netty深入学习之一: 入门篇 本文代码下载: http://download.csdn.net/detail/cheungmine/8497549 1)Netty是什么 Netty是Java NI ...
- C++学习(五)入门篇——基本类型
面向对象编程的本质是设计并扩展自己的数据类型,让类型和数据匹配. 内置C++分成两种类型:基本类型和复合类型 1.简单变量 程序需要存储信息时,必须记录三个基本属性 (1)信息将存储在哪 (2)要存储 ...
随机推荐
- Mybatis在oracle批量更新
最近公司业务中为了提高效率要做mybatis批量更新,但是到了oracle数据库中做了好几次都没成功,后来发现mybatis最后少了个分号,可能是Mybatis内部做了异常try catche 处 ...
- RPM基础知识
RPM包命名原则 httpd-2.2.15-15.el6.centos.1.i686.rpm httpd 软件包名 2.2.15 软件版本 15 软件发布的次数 el ...
- java执行程序的内存分析系列专栏
近段时间研究了java的程序执行过程中的内存分配,收获颇多,解决了我最近时间学习java的很多困惑点.写java内存分析系列的目的主要有两个,一来是希望给像我一样的java初学者一定的启发,希望也能解 ...
- yiic执行出现不是内部或外部命令的解决办法
右击我的电脑-->属性-->高级系统设置-->高级-->环境变量-->系统变量 设置为"D:\Program Files (x86)\wamp\bin\php\ ...
- [leetcode-541-Reverse String II]
Given a string and an integer k, you need to reverse the first k characters for every 2k characters ...
- 使用CodeDOM动态编译一个字符串表达式
由于程序需要,计算的表达式使用字符串传输,这样对运算造成了影响.在程序中直接执行这段表达式可以得到值, 但是使用字符串就没有办法运算了, 所以想到用CodeDOM将这段字符串拼接在代码中编译 类似st ...
- phpstorm,webstorm取消自动保存并标识修改的文件为星星标记
a.取消自动保存是去掉一下两个勾选. b.标记星星要勾选下面的选项.
- IT小天博客APP版本
今天弄了一个博客的APP版本,感觉还不错,欢迎下载体验. 共 1 张图片 APP名称:[IT小天博客APP] APP版本:1.3 APP上线时间:2017-06-29 下载地址:点击下载
- Linux - iostat命令详解
简介 iostat可以提供更丰富的IO性能状态数据,iostat命令有两个用途: 输出CPU的统计信息 输出设备和分区的I/O统计信息 命令语法及参数说明 语法: iostat [ -c | -d ] ...
- Unity3D-Shader-热扭曲效果
[旧博客转移 - 2016年1月13日 13:18 ] 前面的话: 本来我是想写一个水的原理的,但是发现涉及的知识太多,还有好多不懂的,所以就先一步一步来 最近呢,我在网上捡到了一本<热扭曲秘籍 ...