实型(浮点型)
- float定义时记得后面加f,如float f1 = 3.14f;
- 默认情况下,C++输出一个小数会显示6位有效数字
- 科学计数法:float f = 3e2; //3 * 10^2
字符型
- 创建字符型,char,需要用单引号,不能用双引号,且只能有一个字符,只存储1个字节
- 1个字节=8bit=xxxxxxxx=2个16进制字符
- 字符型变量是将对应的ASCII编码存入到存储空间
- 注意char不能存储汉字,汉字占2个字节
- 字符型的ASCII码查询:(int)ch
- A=65, a=97
转义字符
- 常见:\n \ \t
- \t: 制表符,8个字符为一个完整的TAB
字符串
- C风格:char 变量名[] = “字符串值”
- C++风格:string 变量名 = “字符串值”(需要#include)
char str1[] = "abc";
cout << "str1: " << sizeof(str1) << endl;
输出str1: 4
布尔
数据的输入
运算符
算术运算符
- 注意取模运算:10%20=10,小数之间不能做取模运算
- 两个整数相除,结果依然为整数;若要得到小数部分,则变量应该为浮点类型
#include
using namespace std;
int main()
{
int a = 10;
int b = 3;
cout << a / b << endl;
}
结果为3
赋值运算符
比较运算符
逻辑运算符
程序流程结构
选择结构
条件判断
- 注意if(条件)后面不要加分号
- 单行格式if语句:if(条件){ 条件满足执行的语句 }
- 多行格式if语句:if(条件){ 条件满足执行的语句 }else{ 条件不满足执行的语句 };
- 多条件的if语句:if(条件1){ 条件1满足执行的语句 }else if(条件2){条件2满足执行的语句}… else{ 都不满足执行的语句}
三目运算符
- 如:c = a > b ? a : b;
- 和if语句比较,三目运算符优点是短小整洁,缺点是如果用嵌套,结构不清晰。
#include
using namespace std;
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = a > b ? a : b;
cout << "c = " << c << endl;
}
结果为20
switch语句
- switch语句中表达式类型只能是整型或者字符型,不能表示区间(if可以)
- case里如果没有break,那么程序会一直向下执行
- 与if语句比,对于多条件判断时,switch的结构清晰,执行效率高,缺点是switch不可以判断区间
循环结构
C++生成随机数
添加随机数种子,其作用是利用当前系统时间生成随机数,防止每次随机数都一样
#include
srand((unsigned int)time(NULL));
int num = rand() % 100 + 1;
do while循环
#include
#include
using namespace std;
int main()
{
int num = 100;
do
{
int a = num / 100;
int b = (num - a * 100) / 10;
int c = num % 10;
if (pow(a, 3) + pow(b, 3) + pow(c, 3) == num)
{
cout << num << endl;
}
num += 1;
} while (num <= 999);
}
for循环
- for (int i = 0; i < 10; i++)
- for循环中的表达式,要用分号进行分隔
- 注意执行顺序
数组
- 数组就是一个集合,存储了相同类型的数据元素,且数组是由连续的内存地址位置组成的
一维数组
#include
using namespace std;
int main()
{
int arr[5];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
for (int i = 0; i <= 4; i++)
{
cout << arr[i] << endl;
}
int arr[5] = { 10, 20, 30, 40, 50 };
for (int i = 0; i <= 4; i++)
{
cout << arr[i] << endl;
}
int arr[] = { 10, 20, 30, 40, 50 };
for (int i = 0; i <= 4; i++)
{
cout << arr[i] << endl;
}
}
sizeof:统计长度
int:获取十进制首地址;注意获取数组首地址为(int)arr; 获取元素地址为(int)&arr[0]
数组名是常量,不可以进行赋值操作
代码示例
#include
using namespace std;
int main()
{
int arr[] = { 10, 20, 30, 40, 50 };
for (int i = 0; i <= 4; i++)
{
cout << arr[i] << endl;
}
cout << "size of arr: " << sizeof(arr) << endl;
cout << "size of element: " << sizeof(arr[0]) << endl;
cout << "sum of element: " << sizeof(arr) / sizeof(arr[0]) << endl;
cout << "address of arr(16): " << arr << endl;
cout << "address of arr(10): " << (int)arr << endl;
cout << "address of arr[0]: " << (int)&arr[0] << endl;
cout << "address of arr[1]: " << (int)&arr[1] << endl;
}
10
20
30
40
50
size of arr: 20
size of element: 4
sum of element: 5
address of arr(16): 004FFBE4
address of arr(10): 5241828
address of arr[0]: 5241828
address of arr[1]: 5241832
二维数组
定义
数据类型 数组名【行数】【列数】= {{数据1, 数据2}, {数据3, 数据4}}
int arr[2][3] =
{
{1, 2, 3},
{4, 5, 6}
};
用途
int main()
{
int arr[2][3] =
{
{1, 2, 3},
{4, 5, 6}
};
cout << "arr所占内存空间: " << sizeof(arr) << endl;
cout << "arr第一行所占内存空间: " << sizeof(arr[0]) << endl;
cout << "arr第一个元素所占内存空间: " << sizeof(arr[0][0]) << endl;
cout << "arr的行数: " << sizeof(arr) / sizeof(arr[0]) << endl;
cout << "arr的列数: " << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;
cout << "arr的首地址: " << int(arr) << endl;
cout << "arr的第一行首地址: " << int(arr[0]) << endl;
cout << "arr的第二行首地址: " << int(arr[1]) << endl;
cout << "arr的第一行第一个首地址: " << int(&arr[0][0]) << endl;
}
arr所占内存空间: 24
arr第一行所占内存空间: 12
arr第一个元素所占内存空间: 4
arr的行数: 2
arr的列数: 3
arr的首地址: 9434984
arr的第一行首地址: 9434984
arr的第二行首地址: 9434996
arr的第一行第一个首地址: 9434984
函数
定义
返回值类型 函数名(参数列表) {函数体语句 return表达式}
声明
- 目的:告诉编译器函数名称及如何调用函数
- 函数的声明可以多次,但是函数的定义只能有一次
#include
using namespace std;
int max(int a, int b);
int main()
{
int num1 = 10;
int num2 = 20;
int res = max(num1, num2);
cout << res << endl;
}
int max(int a, int b)
{
return a > b ? a : b;
}
值传递
如果形参发生,并不会影响实参(调用函数时,形参num1和num2会独立分配内存空间,不会影响实参a和b的内存空间,即实参不会改变)
函数分文件编写
1 创建头文件(.h)
2 创建源文件(.cpp)
3 在头文件写函数的声明
4 在源文件写函数的定义
swap.h
#pragma once
#include
using namespace std;
void swap(int a, int b);
swap.cpp
#include "swap.h"
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
main.cpp
#include
#include "swap.h"
using namespace std;
int main()
{
int a = 10;
int b = 20;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(a, b);
}
指针
定义和作用
定义:指针变量用于保存地址,指针就是地址,指针前加*代表解引用,找到指针指向内存中的数据
作用:通过指针间接访问内存
#include
using namespace std;
int main()
{
int a = 10;
int* p;
p = &a;
cout << "a 地址: " << &a << endl;
cout << "指针p所指向的地址: " << p << endl;
cout << "指针p指向地址的数据: " << *p << endl;
int b = 10;
int* q = &b;
}
a 地址: 00B3FEBC
指针p所指向的地址: 00B3FEBC
指针p指向地址的数据: 10
所占内存空间
x64为64位编译器,指针占8个字节; x86为32位编译器,指针占4个字节;与数据类型无关
空指针和野指针
注意空指针和野指针
空指针
- 定义:指针变量指向内存中编号为0的空间,即*int p = NULL;
- 作用:初始化指针变量(当不清楚指针变量指向哪一块内存空间时可用)
- 注意:0-255之间的内存编号是系统占用的,不可访问or修改,因此空指针无法访问
野指针
- 定义:指针变量指向非法的内存空间,如**int p = (int )0x1100;
- 注意:不可访问or修改
const修饰指针
关键是看const的位置来确定修饰的是指针还是常量
- const int _p为常量指针,_p的操作不被允许,即不能修改指针指向的值;
- int * const p为指针常量,p的操作不被允许,即不能修改指针的指向;
常量指针(const修饰指针)
int a = 10; const int * p = &a;
指针的指向可以修改(如p = &b),但指针指向的值不可以修改(如*p=20是不允许的)
指针常量(const修饰常量)
int a = 10; int * const p = &a;
指针的指向不可以修改(如p = &b不允许),但指针指向的值可以修改(如*p=20)
代码示例
#include
using namespace std;
int main()
{
int a = 10;
int b = 20;
int const* p = &a;
cout << "a的地址: " << &a << endl;
cout << "b的地址: " << &b << endl;
cout << "指针p: " << p << endl;
p = &b;
cout << "指针p: " << p << endl;
int c = 10;
int d = 20;
int * const q = &c;
cout << "c的值: " << c << endl;
cout << "d的值: " << d << endl;
cout << "指针q的内存数据: " << *q << endl;
*q = 20;
cout << "指针q的内存数据: " << *q << endl;
}
a的地址: 012FFEB0
b的地址: 012FFEA4
指针p: 012FFEB0
指针p: 012FFEA4
c的值: 10
d的值: 20
指针q的内存数据: 10
指针q的内存数据: 20
指针和数组
注:指针+1,地址会根据数据类型进行增加,如下例为int型,因此地址为加4
#include
using namespace std;
int main()
{
int arr[10] = { 1, 2, 3, 4, 5 };
int* p = arr;
cout << "第一个元素: " << *p << endl;
p += 1;
cout << "第二个元素: " << *p << endl;
int* q = arr;
for (int i = 0; i < 5; i++)
{
cout << "q的地址为: " << q << endl;
cout << "第" << i << "个元素为: " << *q << endl;
q += 1;
}
}
第一个元素: 1
第二个元素: 2
q的地址为: 00AFFD20
第0个元素为: 1
q的地址为: 00AFFD24
第1个元素为: 2
q的地址为: 00AFFD28
第2个元素为: 3
q的地址为: 00AFFD2C
第3个元素为: 4
q的地址为: 00AFFD30
第4个元素为: 5
指针和函数
#include
using namespace std;
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "swap1 a = " << a << endl;
cout << "swap1 b = " << b << endl;
}
void swap2(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
cout << "swap2 a = " << *a << endl;
cout << "swap2 b = " << *b << endl;
}
int main()
{
int a = 10;
int b = 20;
swap1(a, b);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap2(&a, &b);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
swap1 a = 20
swap1 b = 10
a = 10
b = 20
swap2 a = 20
swap2 b = 10
a = 20
b = 10
结构体
作用
属于用户自定义的数据类型,允许用户存储不同的数据类型
定义
struct 结构体名 {结构体成员列表};
struct Student
{
string name;
int age;
int score;
};
使用
Student s1;
s1.name = "Mike";
s1.age = 25;
s1.score = 100;
cout << "name: " << s1.name << " age: " << s1.age << " score: " << s1.score << endl;
Student s2 = { "Joy", 24, 90 };
cout << "name: " << s2.name << " age: " << s2.age << " score: " << s2.score << endl;
结构体数组
struct 结构体名 数组名[元素个数] = {{}, {}, …, {}};
Student s[3] =
{
{"Mike", 25, 100},
{"Joy", 24, 95},
{"Tom", 23, 90}
};
结构体指针
通过指针访问结构体中的成员,使用操作符->
进行访问
Student s = { "Joy", 24, 90 };
Student* p = &s;
cout << "name: " << p->name << " age: " << p->age << " score: " << p->score << endl;
结构体中const的使用
- 使用指针而非值传递, 一来可以减少内存空间占用(一个指针4个字节), 二来不会复制新的副本(值传递会拷贝一份副本,增加了内存占用),更适合大规模的数据处理
- 使用const来修饰结构体,可以防止对结构体的属性进行一些误操作.
void print(const Student* p)
{
cout << "print(地址传递) name: " << p->name << " age: " << p->age << " score: " << p->score << endl;
}
通讯录管理系统
几个值得注意的点
1 定义结构体时,由于需要查询到目前Person数组的元素个数,因此需要size,这里使用AddressBooks结构体来加以表示
2 isExist()存在的原因在于删改查时,需要定位到指定姓名的索引号
3 若system(“pause”)出现system不明确的问题,则**#include**
4 清屏操作——system(“cls”)
参考链接
黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难(P1-P83)