c++初识
创建项目
编写“HelloWorld”代码
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!\n";
}
注释
单行注释 //表述信息
多行注释 /*表述信息*/
变量
作用:给一段指定的内存空间起名,方便操作这段内存
语法: 数据类型 变量名 = 初始值;
变量存在的意义:方便我们管理内存空间
示例:
#include <iostream>
using namespace std;
int main()
{
int a = 10;
cout << a << "\n";
cout << "Hello World!\n";
}
常量
作用:用于记录程序中不可更改的数据
C++定义常量的两种方式
1. #define 宏常量: #define 常量名 常量值
- 通常在文件上方定义,表示一个常量
2. const 修饰的变量 const 数据类型 常量名 = 常量值;
- 通常在变量定义前加关键字const,修饰该变量为常量,不可修改
#include <iostream>
using namespace std;
//define 定义宏常量
#define weekDay 7
int main()
{
cout << "一周有" << weekDay << "天" << endl;
//const修饰变量
const int month = 12;
cout << "一年有" << month << "月" << endl;
}
关键字
作用:关键字是C++中预先保留的单词(标识符)
注:关键字不可以做为变量的名称
标识符命名规则
作用:C++规定给标识符(变量、常量)命名时,有一套自己的规则
- 标识符不能是关键字
- 标识符只能由字母、数字、下划线组成
- 标识符是区分大小写的
- 第一个字符必须为字母或下划线
数据类型
C++规定在创建一个变量或者常量时,必须要指定出相应的教据类型,否则无法给变量分配内存
整型
作用:整型变是表示的是整数类型的数据
C++中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同:
数据类型 | 占用空间 | 取值范围 |
short(短整型) | 2字节 | (-2^15~2^15-1) |
int(整型) | 4字节 | (-2^31 ~2^31-1) |
long(长整型) | Windows为4字节,Linux为4字节(32位),8字节(64位) | (2^31 ~2^31-1) |
long long(长长整型) | 8字节 | (-2^63~2^63-1) |
sizeof关键字
作用:利用sizeof关键字可以统计数据类型所占内存大小
语法:sizeof( 数据笑型 /变量)
#include<iostream>
using namespace std;
int main() {
//short(2) int(4) long(4) long long (8)
short a = 100;
cout << "short 数据类型所占字节为" << sizeof(short) << endl;
cout << "short 数据类型所占字节为" << sizeof(a) << endl;
int b = 100;
cout << "int 数据类型所占字节为" << sizeof(int) << endl;
cout << "int 数据类型所占字节为" << sizeof(b) << endl;
long c = 100;
cout << "long 数据类型所占字节为" << sizeof(long) << endl;
cout << "long 数据类型所占字节为" << sizeof(c) << endl;
long long d = 1000;
cout << "long long 数据类型所占字节为" << sizeof(long long) << endl;
cout << "long long数据类型所占字节为" << sizeof(d) << endl;
}
实型(浮点型)
作用:用于表示小数
浮点型变量分为两种:
1.单精度float
2.双精度double
数据类型 | 占用空间 | 有效数宁范围 |
float | 4字节 | 7位有效数字 |
double | 8字节 | 15-16位有效数字 |
格式:
float 变量 = 数值f;
double 变量名 = 数值;
注:float数据类型变量后面必须加f,一般默认小数的数据类型为double,不加f会进行强制数据转换,造成数据丢失
示例:
#include<iostream>
using namespace std;
int main() {
//float
float f1 = 3.1415f;
//double
double f2 = 3.1415926;
//科学计数法
float f3 = 3e2;//3*10^2
float f4 = 3e-2;//3*0.1^2
cout << f1 << endl;
cout << f2 << endl;
cout << f3 << endl;
cout << f4 << endl;
}
字符型
作用:字符型变量用于显示单个字符
语法:char ch = 'a';
注意1:在显示字符型变量时,用单引号将字符括起来,不要用双引号
注意2:单引号内只能有一个字符,不可以是字符串
C和C++中字符型变是只占用1个字节
字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元
示例:
#include<iostream>
using namespace std;
int main() {
//1. 创建字符型变量
char ch = 'a';
cout << ch << endl;
//2. 字符型数据类型所占的内存大小
cout << "char字符型变量所占内存:" << sizeof(char) << endl;
//3. 字符型变量对应的ASCLL码
cout << (int)ch << endl;
//4. 字符型变量相加
cout << int('a' + 'b') << endl;
}
转义字符
作用:用于表示一些不能显示出来的ASCII字符
转义字符 | 含义 | ASCII码值(十进制) |
\a | 警报 | 007 |
\b | 退格(BS)。当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF),将当前位置移到下一行开头 | 010 |
\r | 回车(CR),将当前位置移到本行开头 | 013 |
\t | 水平制表(HT),跳到下一个TAB位置 | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符"\" | 092 |
\' | 代表一个单引号(撒号)字符 | 039 |
\" | 代表一个双引号字符 | 034 |
\? | 代表一个问号 | 063 |
\0 | 数字0 | 000 |
\ddd | 8进制转义字符,d范围0-7 | 3位8进制 |
\xhh | 16进制转义字符,f,A~F | 3位16进制 |
字符串型
作用:用于表示一串字符
两种风格
1. c风格字符串: char 变量名[] = "字符串值"
2. c++风格字符串: string 变量名 = "字符串值"
字符串值:
#include<iostream>
using namespace std;
int main() {
//1.C风格字符串
char str[] = "hello world";
cout << str << endl;
//2. C++风格字符串
string str2 = "hello world";
cout << str2 << endl;
}
布尔类型bool
作用:布尔数据类型代表真或假的值
bool类型只有两个值:
true -真(本质是1)
false -假(本质是0)
示例:
#include<iostream>
using namespace std;
int main() {
//1.创建布尔类型的值并输出
bool flag = true;
cout << flag << endl;
flag = false;
cout << flag << endl;
//2.查看bool类型所占内存空间
cout << "bool类型所占内存空间:" << sizeof(bool) << endl;
}
注:
bool类型处了0代表假,其他都为真
示例:
数据的输入
作用:用于从健盘获取数据
#include<iostream>
using namespace std;
int main() {
1.整型
//int a = 0;
//cout << "请给整型a赋值" << endl;
//cin >> a;
//cout << a << endl;
2.浮点型
//float b;
//cout << "请给浮点型b赋值" << endl;
//cin >> b;
//cout << b << endl;
3.字符型
//char c;
//cout << "请给字符型c赋值" << endl;
//cin >> c;
//cout << c << endl;
4.字符串型
//string d;
//cout << "请给字符串型d赋值" << endl;
//cin >> d;
//cout << d << endl;
//5.布尔类型
bool e;
cout << "请给布尔类型e赋值" << endl;
cin >> e;
cout << (bool)e << endl;
}
注:
bool类型的输入只有0和1两种
在bool类型的输入时,当你输入字符串"true"时,cin
尝试将这个字符串转换为一个整数。由于"true"并不是一个有效的整数表示形式,转换失败,并且很可能导致输入流进入错误状态。如果cin
成功读取了一些字符并且它们可以转换为数字(例如,你输入的是"1true",那么它会读取前面的1
),剩余的部分(即"true")会被留在输入流中,但这并不是你期望的行为。
要正确地处理布尔类型的输入,你应该输入1
代表true
,或者0
代表false
。如果你确实需要从文本输入(如"true"或"false")中读取布尔值,你需要自己编写逻辑来处理这种转换,例如使用条件语句检查输入的字符串并相应地设置布尔变量。
#include <iostream>
#include <string>
int main() {
bool e;
std::string input;
std::cout << "请给布尔类型e赋值 (输入 true 或 false): ";
std::cin >> input;
if (input == "true") {
e = true;
} else if (input == "false") {
e = false;
} else {
std::cout << "输入错误,请输入 true 或 false。" << std::endl;
return 1;
}
// 使用布尔变量e...
std::cout << "布尔变量e的值是: " << std::boolalpha << e << std::endl;
return 0;
}
运算符
作用:用于执行代码的运算
运算符类型 | 作用 |
算术运算符 | 用于处理四则运算 |
赋值运算符 | 用于将表达式的值赋给变量 |
比较运算符 | 用于表达式的比较,并返回一个真值或假值 |
逻辑运算符 | 用于根据表达式的值返回真值或假值 |
算数运算符
作用:用于处理四则运算
赋值运算符
作用:用于将表达式的值赋给变量
比较运算符
作用:用于表达式的比较,并返回一个真值或假值
逻辑运算符
作用:用于根据表达式的值返回真值或假值
程序流程结构
循环结构C/C++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构
顺序结构:程序按顺序执行,不发生跳转
选择结构:依据条件是否满足,有选择的执行相应功能
循环结构:依据条件是否满足,循环多次执行某段代码
选择结构
if语句
作用:执行满足条件的语句
If语句的三种形式:单行格式If语句、多行格式if语句、多条件的if语句
单行格式If语句 if(条件){条件满足执行的语句}
多行格式if语句 if(条件){条件满足执行的语句}else{条件不满足执行的语句 };
多条件的if语句 if(条件1){条件1满足执行的语句} else if(条件2){条件2满足执行的语句}.....else{都不满足执行的语句}
嵌套if语句:在I语句中,可以嵌套使用if语句,达到更精确的条件判断
三目运算符
作用:通过三目运算符实现简单的判断
语法:表达式1 ? 表达式2 : 表达式3
解释:
如果表达式1的估为真,执行表达式2,并返回表达式2的结果
如果表达式1的值为假,执行表达式3,并返回表达式3的结果
示例:、
#include<iostream>
using namespace std;
int main() {
//输出1和2哪个大
cout << (1 > 2 ? 1 : 2) << endl;
}
switch语句
作用:执行多条件分支语句
语法:
循环结构
while循环语句
作用:满足循环条件,执行循环语句
语法:
while(循环条件){循环语句}
解释:只要循环条件的结果为真,就执行循环语句
do...while循环语句
作用:满足循环条件,执行循环语句
语法:do{循环语句 } while(循环条件);
注意:与while的区别在于do..while会先执行一次循环语句再判断循环条件
for循环语句
作用:满足循环条件,执行循环语句
语法:for(起始表达式;条件表达式;末尾循环体){循环语句;}
跳转语句
break语句
作用: 用于跳出选择结构或者循环结构
break使用的时机:
出现在switch条件语句中,作用是终止上case并跳出switch
出现在循环语句中,作用是跳出当前的循环语句
出现在嵌套循环中,跳出最近的内层循环语句
continue语句
作用:在循环语句中跳过本次循环中余下尚未执行的语句,继续执行下一次循环
goto语句
作用:可以无条件跳转语句
语法:
goto 标记;
解释:如果标记的名称存在,执行到goto语句时,会跳转到标记的位置
示例:
#include<iostream>
using namespace std;
int main() {
cout << "1.xxx" << endl;
goto flag;
cout << "2.xxx" << endl;
cout << "3.xxx" << endl;
flag:
cout << "4.xxx" << endl;
}
数组
一维数组
一维数组定义方式
一维数组定义的三种方式:
1.数据类型 数组名[数组长度 ];
2.数据炎型数组名[数组长度 ] = {值1,值2...};
3.数据类型数组名[]={值1,值2 ...};
注:数组的下标从0开始
一维数组名称的用途:
1.可以统计整个数组在内存中的长度
2.可以获职教组在内存中的首地址
#include<iostream>
using namespace std;
int main() {
int arr[2][3] = {
{1,2,3},
{4,5,6}
};
cout << "二维数组占用内存空间为:" << sizeof(arr) << endl;
cout << "二维数组第一行占用内存为:" << sizeof(arr[0]) << endl;
cout << "二维数组第一个元素占用的内存空间为:" << sizeof(arr[0][0]) << endl;
cout << "二维数组的行数为:" << sizeof(arr)/sizeof(arr[0]) << endl;
cout << "二维数组的列数为:" << sizeof(arr[0])/sizeof(arr[0][0]) << endl;
cout << "二维数组的首地址为:" << (int)arr<< endl;
cout << "二维数组第一行首地址为:" << (int)arr[0] << endl;
cout << "二维数组的二行首地址为" << int(arr[0] + sizeof(arr[0]) / sizeof(arr[0][0])) << endl;
cout << "二维数组的二行首地址为" << int(arr[1])<< endl;
cout << (int)(&arr[0] + sizeof(arr[0]) / sizeof(arr[0][0])) << endl;
}
二维数组
二维数组定义的四种方式:
1.数据类型数組名[行数 ][ 列数 ];
2致据类型数組名[ 行数 ][ 列数 ]={{数据1,数2 },{致据3,数据4 }};
3. 数据类型数姐名[行数][ 列数 ]-{数据1,数据2,数据3,数据4};
4. 数据类型 数组名[ |[ 列数 ]-{数据1,数据2,数据3,数据4};
建议:以上4种定义方式,利用第二种更加直观,提高代码的可读性
总结:在定义二维数组时,如果初始化了数据,可以省略行数
函数
概述
作用:将一段经常便用的代码封装起来,减少重复代码一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能,
函数的定义
函数的定义一般主要有5个步骤:
1、返回值类型
2、函数名
3、参数表列
4、函数体语句
5、return 表达式
返回值类型:一个的数可以返回一个值,在的数定义中
函数名:给函数起个名称
参数列表:使用该函数时,传入的数据
函数体语句:花括号内的代码,虽数内需要执行的语句
return表达式:和返回值类型挂钩,函数执行完后,返回相应的教据
函数的调用
#include<iostream>
using namespace std;
int add(int num1, int num2) {
return num1 + num2;
}
int main() {
int a = 10;
int b = 20;
int c = add(a, b);
cout << c << endl;
}
注:a和b称为 实际参数,简称实参
当调用函数时候,实参的值会传递给形参
num1和num2为形参
值传递
- 所谓值传递,就是函数调用时实参将数值传入给形参
- 值传递时,如果形参发生,并不会影响实参
函数的声明
当函数的定义在main函数之前则不需要声明,若在main之后则需要先声明
示例:
如下图所示,不声明函数并将函数定义在main函数之后
正确声明并调用函数
#include<iostream>
using namespace std;
int add(int num1, int num2);
int main() {
int a = 10;
int b = 20;
int c = add(a, b);
cout << c << endl;
}
int add(int num1, int num2) {
return num1 + num2;
}
注:声明可以写多次,定义只可以写一次
函数的分文件编写
作用:让代码结构更加清晰
函数分文件编写一般有4个步骤
1.创建后缀名为.h的头文件
2.创建后缀名为,cpp的源文件
3.在头文件中写函数的声明
4.在源文件中写函数的定义
指针
指针的作用:可以通过指针间接访问内存
- 内存编号是从0开始记录的,一般用十六进制数字表示
- 可以利用指针变量保存地址
指针定义的语法: 数据类型 *指针变量名:
示例:
#include<iostream>
using namespace std;
int main() {
int a = 10;
//1. 定义指针
int* p;
//让指针记录变量a的地址
p = &a;
cout << "a的地址为:" << &a << endl;
cout << "指针p所指向的地址为:" << p << endl;
//2.使用指针
//可以通过解引用的方式来找到指针指向的内存
//指针前加 *代表解引用,找到指针指向的内存中的数据
*p = 1000;
cout << "a=" << a << endl;
cout << "*p=" << *p << endl;
}
指针所占内存空间
在 32位操作系统下: 占用4个字节空间,64位下占8个字节
空指针和野指针
空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的
野指针:指针变是指向非法的内存空间
示例:
#include<iostream>
using namespace std;
int main() {
//指针变量p指向内存地址编号为0x1100空间
int* p = (int*)0x1100;
//方位野指针报错
cout << *p << endl;
}
注:指针变量不能注册内存空间,只能赋值
const修饰指针
const修饰指针有三种情况
1.const修饰指针 … 常量指针
- 指针的指向可以修改,但是指针指向的值不可以改
- const int * p = &a;
2.const修饰常量 … 指针常量
- 指针的指向不司以改,指计指向的值可以改
- 例: int * const p = &a;
3.const即修饰指针,又修饰常量
- 例:const int * const p = &a;
指针和数组
示例:
#include<iostream>
using namespace std;
int main() {
//利用指针访问数组中的元素
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
cout << "第一个元素为:" << arr[0] << endl;
int* p = arr;
cout << "利用指针访问数组第一个元素:" << *p << endl;
p++;//让指针向后偏移4个字节
cout << "利用指针访问数组第二个元素:" << *p << endl;
}
指针与函数
#include<iostream>
using namespace std;
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int a = 10;
int b = 20;
swap(&a, &b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
}
结构体
结构体基本概念
结构体属于用户自定义的数据类型允许用户存储不同的数据类型
结构体定义和使用
语法:struct结构体名{结构体成员列表 };
通过结构体创建变量的方式有三种:
- struct 结构体名 变量名
- struct 结构体名 变晕名={成员1值,成员2值...]}
- 定义结构体时顺便创建变量
示例:
#include<iostream>
using namespace std;
struct student {
string name;
int age;
int score;
}s3;
int main() {
//结构体定义与使用
// struct 结构体名 变量名
struct student s1;
s1.name = "张三";
s1.age = 18;
s1.score = 100;
cout << "姓名:" << s1.name << "年龄:" << s1.age << "分数" << s1.score << endl;
//struct 结构体名 变晕名={成员1值,成员2值...}
struct student s2 = { "李四",12,100 };
cout << "姓名:" << s2.name << "年龄:" << s2.age << "分数" << s2.score << endl;
//定义结构体时顺便创建变量
s3 = { "王五",13,100 };
cout << "姓名:" << s1.name << "年龄:" << s1.age << "分数" << s1.score << endl;
}
注:在定义结构体变量时可以不用加struct (结构体名 变量名)
结构体数组
作用:将自定义的结构体放入到数组中方便维护
语法:结构体名 数祖名[元素个数] = {{},{},.....}
示例:
#include<iostream>
using namespace std;
//创建结构体
struct student {
string name;
int age;
int score;
};
int main() {
//创建结构体数组
struct student stuArray[3] = {
{"lili",12,100},
{"jack",12,100},
{"mike",13,100}
};
//遍历结构体数组中的数据
for (int i = 0; i < 3; i++) {
cout << "姓名:" << stuArray[i].name
<< "年龄:" << stuArray[i].age
<< "分数" << stuArray[i].score << endl;
}
}
结构体指针
作用:通过指针访问结构体中的成员
利用操作符 -> 可以通过结构体指针访问结构体属性
示例:
#include<iostream>
#include<string>
using namespace std;
//创建结构体
struct student {
string name;
int age;
int score;
};
int main() {
//创建学生结构体变量
struct student s2 = { "李四",12,100 };
//通过指针指向结构体变量
student* p = &s2;
//通过指针访问结构体变量中的数据
cout << "姓名:" << p->name
<< "年龄:" << p->age
<< "分数" << p->score << endl;
}
结构体嵌套结构体
作用: 结构体中的成员可以是另一个结构体
例如:每似老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体
示例:
#include<iostream>
#include<string>
using namespace std;
//创建结构体
struct student {
string name;
int age;
int score;
};
struct teacher {
int id;
string name;
int age;
struct student stu;
};
int main() {
teacher t;
t= { 1,"lucy",30,{"lili",13,100}};
cout <<"老师编号:"<<t.id
<< "老师姓名:" <<t.name
<<"老师年龄" << t.age
<< "学生姓名:" << t.stu.name
<< "学生年龄:" << t.stu.age
<< "学生分数" << t.stu.score << endl;
}
结构体做函数参数
作用:将结构体作为参数向函数中传递传递方式有两种
- 值传递
- 地址传递
#include<iostream>
using namespace std;
//创建结构体
struct student {
string name;
int age;
int score;
};
//值传递
void printStu(student s1) {
cout << "姓名:" << s1.name
<< "年龄:" << s1.age
<< "分数" << s1.score << endl;
}
//址传递
void printStu2(student* p) {
cout << "姓名:" << p->name
<< "年龄:" << p->age
<< "分数" << p->score << endl;
}
int main() {
struct student s2 = { "李四",12,100 };
student* p = &s2;
printStu(s2);
printStu2(p);
}
结构体中const使用场景
作用:用const来防止误操作
示例1:若相对结构体变量中其中一个变量设置为不可更改则如下
#include<iostream>
using namespace std;
//创建结构体
struct student {
string name;
const int age;
int score;
};
//址传递
//将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
void printStu2(student* p) {
//p->age = 200;
cout << "姓名:" << p->name
<< "年龄:" << p->age
<< "分数" << p->score << endl;
}
int main() {
struct student s2 = { "李四",12,100 };
student* p = &s2;
printStu2(p);
}
示例2:使结构体变量整体都不可修改
void printStu2(const student* p) {
p->age = 200;
cout << "姓名:" << p->name
<< "年龄:" << p->age
<< "分数" << p->score << endl;
}