C++基础入门
文章目录
helloworld
#include<iostream>
using namespace std;
int main() {
cout << "helloworld!" << endl;
system("pause");
return 0;
}
注释
- 单行注释:
// 描述信息
- 通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明
- 多行注释:
/* 描述信息 */
- 通常放在一段代码的上方,对该段代码做整体说明
变量
//变量的定义
//语法:数据类型 变量名 = 初始值
int a = 10;
cout << "a = " << a << endl;
数据类型
整型
数据类型 | 占用空间 | 取值范围 |
---|---|---|
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
int b = 5;
cout << "字节为" << sizeof(int) << endl;
cout << "字节为" << sizeof(short) << endl;
cout << "字节为" << sizeof(long) << endl;
cout << "字节为" << sizeof(long long) << endl;
cout << "字节为" << sizeof(b) << endl;
实型
两者的区别在于表示的有效数字范围不同。
数据类型 | 占用空间 | 有效数字范围 |
---|---|---|
float | 4字节 | 7位有效数字 |
double | 8字节 | 15~16位有效数字 |
//float double
float f1 = 3.15555f;
float f2 = 3e-4f;
double b1 = 3.1111;
cout <<f1<<"字节为" << sizeof(f1) << endl;
cout <<f2<<"字节为" << sizeof(f2) << endl;
cout <<f2<<"字节为" << sizeof(0.01f) << endl;
cout <<f2<<"字节为" << sizeof(0.01) << endl;
cout <<b1<<"字节为" << sizeof(b1) << endl;
字面量也是有类型的。
例如,3是int型字面量,3.0是double型字面量,3.0f是float型字面量,'3’是char型字面量。
如果用一个double型字面量去初始化或者赋值给一个float型变量,则会发生隐式类型转换,因为double型值的二进制位模式与float型值的二进制位模式是不同的。这么做不是好习惯。
字符型
**作用:**字符型变量用于显示单个字符
语法:char ch = 'a';
注意1:在显示字符型变量时,用单引号将字符括起来,不要用双引号
注意2:单引号内只能有一个字符,不可以是字符串
-
C和C++中字符型变量只占用1个字节。
-
字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元
[char c = 'bbbb'; //char c2 = "bbbb"; 报错 char c3 = 'c'; cout << c << endl; //输出 b cout << c3 << endl; //转义字符 cout << "\\aa" << endl; cout << " \nbb " << endl; cout << " \tcc " << endl;
字符转型
//c语言
char str1[] = "dkfje";
// c++
string str2 = "fdke";
cout << str1 << endl;
cout << str2 << endl;
布尔类型 bool
**作用:**布尔数据类型代表真或假的值
bool类型只有两个值:
- true — 真(本质是1)
- false — 假(本质是0)
bool类型占1个字节大小
bool t = true;
bool f = false;
cout << t << endl; //1
cout <<f << endl; //0
数据输入
int c1 = 0;
double c2 = 0;
float f3 = 0;
char c4 = 0;
string c5 ;
bool c6 = 0;
cin >> c1 >> c2 >> f3 >> c4 >> c5 >> c6;
cout << "---------------" << endl;
cout << c1 << endl;
cout << c2 << endl;
cout << f3 << endl;
cout << c4 << endl;
cout << c5 << endl;
cout << c6 << endl;
运算符
算术运算符
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模(取余) | 10 % 3 | 1 |
++ | 前置递增 | a=2; b=++a; | a=3; b=3; |
++ | 后置递增 | a=2; b=a++; | a=3; b=2; |
– | 前置递减 | a=2; b=–a; | a=1; b=1; |
– | 后置递减 | a=2; b=a–; | a=1; b=2; |
赋值运算符
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
= | 赋值 | a=2; b=3; | a=2; b=3; |
+= | 加等于 | a=0; a+=2; | a=2; |
-= | 减等于 | a=5; a-=3; | a=2; |
*= | 乘等于 | a=2; a*=2; | a=4; |
/= | 除等于 | a=4; a/=2; | a=2; |
%= | 模等于 | a=3; a%2; | a=1; |
比较运算符
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
== | 相等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 1 | 1 |
逻辑运算符
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
! | 非 | !a | 如果a为假,则!a为真; 如果a为真,则!a为假。 |
&& | 与 | a && b | 如果a和b都为真,则结果为真,否则为假。 |
|| | 或 | a || b | 如果a和b有一个为真,则结果为真,二者都为假时,结果为假。 |
程序流程结构
if语句
if(条件){ 条件满足执行的语句 }
多行格式if语句:if(条件){ 条件满足执行的语句 }else{ 条件不满足执行的语句 };
多条件的if语句:if(条件1){ 条件1满足执行的语句 }else if(条件2){条件2满足执行的语句}... else{ 都不满足执行的语句}
三目运算符
作用: 通过三目运算符实现简单的判断
语法:表达式1 ? 表达式2 :表达式3
switch语句
switch(表达式)
{
case 结果1:执行语句;break;
case 结果2:执行语句;break;
...
default:执行语句;break;
}
循环语句
while(循环条件){ 循环语句 }
do{ 循环语句 } while(循环条件);
for(起始表达式;条件表达式;末尾循环体) { 循环语句; }
跳转语句
break语句
作用: 用于跳出选择结构或者循环结构
break使用的时机:
- 出现在switch条件语句中,作用是终止case并跳出switch
- 出现在循环语句中,作用是跳出当前的循环语句
- 出现在嵌套循环中,跳出最近的内层循环语句
continue语句
**作用:**在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
goto语句
**作用:**可以无条件跳转语句
语法: goto 标记;
**解释:**如果标记的名称存在,执行到goto语句时,会跳转到标记的位置
数组
一维数组定义的三种方式:
-
数据类型 数组名[ 数组长度 ];
-
数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
-
数据类型 数组名[ ] = { 值1,值2 ...};
//数据类型 数组名[] = {值1,值2 ,值3 ...}; int score3[] = { 100,90,80,70,60,50,40,30,20,10 }; for (int i = 0; i < 10; i++) { cout << score3[i] << endl; } for (int i = 0; i < 10; i++) { cout << score3[i] << endl; }
一维数组数组名
一维数组名称的用途:
-
可以统计整个数组在内存中的长度
-
可以获取数组在内存中的首地址
//数组名用途 //1、可以获取整个数组占用内存空间大小 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; cout << "整个数组所占内存空间为: " << sizeof(arr) << endl; cout << "每个元素所占内存空间为: " << sizeof(arr[0]) << endl; cout << "数组的元素个数为: " << sizeof(arr) / sizeof(arr[0]) << endl; //2、可以通过数组名获取到数组首地址 cout << "数组首地址为: " << (int)arr << endl; cout << "数组中第一个元素地址为: " << (int)&arr[0] << endl; cout << "数组中第二个元素地址为: " << (int)&arr[1] << endl;
整个数组所占内存空间为: 40
每个元素所占内存空间为: 4
数组的元素个数为: 10
数组首地址为: -649070616
数组中第一个元素地址为: -649070616
数组中第二个元素地址为: -649070612二维数组定义方式
二维数组定义的四种方式:
数据类型 数组名[ 行数 ][ 列数 ];
数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
- ` 数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
//方式2
//数据类型 数组名[行数][列数] = { {数据1,数据2 } ,{数据3,数据4 } };
int arr2[2][3] =
{
{1,2,3},
{4,5,6}
};
//方式3
//数据类型 数组名[行数][列数] = { 数据1,数据2 ,数据3,数据4 };
int arr3[2][3] = { 1,2,3,4,5,6 };
//方式4
//数据类型 数组名[][列数] = { 数据1,数据2 ,数据3,数据4 };
int arr4[][3] = { 1,2,3,4,5,6 };
二维数组数组名
* 查看二维数组所占内存空间
* 获取二维数组首地址
//二维数组数组名
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 << "二维数组首地址:" << arr << endl;
cout << "二维数组第一行地址:" << arr[0] << endl;
cout << "二维数组第二行地址:" << arr[1] << endl;
cout << "二维数组第一个元素地址:" << &arr[0][0] << endl;
cout << "二维数组第二个元素地址:" << &arr[0][1] << endl;
函数的定义
函数的定义一般主要有5个步骤:
1、返回值类型
2、函数名
3、参数表列
4、函数体语句
5、return 表达式
语法:
C++
返回值类型 函数名 (参数列表)
{
函数体语句
return表达式
}
函数的调用
` 函数名(参数)`
值传递时,==如果形参发生,并不会影响实参==
函数的**声明可以多次**,但是函数的**定义只能有一次**
### 函数的分文件编写
**作用:**让代码结构更加清晰
函数分文件编写一般有4个步骤
1. 创建后缀名为.h的头文件
2. 创建后缀名为.cpp的源文件
3. 在头文件中写函数的声明
4. 在源文件中写函数的定义
//swap.h文件
#include<iostream>
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函数文件
#include "swap.h"
int main() {
int a = 100;
int b = 200;
swap(a, b);
system("pause");
return 0;
}
指针
指针变量的定义和使用
指针变量定义语法: 数据类型 * 变量名;
#include<iostream>
using namespace std;
int main() {
int a = 90;
int* p;
p = &a;
cout << a << endl;
cout << p << endl;
cout << *p << endl;
cout << a << endl;
cout << p << endl;
cout << *p << endl;
cout << sizeof(p) << endl;
cout << sizeof(*p) << endl;
cout << sizeof(float *) << endl; //4
cout << sizeof(double *) << endl; //4
cout << sizeof(string *) << endl; //4
cout << sizeof(int *) << endl; //4
cout << sizeof(bool *) << endl; //4
system("pause");
return 0;
}
总结:所有指针类型在32位操作系统下是4个字节
空指针和野指针
int* p1 = NULL;
cout << "---------------" << endl;
cout << p1 << endl;
//cout << *p1 << endl; bug
int* p2 = (int*)0x137FC4C;
cout << p2 << endl;
//cout << *p2 << endl; bug
const修饰指针
const修饰指针有三种情况
-
const修饰指针 — 常量指针
-
const修饰常量 — 指针常量
-
const即修饰指针,又修饰常量
int a = 10;
int b = 10;
//const修饰的是指针,指针指向可以改,指针指向的值不可以更改
//const修饰指针 --- 常量指针
const int * p1 = &a; // 修饰*p 值不可变
p1 = &b; //正确
//*p1 = 100; 报错
//const修饰的是常量,指针指向不可以改,指针指向的值可以更改
//const修饰常量 --- 指针常量
int * const p2 = &a; //修饰p 地址不可变
//p2 = &b; //错误
*p2 = 100; //正确
//const既修饰指针又修饰常量
const int * const p3 = &a;
//p3 = &b; //错误
//*p3 = 100; //错误
指针和数组
int arr[] = { 3,34,34,3,43,43,54,6,5676767434,23,23246,34 };
int* p_arr = arr;
cout << "----------------" << endl;
for (int i = 0; i < sizeof(arr)/(sizeof(arr[0])); i++)
{
cout << arr[i] << endl;
cout << "---*P_a___" << *p_arr << endl;
p_arr++;
}
指针和函数
**作用:**利用指针作函数参数,可以修改实参的值
int swap1(int a, int b)
{
int temp = a;
a=b;
b = temp;
return 0;
}
int* swap1(int* a, int* b)
{
int temp = *a;
*a=*b;
*b = temp;
return 0;
}
int main()
{
int a = 11;
int b = 23;
swap(a, b);
cout << "原有函数的swap" << endl;
cout << "a:" << a << endl;
cout << "b:" << b << endl;
cout << "swap1函数" << endl;
swap1(a, b);
cout << "a:" << a << endl;
cout << "b:" << b << endl;
cout << "swap1函数" << endl;
swap1(&a, &b);
cout << "a:" << a << endl;
cout << "b:" << b << endl;
system("pause");
return 0;
}
原有函数的swap
a:23
b:11
swap1函数
a:23
b:11
swap1函数
a:11
b:23
指针-数组-函数
void buSort(int* arr, int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++) {
if (arr[j] < arr[j + 1]) // 5<9 95 倒序
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void printArr(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << endl;
}
}
int main()
{
int arr[] = { 34,4,34,6576,878784,23,23,3,5,7,6879,89665,423,2e6,34,4,6 };
int len = sizeof(arr) / (sizeof(int));
buSort(arr, len);
printArr(arr, len);
system("pause");
return 0;
}
结构体
结构体定义和使用
语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
- struct 结构体名 变量名
- struct 结构体名 变量名 = { 成员1值 , 成员2值…}
- 定义结构体时顺便创建变量
总结1:定义结构体时的关键字是struct,不可省略
总结2:创建结构体变量时,关键字struct可以省略
总结3:结构体变量利用操作符 ‘’.‘’ 访问成员
结构体
结构体定义和使用
语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
student stu1;
stu1.name = "李四";
stu1.id = 34;
stu1.score = 77;
cout << "姓名:" << stu1.name << "学号:" << stu1.id << "分数" <<stu1.score<< endl;
student stu2[2] = {
{"张三",212,67},{"王五",87,64} //{{}}
};
for (int i = 0; i < 2; i++) {
cout << "姓名:" << stu2[i].name << "学号:" << stu2[i].id << "分数" << stu2[i].score << endl;
}
student stu3 = {"张三",212,67}; //{}
cout << "姓名:" << stu3.name << "学号:" << stu3.id << "分数" << stu3.score << endl;
- struct 结构体名 变量名
- struct 结构体名 变量名 = { 成员1值 , 成员2值…}
- 定义结构体时顺便创建变量
总结1:定义结构体时的关键字是struct,不可省略
总结2:创建结构体变量时,关键字struct可以省略
总结3:结构体变量利用操作符 ‘’.‘’ 访问成员
结构体数组
struct 结构体名 数组名[元素个数] = { {} , {} , ... {} }
结构体指针
student* p = &stu3;
cout<<“p指针” << “姓名:” << p->name << “学号:” << p->id << “分数” << p->score << endl;
结构体嵌套
struct teacher {
int id;
string name;
student stu0;
};
teacher tea;
tea.id = 8;
tea.name = "赵六";
tea.stu0.id = 88;
tea.stu0.name = "红八";
tea.stu0.score = 77;
cout << "id:" << tea.id << " tea.name " << tea.name << " tea.stu0.id " << tea.stu0.id << endl;
值传递和地址传递
void printStudent1(student stu){
cout << "学号:" << stu.id << " 姓名: " << stu.name << " 分数: " << stu.score << endl;
}
void printStudent1(student *stu){
cout << "学号:" << stu->id << " 姓名: " << stu->name << " 分数: " << stu->score << endl;
}
//值传递和地址传递
printStudent1(stu3);
printStudent1(&stu3);
总结:如果不想修改主函数中的数据,用值传递,反之用地址传递
结构体中 const使用场景
void printStudent(const student *stu) //加const防止函数体中的误操作
{
//stu->age = 100; //操作失败,因为加了const修饰
cout << “姓名:” << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;
}
案例1
struct Student
{
string name;
int score;
};
struct Teacher {
string name;
Student stu[2];
};
void allocate(Teacher t[],int len)
{
string str = "ABCDE";
string tName = "教师";
string sName = "学生";
for (int i = 0; i < len; i++)
{
t[i].name = tName + str[i];
int le = sizeof(t[i].stu) / sizeof(t[i].stu[1]);
for (int j = 0; j < le; j++) {
t[i].stu[j].name = sName + str[i];
t[i].stu[j].score = rand()%61+40;
}
};
}
void printStudent(Teacher t[], int len) {
for (int i = 0; i < len; i++) {
cout << "教师姓名: " << t[i].name << endl;
int le = sizeof(t[i].stu) / sizeof(t[i].stu[1]);
for (int j = 0; j < le; j++) {
cout << "\t学生姓名: " << t[i].stu[j].name << " 学生分数: " << t[i].stu[j].score << endl;
}
}
}
int main()
{
Teacher t[3];
string s = "教师";
string seed = "abc";
cout << string("---------------教师aa") + seed[1] << endl;
cout << s+seed[1]<< endl;
int len = sizeof(t) / sizeof(Teacher);
allocate(t, len);
printStudent(t, len);
system("pause");
return 0;
}
cout << string(“---------------教师aa”) + seed[1] << endl; 正常输出
cout << “---------------教师aa” + seed[1] << endl; 不正常输出 // a
案例2
英雄年龄排序
#include<iostream>
using namespace std;
struct Hero
{
string name;
int age;
string sex;
};
void bubbleSort(Hero hero[], int len)
{
for (int i = 0; i < len-1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (hero[j].age<hero[j + 1].age)
{ //5>9 9 5
Hero a = hero[j];
hero[j] = hero[j+1];
hero[j+1] = a;
}
//cout << hero[i].name << "年龄" << hero[i].age << " 性别" << hero[i].sex << endl;
}
}
}
void printHero(Hero hero[], int len)
{
for (int i = 0; i < len; i++) {
cout << hero[i].name << "年龄" << hero[i].age << " 性别" << hero[i].sex<<endl;
}
}
int maindd()
{
Hero hero[5] = {
{"刘备",23,"男"},
{"关羽",22,"男"},
{"张飞",20,"男"},
{"赵云",21,"男"},
{"貂蝉",19,"女"},
};
int len = sizeof(hero) / sizeof(hero[0]);
cout << len << endl;
bubbleSort(hero, len);
printHero(hero, len);
system("pause");
return 0;
}
参考:黑马程序员