使用new关键字创建数组
使用new关键字创建数组的方式如下:
int* p = new int[elementCount];
整型指针p将指向数组的第一个元素的地址。
可以通过指针名来写入或读取数组的元素,如:
p[0] = 7;
cout << p[0] << endl;
new创建的数组需要使用delete去释放内存,由于数组的连续的若干个地址组成的,所以释放内存操作如下:
delete[] p;
使用new关键字创建数组
使用new关键字创建数组的方式如下:
int* p = new int[elementCount];
整型指针p将指向数组的第一个元素的地址。
可以通过指针名来写入或读取数组的元素,如:
p[0] = 7;
cout << p[0] << endl;
new创建的数组需要使用delete去释放内存,由于数组的连续的若干个地址组成的,所以释放内存操作如下:
delete[] p;
指针和数组
C++中,输出数组会输出一个内存地址,表明数组也是指针的一种,它会在内存中申请连续的空间。数组名指向数组第一个元素的内存地址,对它进行取值操作会取到第一个元素的值,对数组名进行加减法时,会移动指针指向的内存地址,加法向后,减法向前。可以通过这种方式对指定下标元素进行赋值操作,如下:
int test[] {11,22,33,44,55};
*(test + 1) = 1000;
上述操作会对数组test的第二个元素赋值1000。
new关键字和delete关键字
new关键字用法如下:
int* p = new int;
*p = 0;
通过new关键字申请内存地址,一定要使用delete关键字释放内存,及时清空内存空间,delete关键字用法如下:
delete p;
声明的变量无需手动释放内存。
空指针、空类型指针
当无法知晓先前声明的指针具体指向哪一内存地址时,可以使指针指向空地址,如下:
int* p1 = NULL;
int* p2 = 0;
C++11标准引入了新的空指针指定方式,如下:
int* p3 = nullptr;
可以指定空类型指针,如下:
void* p4;
表示p4可以接受任意类型的地址,有如下操作:
int a = 0;
int* pa = &a;
p4 = &a;
如果要使用空类型指针指向地址的值,需要将空类型指针进行强制类型转换,如:
int b = *((int*)p4);
指针
1.指针可以用来存储变量的地址,声明指针如下:
int a = 0;
int* pa = &a;
指针类型需要与变量的类型保持一致,否则将报错。
2.直接输出指针会输出内存地址,所以要取得指针所指的内存地址内存储的值需要在指针前加入*符号,如:
int a = 0;
int* pa = &a;
cout << *pa << endl;
3.指针间的赋值操作如下:
int a = 0;
int* pa = &a;
int* p;
p = pa;
4.通过指针去存储数据的操作如下:
*pa = 100;
此操作将会将pa指针指向的内存地址中存储的值设置为100,所以此前定义的变量a也会变成100。如果通过p指针去修改值,也会有同样的结果。
*指针必须初始化,使用没有初始化的指针会报错。
内存和地址
内存是程序运行时,存储变量或常量的地方,可以把内存想象成一个字节数组,这个字节数组的元素下标就相当于内存的地址。
内存中的每个位置都由一个独一无二的地址表示,内存中的每个位置都包含一个值,可以通过一个地址找到内存的具体位置后得到该地址中存储的值。
在声明一个变量时,系统会自动为该变量申请内存空间,后续通过变量名去访问内存并取得该值,无需关心内存的地址。
可以使用&符号取得一个变量的值,如:
int i = 0;
cout << &i << endl;
内存的地址用16进制数字表示。
可以使用*符号取得一个内存地址中存储的值,如:
int i = 0;
cout << *(&i) << endl;
枚举类型
枚举类型的声明如下:
enum TestEnum{
Type1,
Type2,
Type3
};
枚举类型的实际值是整型数据,可以当做整型去使用,枚举的第一个值为0。当使用cout去输出一个枚举类型的变量时,会输出整型。
枚举的值是可以更改的,如:
enum TestType{
Type1 = 1;
Type2 = 4;
Type3 = 8;
};
在后续使用时需要保证指定的值存在于枚举中。
结构体
结构体类似于类,可以存储多类型的变量。它有自己的作用域,如果他声明在函数体外,则可以被多个函数调用,如果在函数体内,则只能由该函数调用。
结构体的声明方法如下:
struct StcTest{};
然后在结构体内(花括号内)声明该结构体的成员变量,如下:
struct StcTest{
string a;
int b;
float c;
char d;
};
在使用结构体前,需要创建结构体的实体,如下:
StcTest stcTest;
然后才可以访问结构体的成员变量,如下:
string name = stcTest.a;
int score = stcTest.b;
......
在创建结构体的实体时,可以对结构体的成员变量按顺序进行赋值,如:
StcTest stcTest1 = {"a", 1, 3.5f, 'b'};
StcTest stcTest2{"a", 1, 3.5f, 'b'};
StcTest stcTest3{ };
示例:
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
struct Stc1{
public:
string name = "Haze";
float height = 176.8f;
float weight = 74.0f;
string job = "Programmer";
};
int main()
{
Stc1 stc;
cout << stc.name << "'s height is "
<< stc.height << "cm and his weight is "
<< stc.weight << "kg and he is a " << stc.job << endl;
Stc1 stc2;
stc2.name = "YH";
stc2.height = 177.0f;
stc2.weight = 74.0f;
stc2.job = "Technical artist";
cout << stc2.name << "'s height is "
<< stc2.height << "cm and his weight is "
<< stc2.weight << "kg and he is a " << stc2.job << endl;
}
可以声明结构体数组,其方法和其他输入类似,如下:
StcTest stcTest[]{{}, {}, {}, {}};
因为结构体数组的元素均为一个结构体,所以每个元素都需要用花括号括起来。
C++string类库
使用string类库需要include<string>。引入类库后可直接使用string声明一个字符串,如:
string str;
string str2 = "Example";
未声明的字符串会默认为空字符串。可以对字符串类型的变量赋值,如:
string str;
string str1 = "Example";
str = str1;
获取用户输入的字符串赋值给字符串变量需要使用getline()方法,如下:
string str;
getline(cin,str);
获取字符串中的第i个字符的操作如下:
string str = "Example";
char c = str[2];
注意,i不能越界,必须大于0且小于字符串的长度。
字符串变量之间可以进行加法运算,通过"+"运算符连接两个字符串,如:
str1 = "Example";
str2 = " string";
string str3 = str1 + str2;
str3的值为"Example string"。
可以通过string.size()获取字符的个数。
使用cin函数需要注意的点
用户输入的制表符、空格都会被cin视为输入的结束。
可以使用cin.getline(array, value);来避免上述问题。
字符串
C语言风格字符串
C语言当中没有实际的字符串,是通过字符类型的数组实现字符串,如:
char exArray[] = {'e','x','a','m','p','l','e','\0'};
\0在C语言表示字符串的结束。
不以\0结束的字符数组将会在输出数组的时候输出乱码。
上述方式过于繁琐,在声明字符串时可以使用以下方法:
char exArray[] = "example";
此方法会解析双引号括起来的字符串并生成字符数组,并且自动添加\0。此时数组的长度为字符的个数+1,\0同样被视为一个数组元素。
长字符串可以分割为多个字符串,如:
char exArray[] = "Example string.""This is the second string.";
数组的初始化
以整型为例,数组的初始化如下:
1)声明数组时指定数组长度并完全初始化,如:
int exArray[4] = {11,22,33,44};
2)声明数组时指定数组长度并部分初始化,如:
int exArray[4] = {11,22};
未初始化的数组元素的默认值为0。
3)声明数组时不指定数组长度,如:
int exArray[] = {11,22,33,44,55};
此时,数组会根据声明的元素个数为数组设置长度。
4)声明数组时指定数组长度并初始化,且不使用赋值运算符,如:
int exArray[]{11,22,33,44};
此为C++11的标准。
数组的索引(下标)
C++中,数组的下标从0开始到数组的长度减去1结束,如:
int exArray[]{11,22,33,44};
该数组的下标为0~3。
数组里的值通过数组下标来调用,如:
需要调用上述数组的低3个元素时,如下操作:
int ex = exArray[2];
数组的下标必须是存在的,不得小于0且不得大于数组的长度。注意,C++中下标越界不会报错。
修改数组元素的值得方式与调用数组元素的方式相似,如:
exArray[2] = 104;
数组
数组是存储若干个相同数据类型的值的容器,数组有3要素,1是数组存储的数据类型,2是数组的名字,3是数组的长度。
数组的声明
数组的声明如下:
type arrayName[elementsCount];
type是数组存储的数据类型,arrayName是数组的名字,elementsCount是数组的长度。数组的长度必须大于0。
auto关键字
自动推断类型的关键字,它将会根据值来对变量设置数据类型。它不允许在声明变量时不设置默认值,必须在声明的同时为变量设置默认值。
auto关键字无法精确的指定变量的具体数据类型,所以默认值可能出现混淆时,就只能声明具体数据类型的变量。
练习题
1、让用户输入自己的身高(米),将它转换为厘米输出。
答:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
float height = 0.0f;
cout << "Enter your height in meter:";
cin >> height;
cout << "Your height in centimeter is: " << height * 100.0f <<"cm" << endl;
}
2、编写一个程序,让用户输入秒数,将他转换为天-小时-分钟-秒并打印出来。
答:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int second = 0;
cout << "Enter a second(integer):";
cin >> second;
//1h = 60m = 3600s 1d = 24h
cout << "The converted result is: "
<< second / 60 / 60 / 24<< "day(s), "
<< second / 3600 % 24<< "hour(s), "
<< second / 60 % 60<< "minute(s), "
<< second % 60<< "second(s)."<<endl;
}
3、要求用户输入一个班级的男生和女生的人数,输出女生的比例(百分比)。
答:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int male = 0;
int female = 0;
cout << "Enter the count for male in the class:";
cin >> male;
cout << "Enter the count for female in the class:";
cin >> female;
cout << "The percentage of female in the class is:"
<< (float)female / (float)(female + male) * 100.0f
<< "%." << endl;
}
类型转换
int -> float 不发生变化。
float/double -> int 向下取整。
尽量避免将超过数据类型取值范围外的值赋值给变量。
float + int 的情况下会视值的大小进行类型转换,值小的转换为值大的数据类型。
强制类型转换
1)在常量或变量前加上要转换的数据类型并使用括号括起来,如:
int i = (int)12.9;
此为C语言标准。
2)在常量或变量前加上要转换的数据类型并使用括号将常量或变量括起来,如:
int j = int(12.9);
此为C++语言标准。
两种转换规则均与上述类型转换规则相同,浮点转到整型会进行向下取整。
算数运算符
算数运算符有 +、-、*、/和%,分别为加、减、乘、除和取余(求模),用于数字类型数据的计算。
运算结果受赋值变量的数据类型的影响,如运算符两边的数据为浮点型,但接收结果的变量为整型,则结果不会采用四舍五入的方式取整,而是会向下取整,如下:
float a = 1.5;
float b = 2.3;
实际上a + b应该等于3.8,但如果接收结果的变量c为整型int时:
int c = a + b;
变量c的值为3.8向下取整的3。
关于取余运算符,在C++中,要求运算符两边的变量或常量均为整型数据。
关于优先级,与数学当中的优先级基本一致。
浮点型
浮点型是小数,分为单精度float和双精度double以及long double。float类型包含符号位1位、指数位8位和尾数位23;double类型包含符号位1位,指数位11位和尾数位52位;
C++中的科学计数法
可使用科学计数法表示浮点型数据,如1340000000可表示为1.34e+9。
e后面的符号表示小数点的左移或右移,如1.2e-6就等于0.0000012。
常量
常量是固定不变的量,如某个字符、数字或者true、false等。
常量的声明需要使用const限定符,如下:
const int i = 100;
常量一旦声明之后,就无法在其他代码段修改其值,必须转到声明行进行修改。
布尔类型
布尔类型变量的值只能是true和false。true为肯定,false为否定。一段逻辑运算符表达式的结果为布尔类型的值,如:
1 <= 2
该表达式的值为false。
将布尔类型的值输出到控制台时,会输出为1(true)或0(false)。
字符类型
字符型char需要用单引号"'"包围。
char型实际上也属于整型,可以通过将字符类型的值赋值给整型变量以得出该结论。这种情况下,字符类型的值会转换成ASCII码。
ASCII码对照表:https://tool.oschina.net/commons?type=4