预备知识
c++在c语言的基础上添加了面向对象编程和泛型编程
c语言诞生的背景:贝尔实验室开发UNIX操作系统,需要一种高级语言代替汇编语言,避免在每台计算机上执行不同的汇编程序
c语言编程的原理(强调的是算法)
- 需要处理的概念——数据和算法
- 结构化编程和自顶向下的编程方法,将程序不断划分成程序单元,便于阅读和管理
面向对象编程:
- 面向对象编程强调数据,用类描述特定的数据结构
- 首先设计类,然后再设计程序解决问题,从低级组织到高级组织的处理过程叫做自下向上的编程
面向对象编程的优点:
1. 有助于创建可重用的代码
2. 信息隐藏可以保护数据
3. 多态能够为运算符和函数创建多个定义,通过编程上下文确定使用哪个定义
4. 继承能够使用旧类派生出新类
泛型编程:
- 目标:使重用代码和抽象通用概念的技术更简单
- 强调独立于特定数据类型
- 提供了执行常见任务的工具,即泛型编程与面向对象编程的应用场景不同
- 泛型指的是创建独立于类型的代码,比如设计一个排序函数,此排序函数不单独为整形、浮点型所设计,而泛型编程对语言进行扩展,以便可以只编写一个泛型函数
可移植性
在不修改代码的情况下,更换计算机平台,重新编译程序后,程序运行良好,则该程序是可移植性的
可移植性的挑战:
1. 硬件——避免
2. 语言——标准:异常、运行阶段类型识别、模板和便准模板库
3.
编译和链接
使用visual c++2015进行编程
步骤:
1. 新建项目
2. 选择win32–win32 console application
3. 选择空项目
IDE环境
1. compile
对当前打开的文件中的代码编译
2. build
和make
编译项目中所有源代码文件的代码,重新编译新修改文件
3. build all
重新编译所有源代码文件
4. 为了查看程序输出,可以在程序的最后加上下面的代码
cin.get();
cin.get();
return 0;
cin.get()
语句读取下一次键击,上述语句让程序等待,直到按下Enter键。如果程序在常规输入后留下一个没有被处理的键击,那么第二条语句是必需的,enter键将被第一个cin.get()
吸收
问题
问题1:什么是泛型编程?
对编程语言进行扩展,以使程序不针对特定数据类型而适用
问题2:什么是多态和编程上下文?
2018/7/14
开始学习c++
一个简单的c++程序:
#include<iostream>
using namespace std;
int main()
{
for (int i = 0; i < 5; i++) {
cout << i << endl;
}
cout << "hello world" << endl;
system("pause");
return 0;
}
main()
函数
int main()
叫函数头,{}
包含的部分叫函数体
- 作为接口的函数头
函数头描述了函数与调用它的函数之间的接口,函数名前面的部分叫做函数返回类型,函数名后括号中的而部分叫做形参列表。
通常main()
被启动代码调用,启动代码是由编译器添加到程序中的,是程序和编译系统之间的桥梁
如果编译器到达main()
函数末尾时没有遇到返回语句,认为以return 0
结尾
c语言中,省略返回类型相当于函数类型为
int
,但是c++淘汰了这种用法
注释
c++注释://
c注释:/**/
c++
预处理器和iostream
文件
如果需要使用c++的输入或者输出工具,需要提供下面两行代码:
#include <iostream>
using namespace std;
该编译指令使预处理器将iostream文件的内容添加到程序中,这涉及程序与外部世界之间的通信,iostream文件中的内容,将取代第一行代码,因此使用cin
和cout
的程序必须包含iostream
c头文件的扩展名为h,c++头文件没有扩展名
名称空间
名称空间编译指令using namespace std;
名称空间所解决的问题:名称空间支持是c++一项特性,在引用他人代码组合起来的时候解决函数名称共用问题。所引用的代码封装在名称空间单元中,可以用名称空间的名称来指出用哪个厂商的产品,比如wanda()
函数的全称为Microflop::wanda()
Piscine::wanda()
,这样程序可以根据名称空间区分不同版本
所以cout
实际上是std::cout
,endl
实际上是std::endl
所以也可以使用下面的代码代替using namespace std;
using std::cout;
using std::endl;
using std::cin;
使用cout进行c++输出
cout
是一个预定义的对象,<<
表示信息流动方向,实际上是运算符重载
问题:什么是运算符重载?
允许用户定义的类型重新定义运算符的含义
endl
:重起一行,位于名称空间std中,在iostream中定义的,保证程序继续运行前刷新输出\n
:count << "what are you\n";
引号扩起的字符串通常用
\n
,其他情况用endl
int main()
{
int carrots;
carrots = 25;
cout << "I have ";
cout << carrots;
cout << " carrots." << endl;
carrots = carrots - 1;
cout << "Now i hava " << carrots << " carrots" << endl;
system("pause");
return 0;
}
在声明变量的时候将为变量分配内存空间 赋值语句将值赋给存储单元
“`cout“`在打印之前,必须将整数形式的数字转换为字符串形式,“`可以连续使用赋值运算符
类
类描述的是数据格式和用法,对象则是根据数据格式创建的实体 类描述指定了可对类对象执行的所有操作,c++两种发送消息的方式:类方法和运算符重载c++中,函数调用必须 包括括号,即使没有参数
用户定义的函数
添加另一个用户定义的函数,在使用前必须提供原型,放到main()定义之前- 没有返回值的函数
#include<iostream>
using namespace std;
void simon(int);
int main()
{
simon(3);
system("pause");
return 0;
}
void simon(int n)
{
using namespace std;
cout << "simon says touch your toes " << n << " times." << endl;
}
定义simon()的源代码位于main()后面,不允许将函数定义嵌套在另一个函数定义中
- 有返回值的函数
#include<iostream>
using namespace std;
int stonetolb(int);
int main()
{
int pounds = stonetolb(2);
cout << pounds << endl;
system("pause");
return 0;
}
int stonetolb(int sts)
{
return 14 * sts;
}
–
处理数据
内置的c++数据类型分为——
基本类型:整数和浮点数
复合类型:数组、字符串、指针和结构
c++命名规则其一:以两个下划线或下划线和大写字母大头的名称被保留给实现,以一个下划线开头的名称被保留给实现,用作全局标识符
基本类型
- 整型short\int\long\long long
- short至少16位
- int至少和short一样长
- long至少32位,且至少与int一样长
- long long至少64位,且至少与long一样长
可以用sizeof
运算符返回类型或者变量的长度,单位是字节
#include<iostream>
using namespace std;
int main()
{
int a = INT_MAX;
long n_long = LONG_MAX;
long long x_llong = LLONG_MAX;
cout << "short is " << sizeof (short) << " bytes." << endl;//2
cout << "int is " << sizeof(int) << " bytes." << endl;//4
cout << "long is " << sizeof(long) << " bytes." << endl;//4
cout << "long long is " << sizeof(long long) << " bytes." << endl;//8
cout << "int is " << a << " bytes." << endl;// 2147483647
cout << "n_long is " << n_long << " bytes." << endl;// 2147483647
cout << "x_llong is " << x_llong << " bytes." << endl;// 9223372036854775807
system("pause");
return 0;
}
初始化的方式:
int emus{ 7 };
int rheads = { 12 };
无符号类型
unsigned short change
#include<iostream>
using namespace std;
int main()
{
int n_int = INT_MAX;
unsigned int un_int = INT_MAX;
cout << n_int << endl;
cout << un_int << endl;
cout << n_int + 1 << endl;
cout << un_int + 1 << endl;
system("pause");
return 0;
}
无符号整型可以增大变量能够存储的最大值
上面的例子中n_int进行过加1操作会变成赋值,因为符号为产生进位
整形字面量
c++能够用三种不同的计数方式来书写整数:基数为10,8,16
如果第一位是0,第二位是1-7,则基数是8;
如果前两位是0x或0X,则基数是16.
在默认情况下,cout以十进制格式显示整数,在计算机中存储都以二进制形式进行存储
endl
提供了控制符dec
“`hex\
oct分别指示
cout“`以十进制、十六进制和八进制格式显示整数
在打印的下一行加入下面的代码
cout << hex;
char类型
char类型是另一种整型,能存储所有基本符号
#include<iostream>
using namespace std;
int main()
{
char ch;
cin >> ch;
cout << ch << endl;
system("pause");
return 0;
}
程序输入字母也被输出,但是内存中存储的内容为字母对应的字符编码
实际上,程序调用了cout
的put
函数
cout.put(ch)
实际上ch
存储的是整数,可以执行整数的操作,如加法
#include<iostream>
using namespace std;
int main()
{
char ch;
cin >> ch;
cout << ch << endl;
cout << ch + 1 << endl;
system("pause");
return 0;
}
最后一行将输出78
如果输入数字5,ch
中将存储5的字符编码53,所以第二行输出54
#include<iostream>
using namespace std;
int main()
{
char ch;
cin >> ch;
cout << ch << endl;
cout << ch + 1 << endl;
cout.put(ch);
system("pause");
return 0;
}
书写字符常量的最简单方法是用单引号括起
'A'
'5'
如果char
型存储的是数值类型,那么unsigned char
和signed char
差异很重要,signed char
表示范围是-128–127
布尔类型
非零值为true,零为false,true 可以转换为1,false转换为0
const限定符
const关键字修改变量声明和初始化
const int Months = 12;
将名称的首字母大写,提醒自己表示常量
浮点数
float
double
long double
浮点数表示法:
12.3
2.52e+8//小数点向右移动8位
8.33E-4//小数点向左移动4位
c++算数运算符
+
-
*
/
%
除法分支,如果两个操作数都是整数,执行整数除法,小数部分被丢弃,有一个是浮点数,则结果为浮点数
类型转换
将一个值赋值给取值范围更大的类型通常不会导致问题,但是将一个很大的值赋值给一个较小的值会降低精度。
int('Q');
c++11中的
auto
声明,让编译器能够根据初始值的类型推断变量的类型
复合类型
数组
编译器不会检查使用的下标是否有效
数组初始化:int a[3] = {20,1,2};
初始化时,提供的值可以少于数组的元素数目,如果只对数组一部分进行初始化,编译器将把其他元素设置成0。初始化全为0:
long b[3] = {0};
short thing[] = {1,5,2,3};
编译器会计算元素个数
拓展:vector
字符串
用char数组类型存储字符串,需要以空字符结尾,空字符被写作\0
char dog[3] = {
'b','e','a'};//not a string
char cat[3] = {
'b','e','\0'};//a string
很多处理字符串的函数的处理规则都是以遇到空字符停止
下面的字符串初始化也是合理的,用引号括起的字符串隐式包括 结尾的空字符
char bird[11] = "Mr. cheeps";
char fish[] = "bubbles";
在确定存储字符串所需的最短数组时,记得将结尾的空字符计算在内
拓展:string
标准头文件cstring提供了很多与字符串相关的函数
#include<iostream>
//#include<cstring>
using namespace std;
int main()
{
const int Size = 15;
char name1[Size];
cin >> name1;
cout << strlen(name1) << endl;
system("pause");
return 0;
}
但是尝试注释调cstring头文件也没有报错
strlen不会计算空字符,若数组存储内容中间含有空字符,即使后面还有字符,字符串也会在空字符处结束;cin使用空白(空格、制表符和换行符)来确定字符串的结束位置
解决各个单词空格分开的问题:
每次读取一行字符串输入
istream中的类提供了一些面向行的类成员函数:getline()
和get()
,读取一行输入,直到到达换行符,但是getline()
会丢弃换行符,get()
将换行符保留在输入序列中。
getline()
调用方法:
cin.getline(数组名称,字符数)
若字符数为20,最多读取19个字符
const int Size = 15;
char name1[Size];
char name2[Size];
cin.getline(name1, Size);
cin.getline(name2, Size);
cout << name1 << endl;