C++基础语法
C++初识
第一个C++程序
编写一个C++程序总共分为4个步骤
- 创建项目
- 创建文件
- 编写代码
- 运行程序
创建项目
Visual Studio是我们用来编写C++程序的工具

创建文件



编写代码
#include <iostream> using namespace std; int main() { cout << "hello world" << endl; /* main函数是一个程序的入口 每个程序都必须有这么一个函数 有且仅有一个 */ system("pause"); return 0; }
运行程序

注释
作用:在代码中加一些说明和解释,方便自己或其他程序员阅读代码
两种格式
-
单行注释://说明信息
- 通常放在一行代码上方,或者一条语句的末尾,对该代码说明
-
多行注释:/*说明信息*/
- 通常放在一段代码的上方,对该段代码做整体说明
编译器在执行代码时,会忽略注释的内容
变量
作用:给一段指定的内存空间起名,方便操作这段内存
语法:数据类型 变量名 = 初始值;
示例
#include <iostream> using namespace std; int main() { //变量的创建语法:数据类型 变量名 = 变量初始值 int a = 10; system("pause"); return 0; }
常量
作用:用于记录程序中不可更改的数据
C++定义常量两种方式
#define
宏常量:#define
常量名 常量值- 通常在文件上方定义,表示一个常量
cons
修饰的变量:const
数据类型 变量名 常量值- 通常在变量定义前加关键字
const
,修饰改变量为常量,不可更改
- 通常在变量定义前加关键字
示例
#include <iostream> using namespace std; // 宏常量 #define day 7 int main() { cout << "一周总共有:" << day << "天" << endl; // const修饰变量 const int year = 100; return 0; }
关键字
作用:关键字是C++中预先保留的单词(标识符)
- 在定义变量或者常量的时候,不要使用关键字
标识符命名规则
作用:C++规定给标识符(变量、常量)命名时,有一套自己的规则
-
标识符不能是关键字
-
标识符只能由字母、数字、下划线组成
-
第一个字符必须为字母或者下划线
-
标识符中字母区分大小写
建议:给标识符命名时,争取见名知意的效果
数据类型
C++规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存
整型
作用:整型变量能够表示的是整数类型的数据
C++中能够表示整型的类型有以下几种方式,区别在于所占内存不同
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | -215~215-1 |
int(整型) | 4字节 | -231~231-1 |
long(长整型) | win为4字节、Linux32位为4字节/64位为8字节 | -231~231-1 |
long long(长长整型) | 8字节 | -263~263-1 |
sizeof关键字
作用:利用sizeof
关键字可以统计数据类型所占内存大小
语法:sizeof
(数据类型/变量)
示例
#include <iostream> using namespace std; int main() { int a = 5; cout << sizeof(a) << endl; cout << sizeof(int) << endl; const int year = 100; cout << sizeof(year) << endl; return 0; }
实型(浮点型)
作用:用于表示小数
浮点型分为两种:
- 单精度
float
- 双精度
double
两者的区分在于表示的有效数字范围不同
数据类型 | 占用空间 | 有效数字范围 |
---|---|---|
float | 4bit | 7为有效数字 |
double | 8bit | 15~16位有效数字 |
#include <iostream> using namespace std; int main() { // float float a = 5.6; cout << a << endl; // double double b = 5.6; cout << b << endl; //科学计数法表示 float d = 3e2; //代表 3 * 10 ^ 2 cout << d << endl; return 0; }
字符型
作用:字符型变量用于显示单个字符
语法:char c = "a";
在显示字符型变量时,用单引号键字符括起来,不要用双引号
单引号内只能有一个字符,不可以是字符串
- C++和C中字符型变量只占用1个字节
- 字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放到存储单元
#include <iostream> using namespace std; int main() { // 字符型 char d = 'D'; cout << d << endl; cout << (int)d << endl; // 字符型对应ASCII编码 /* char d = "D"; 创建字符型变量时候,要用单引号 char d = 'hello'; 创建字符型变量时候,单引号内只能有一个数值 */ system("pause"); return 0; }
转义字符
作用:用于表示一些不能显示出来的ASCII字符
常用的转义字符有://、/t、/n
#include <iostream> using namespace std; int main() { // 换行符 \n cout << "Hello World \n"; cout <<"Hello World" << endl; // 反斜杆 \\ cout << "\\" << endl; // 水平制表符 \t 可以整齐输出数据 cout << "Hello \t World"; system("pause"); return 0; }
字符串型
作用:用于表示一串字符
两种风格
-
C风格字符串:
char 变量名[] = "字符串值"
#include <iostream> using namespace std; int main() { char a[] = "hello world"; // 双引号 cout << a <<endl; cout << sizeof(a) << endl; // 12 system("pause"); return 0; } -
C++风格字符串:
string 变量名 = "字符串值"
#include <iostream> #include <string> // 用C++风格字符串的时候,要包含这个头文件 using namespace std; int main() { // 包含一个头文件 string a = "hello world"; cout << a <<endl; cout << sizeof(a) << endl; // 40 system("pause"); return 0; }
布尔数据类型 bool
作用:布尔数据类型代表真或假的值
bool类型只有两个值
- true:真(本质是1)
- false:假(本质是0)
bool类型占一个字节大小
#include <iostream> #include <string> // 用C++风格字符串的时候,要包含这个头文件 using namespace std; int main() { // 创建bool数据类型 bool flag = true; // true代表真 cout << flag << endl; // 本质上,1代表真的值,0代表假的值 // 查看bool类型占用的内存空间 cout << flag << endl; system("pause"); return 0; }
数据的输入
作用:用于从键盘获取数据
语法:cin >> 变量
#include <iostream> #include <string> // 用C++风格字符串的时候,要包含这个头文件 using namespace std; int main() { // 整型 int a = 0; cout << "请输入一个整数:"; cin >> a; cout << "整型变量a = " << a << endl; // 字符串型 string a = "hello"; cout << "请输入一个字符串数:"; cin >> a; cout << "字符串型变量a = " << a << endl; // bool型 bool a = false; // 非空即为真 cout << "请输入一个bool数:"; cin >> a; cout << "bool型变量a = " << a << endl; // 字符型 char a = '0'; cout << "请输入一个字符:"; cin >> a; cout << "字符型变量a = " << a << endl; // 浮点型 float a = 3.14f; cout << "请输入一个浮点数:"; cin >> a; cout << "浮点型变量a = " << a << endl; system("pause"); return 0; }
运算符
作用:用于执行代码的运算
算术运算符
作用:用于处理四则运算
"+" 加, "-" 减, "/" 除, "*" 乘, "%" 取余, "++" 递增, "--"递减
#include <iostream> #include <string> // 用C++风格字符串的时候,要包含这个头文件 using namespace std; int main() { int a = 10; int b = 3; // + cout << a+b << endl; //- cout << a - b << endl; // / 两个整数相除 结果为整数,将小数去除 cout << a / b << endl; // * cout << a * b << endl; // % 两个小数不可进行取余运算 cout << a % b << endl; system("pause"); return 0; }
++ 和 --
#include <iostream> #include <string> // 用C++风格字符串的时候,要包含这个头文件 using namespace std; int main() { // ++ 递增 int a = 10; ++a; // 让变量进行加一的结果,前置递增 a++; // 后置递增 // 前置递增 先进行变量+1,后进行表达式的运算 int b = 10; int c = ++b * 10; cout << "前置b=" << b << endl; cout << "前置c=" << c << endl; // 后置递增 先进行表达式的运算,后让变量+1 int b1 = 10; int c1 = b1++ * 10; cout << "后置b=" << b1 << endl; cout << "后置c=" << c1 << endl; system("pause"); return 0; }
赋值运算符
作用:用于将表达式的值赋给变量
"=" 等于, "+=" 加等于 , "-=" 减等于 , "/=" 除等于 , "%=" 余等于 , "*=" 乘等于
#include <iostream> #include <string> // 用C++风格字符串的时候,要包含这个头文件 using namespace std; int main() { int a = 10; int b = 20; // += a += b; // 相当于:a = a + b cout << a << endl; // -= a -= b; // 相当于:a = a - b cout << a << endl; // /= a /= b; // 相当于:a = a / b cout << a << endl; // *= a *= b; // 相当于a = a * b cout << a << endl; // = a = b - a; cout << a << endl; }
比较运算符
"=="等于 , "<=" 小于等于, ">=" 大于等于 , "!=" 不等于 , "<" 小于 , ">" 大于
返回bool类型
#include <iostream> #include <string> // 用C++风格字符串的时候,要包含这个头文件 using namespace std; int main() { int a = 10; int b = 20; // >= cout << (a >= b) << endl; // <= cout << (a <= b) << endl; // == cout << (a == b) << endl; // != cout << (a != b) << endl; // < cout << (a < b) << endl; // > cout << (a > b) << endl; }
由于运算的优先级,要用括号隔开
逻辑运算符
作用:用于根据表达式的值返回真值或假值
"!" 非 , "&&" 与 , "||" 或
#include <iostream> #include <string> // 用C++风格字符串的时候,要包含这个头文件 using namespace std; int main() { // 逻辑运算符 // ! 真变假、假变真 bool a = true; cout << !a<< endl; // && 两个都为真,则为真;同真则真,其余为假 int a1 = 10; int b = 0; cout << (a1 && b) << endl; // || 只要有一个为真,则为真;同假则假,其余为真 cout << (a1 || b) << endl; // 综合应用 cout << (a1 || !( a1 && ! a ) ); }
程序流程结构
C/C++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构
- 顺序结构:程序按顺序执行,不发生跳转
- 选择结构:依据条件是否满足,有选择的执行相应功能
- 循环结构:依据条件是否满足,循环多次执行某段代码
选择结构
if语句
作用:执行满足条件的语句
if语句的三种形式
- 单行格式if语句
- 多行格式if语句
- 多条件的if语句
单行格式
#include <iostream> using namespace std; int main() { // 选择结构 单行if语句 // 用户输入一个数字 int num = 1; cout << "请输入一个数字:"; cin >> num; // 判断数字是否大于100,是则输出原数 if (num >= 100){ // 注意if语句后面不要加分号,否则,if将不会进行判断 cout << num; } }
多行if语句
#include <iostream> using namespace std; int main() { // 选择结构 单行if语句 // 用户输入一个数字 int num = 1; cout << "请输入一个数字:"; cin >> num; // 判断数字是否大于100,是则输出原数;否则,输出0 if (num >= 100) { // 注意if语句后面不要加分号,否则,if将不会进行判断 cout << num << endl; } else { cout << "0" << endl; } }
多条件if语句
#include <iostream> using namespace std; int main() { // 选择结构 单行if语句 // 用户输入一个数字 int num = 1; cout << "请输入一个数字:"; cin >> num; // 判断数字是否大于600,是则输出原数;数字是否小于600,大于0,是则输出100;否则,输出0 if (num >= 600) { // 注意if语句后面不要加分号,否则,if将不会进行判断 cout << num << endl; } else if (num >= 100) { cout << "100" << endl; } else { cout << "0" << endl; } }
if ( 条件1 ) { 条件1满足执行语句} else if ( 条件2 ) { 条件2满足,同时条件1不满足,执行的语句 }··· else
嵌套if语句
在if语句中,可以嵌套使用if语句,达到更加精确的条件判断
案例:输入3个数字,判断出最大的数字
#include <iostream> using namespace std; int main() { int num = 1; int num1 = 1; int num2 = 1; cout << "请输入三个数字:"; cin >> num; cin >> num1; cin >> num2; if ( num > num1 ) { // 判断 num 和 num1 if ( num > num2 ) { // 判断 num 和 num2 cout << num << "最大" << endl; } else { cout << num2 << "最大" << endl; } } else { if (num1 > num2) { cout << num1 << "最大" << endl; } else { cout << num2 << "最大" << endl; } cout << "判断完毕" << endl; } }
三目运算符
作用:通过三目运算实现简单的判断
语法:表达式1 ? 表达式2 : 表达式3
#include <iostream> using namespace std; int main() { // 三目运算 // 将 a 和 b 做比较,将大的值赋值给c int a = 10; int b = 20; int c = 0; c = a > b ? a : b; // 如果 a 比 b 大,则将a赋值给c /* if ( a > b ) { c = a; } else { c = b } */ }
在C++中,三目运算符返回的是变量,可以继续赋值
switch语句
作用:执行多条件分支语句
语法:
switch ( 表达式 ) { case 结果1: 执行语句; break; // switch里面不一定每个case都要对应break,break的作用的向外跳出一层 ······ default: 执行语句; break; // 不一定需要default判断 }
示例
#include <iostream> using namespace std; int main() { // switch 语句 // 电影打分 int score = 0; cout << "请输入分数:"; cin >> score; cout << "您打的分数为:" << score << endl; switch (score) { case 10: cout << "是经典电影" << endl; break; // 退出当前分支,如果没有break,则会继续向下运行 default: // 当所有条件不满足时,执行该语句 cout << "普通" << endl; } }
缺点:判断的时候,只能是整型或者字符型,不可以是一个区间
优点:结构清晰,执行效率高
注意
- switch语句中表达式类型只能是整型或者字符型
- case里如果没有break,那么程序会一直向下执行
循环结构
while循环语句
作用:满足循环条件,执行循环语句
语法:while ( 循环条件 ) { 循环语句 }
解释:只要循环条件的结果为真,就执行循环语句
#include <iostream> using namespace std; int main() { int nu = 0; // 在屏幕中打印0到9的数字 while ( nu < 10 ) { cout << nu << endl; nu++; } }
猜数字游戏
#include <iostream> using namespace std; // time系统时间头文件包含 #include <ctime> int main() { // 添加随机数的种子,利用当前系统时间生成随机数,防止每次随机数一样 srand((unsigned int)time(NULL)); // 系统生成随机数 int rand_nu = rand() % 100 + 1; // rand()%100生成0到99的随机数 // 猜测数字 int guess_nu = 0; while (guess_nu != rand_nu) { cout << "请输入一个数字:"; cin >> guess_nu; // 判断 if (guess_nu > rand_nu) { cout << "输大了,请重新猜测!!!" << endl; } else if (guess_nu < rand_nu){ cout << "输小了,请重新猜测!!!" << endl; } else { cout << "恭喜你,猜对了!!!" << endl; break; } } }
do···while循环语句
作用:满足循环条件,执行循环语句
语法:do {循环语句} while (循环条件);
注意:与while的区别在于do...while会先执行一次循环时间,在判断循环条件
#include <iostream> using namespace std; int main() { // do...while语句 // 在屏幕中输出 0 到 9 这10个数字 int num = 0; do { cout << num << endl; num++; } while (num <= 9); }
水仙花数
水仙花数是指一个三位数,它的每个位上的数字的3次幂之和等于它本身
如:1 ^ 3 + 5 ^ 3 + 3 ^ 3 = 153
#include <iostream> using namespace std; int main() { int nu = 100; // 水仙花数 do { int ge = 0; // 定义个位的数字 int shi = 0; // 定义十位的数字 int bai = 0; // 定义百位的数字 ge = nu % 10; shi = nu / 10 % 10; bai = nu / 100; if (ge*ge*ge + shi*shi*shi + bai*bai*bai == nu){ cout << "水仙花数:" << nu << endl; } nu++; } while ( nu <= 999 ); }
for循环语句
作用:满足循环条件,执行循环语句
语法:for (起始表达式;条件表达式;末尾循环体) { 循环语句; }
#include <iostream> using namespace std; int main() { // for循环 // 从数字0打印到9 for (int i = 0; i < 10; i++ ) { cout << i << endl; } // 也可以 int i = 0; for (;;) { if (i >= 10) { break; } cout << i << endl; i++; } }
案例:敲桌子
从1开始数到数字100,如果数字个位含有7,或者数字十位含有7,或者该数字是7的倍数,我们打印敲桌子,其余的打印输出
#include <iostream> using namespace std; int main() { // 从1开始数到数字100,如果数字个位含有7,或者数字十位含有7,或者该数字是7的倍数,我们打印敲桌子,其余的打印输出 for (int i = 1; i < 100; i++) { if (i % 10 == 7 || i % 100 / 10 == 7 || i % 7 == 0) { cout << "敲桌子" << endl; } else { cout << i << endl; } } }
嵌套循环
作用:在循环中在嵌套一层循环,解决一些实际问题
#include <iostream> using namespace std; int main() { // 嵌套循环 for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { cout << "*"; } cout << "" << endl; } }
打印九九乘法口诀表
#include <iostream> using namespace std; int main() { // 嵌套循环 for (int i = 1; i < 10; i++) { for (int j = 1; j < i+1; j++) { cout << i << "*" << j << "=" << i * j << "\t"; } cout << "" << endl; } }
跳转语句
break语句
作用:用于跳出选择结构或者循环结构
break使用的时机:
- 出现在switch语句中,作用是终止case并跳出switch
- 出现在循环语句中,作用是跳出当前的循环语句
- 出现在嵌套循环中,跳出最近的内层循环语句
continue语句
作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
#include <iostream> using namespace std; int main() { for (int i = 0; i <= 10; i++) { if (i % 2 == 0) { continue; } else { cout << i << "\t"; } } }
goto语句
作用:可以无条件跳转语句
语法:goto 标记;
解释:如果标记的名称存在,执行到goto语句时,会跳转到标记的位置
#include <iostream> using namespace std; int main() { // goto cout << "hello" << endl; cout << "hello" << endl; cout << "hello" << endl; goto flag; cout << "hello" << endl; cout << "hello" << endl; flag: cout << "world"; }
数组
概述
数组:就是一个集合,里面存放了相同类型的数据元素
特点
- 数组中的每个数据元素都是相同的数据类型
- 数组是由连续的内存位置组成的
一维数组
定义方式
数据类型 数组名[ 数组长度 ];
数组类型 数组名[ 数组长度 ] = {值1, 值2...};
数组类型 数组名[ ] = {值1, 值2...}
#include <iostream> using namespace std; int main() { // 1. 数据类型 数组名[ 数组长度 ]; int arr[4]; arr[0] = 10; // 赋值操作 // 2. 数组类型 数组名[ 数组长度 ] = {值1, 值2...}; int arr1[5] = { 2, 2, 10, 20 }; // 如果在初始化数据的时候,没有全部填完,会用0来填补剩余数据 cout << arr1[0] << endl; // 通过下标索引取值 // 利用循环取值 for (int i = 0; i < 5; i++) { cout << arr1[i] << endl; } }
定义数组的时候必须有一个初始的长度
数组名的命名规范与变量名命名规范一致,不要和变量重名
数组中下标是从0开始索引
数组名
一维数组名称的用途:
- 可以统计整数组在内存中的长度
- 可以获取数组在内存中的首地址
#include <iostream> using namespace std; int main() { int arr[5] = { 2, 2, 10, 20 }; cout << "数组所占空间为" << sizeof(arr) << "\n" << "里面有" << (sizeof(arr) / sizeof(arr[0])) << "个元素" << endl; cout << "数组的首地址为" << (int)arr << "\n每个元素所占空间为" << sizeof(arr[0]) << "\n数组中第一个元素的地址为" << (int)&arr[0] << endl; }
数组名是一个常量,不可以进行赋值的操作
案例
找出数组中的最大的元素
#include <iostream> using namespace std; int main() { //找出数组中最大的数字 int max_nu = 0; // max_nu用于存储最大值 int arr[5] = { 300, 350, 200, 400, 250 }; for (int i = 0; i < ((sizeof(arr) / sizeof(arr[0]))-1); i++) { max_nu = arr[i] > arr[i + 1] ? arr[i] : arr[i + 1]; } cout << max_nu << endl; }
组元素逆置
将数组中的元素首尾进行互换
#include <iostream> using namespace std; int main() { // 数组里面的内容逆转 int arr1[5] = { 300, 350, 200, 400, 250 }; int end = sizeof(arr1) / sizeof(arr1[0]); // 末尾下标 int start = 0; // 起始下标 while (start < end) { int temp = arr1[start]; arr1[start] = arr1[end]; arr1[end] = temp; start++; end--; } for (int i = 0; i < (sizeof(arr1) / sizeof(arr1[0])); i++) { cout << arr1[i] << endl; } }
冒泡排序
作用:最常用的排序算法,对数组内的元素进行排序
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个
- 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值
- 重复以上的步骤,每次比较次数-1,直到不需要比较
排序 int arr = { 4, 2, 8, 0, 5, 7, 1, 3, 9};
#include <iostream> using namespace std; int main() { // 利用冒泡排序,实现升序排序 int arr[ ] = {4, 2, 8, 0, 5, 7, 1, 3, 9}; cout << "排序前:"; for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) { cout << arr[i] << " "; } for (int i = 0; i < (sizeof(arr) / sizeof(arr[0]) - 1); i++) { // 排序次数为元素个数减一 for (int j = 0; j < (sizeof(arr) / sizeof(arr[0]) - 1 - i); j++) { // 内层循环对比次数元素个数 - 排序次数 - 1 if (arr[j] > arr[j + 1]) { // 如果前一个数字比第二个数字大,交换顺序 int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } cout << "排序后:"; for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) { cout << arr[i] << " "; } }
二维数组
二维数组就是在以为数组上,多加一个维度
定义方式
数据类型 数组名 [ 行数 ] [ 列数 ];
数据类型 数组名 [ 行数 ] [ 列数 ] = { { 数据1, 数据2 }, {数据3, 数据4}} ;
数据类型 数组名 [ 行数 ] [ 列数 ] = {数据1, 数据2, 数据3, 数据4};
数据类型 数组名 [ ] [ 列数 ] = {数据1, 数据2, 数据3, 数据4};
以上定义方式,利用第二种更加直观,提高代码的可读性
#include <iostream> using namespace std; int main() { // 1. `数据类型 数组名 [ 行数 ] [ 列数 ];` int arr1[2][3]; // 2. `数据类型 数组名[行数][列数] = { { 数据1, 数据2 }, {数据3, 数据4} }; ` int arr2[2][3] = { {1, 2 ,3}, {4, 5, 6} }; // 二次循环,外层循环打印行数,内层循环打印列数 for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { cout << arr2[i][j] << " "; }; cout << endl; }; // 3. `数据类型 数组名[行数][列数] = { 数据1, 数据2, 数据3, 数据4 }; ` int arr3[2][3] = { 1, 2, 3, 4, 5, 6 }; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { cout << arr2[i][j] << " "; }; cout << endl; }; // 4. `数据类型 数组名[][列数] = { 数据1, 数据2, 数据3, 数据4 }; ` int arr3[2][3] = { 1, 2, 3, 4, 5, 6 }; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { cout << arr2[i][j] << " "; }; cout << endl; }; }
数组名
- 查看二维数组所占内存空间
- 获取二维数组首地址
#include <iostream> using namespace std; int main() { int arr2[2][3] = { {1, 2 ,3}, {4, 5, 6} }; // 查看占用内存 cout << "二维数组占用内存空间为:" << sizeof(arr2) << endl; cout << "二维数组第一行占用内存为:" << sizeof(arr2[0]) << endl; cout << "二维数组第一个元素占用的内存为:" << sizeof(arr2[0][0]) << endl; cout << "二位数组的一行的元素数量为:" << sizeof(arr2[0]) / sizeof(arr2[0][0]) << endl << "二维数组的行数为:" << sizeof(arr2) / sizeof(arr2[0]) << endl; // 查看二维数组的首地址 cout << "二维数组首地址为:" << (int)arr2 << endl; cout << "二维数组第一行的首地址为:" << (int)arr2[0] << endl; cout << "二维数组第一个元素的首地址为:" << (int)&arr2[0][0]; }
案例
有一个数组 int arr[3][3] = {{100, 100, 100}, {90, 50, 100}, {60, 70, 80}}
计算该数组每一行的总和
#include <iostream> using namespace std; int main() { // 求数组中每一行内数字的总和 int arr[3][3] = { {100, 100, 100}, {90, 50, 100}, {60, 70, 80} }; // 二次循环,得到数组中的每一个值 for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) { int sum = 0; for (int j = 0; j < (sizeof(arr[0]) / sizeof(arr[0][0])); j++) { sum += arr[i][j]; }; cout << "第" << (i + 1) << "行的和为:" << sum <<endl; }; }
函数
概述
作用:将一段经常使用的代码进行封装起来,减少重复代码;一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能
函数的定义
函数的定义一般主要有5个步骤
- 返回值类型
- 函数名
- 参数系列
- 函数体语句
- return表达式
语法
返回值类型 函数名 (参数列表) { 函数体语句 return 表达式 }
实现一个加法的函数,传入两个整型数值,计算数据相加的结果,并且返回
#include <iostream> using namespace std; // 函数体 int add(int num1, int num2) { return num1 + num2; }
函数的调用
功能:使用定义好的函数
语法:函数名(参数)
#include <iostream> using namespace std; // 函数体 int add(int num1, int num2) { // 函数定义里面的参数没有实际值,称为形参(形式参数) return num1 + num2; } int main() { cout << add(1, 2) << endl; // 在main函数中调用add函数,其中,1和2为实参(实际参数),位置要一一对应 }
值传递
- 所谓值传递,就是函数调用时实参将数值传入给形参
- 值传递时,如果形参发生改变,不会影响实参
#include <iostream> using namespace std; /* 值传递 定义函数,实现两个数字进行交换函数 如果函数不需要返回值声明的时候可以写void */ void swap(int num1, int num2) { cout << "交换前的数字" << endl << "num1:" << num1 << "\tnum2:" << num2; int temp = num1; num1 = num2; num2 = temp; cout << "\n交换后的数字" << endl << "num1:" << num1 << "\tnum2:" << num2; } int main() { int num1 = 10; int num2 = 20; cout << "未调用前的数字" << endl << "num1:" << num1 << "\tnum2:" << num2 << endl; // 当我们做值传递的时候,函数的形参发生改变,并不会影响形参 swap(num2, num1); }
函数的常见样式
常见的函数样式有4种
- 有参无返
- 无参无返
- 无参有返
- 有参有返
#include <iostream> #include <string> using namespace std; // 1. 有参无返 void test01(string str) { cout << str << endl; } // 2. 无参无返 void test02() { cout << "this is test02" << endl; } // 3. 无参有返 int test03() { return 100; } // 4. 有参有返 int test04(int num1, int num2) { return num1 * num2; } int main() { // 1. 有参无返调用 test01("hello world"); // 2. 无参无返调用 test02(); // 3. 有参无返调用 cout << test03() << endl; // 4. 有参有返调用 cout << test04(2, 3) << endl; }
函数的声明
作用:告诉编译器函数名称及如何调用函数.函数的实际主体可以单独定义
- 函数声明可以多次,但是函数的定义只能有一次
#include <iostream> #include <string> using namespace std; // 函数声明:提前告诉编译器函数的存在 // 函数声明-->如果没有该声明那么函数将不会调用 int max(int num1, int num2); int main() { int a = 10; int b = 20; cout << max(a, b) << endl; } // 比较函数,实现两个整型数字进行比较,返回较大的数字 int max(int num1, int num2) { return num1 > num2 ? num1 : num2; }
函数的分文件编写
作用:让代码结构更加清晰
函数分文件编写一般有4个步骤
- 创建后缀名为.h的头文件
- 创建后缀名为.cpp的源文件
- 在头文件中写函数的声明
- 在新的源文件中写函数的定义
/* 新建的源文件中 */ #include "标头.h" // 比较函数,实现两个整型数字进行比较,返回较大的数字,函数定义 int max(int num1, int num2) { return num1 > num2 ? num1 : num2; } /* 新建的头文件中(名称为标头.h) */ #include <iostream> using namespace std; int max(int num1, int num2); /* 运行文件中 */ #include "标头.h" int main() { int a = 10; int b = 20; cout << max(a, b) << endl; }
指针
基本概念
作用:可以通过指针间接访问内存
- 内存编号是从0开始记录的,一般用十六进制数字表示
- 可以利用指针变量保存地址
定义和使用
指针变量定义语法:数据类型 * 变量名
#include <iostream> using namespace std; int main() { // 定义一个指针 int a = 10; // 指针定义语法:数据类型 * 变量名 int * p; // 让指针记录变量a的地址 p = &a; // & 取址符号 cout << "a的地址为:" << &a << endl; cout << "指针p的值为:" << p << endl; // 使用指针 // 可以通过解引用的方式来找到指针指向的内存 // 指针前加 * 代表解引用,找到指针指向的内存中的数据 *p = 100; cout << "a等于:" << a << "\n*p等于" << *p << endl; }
指针所占的内存空间
#include <iostream> using namespace std; // 在32位操作系统下,指针占4bit,不管是什么数据类型 // 在64位操作系统下,指针占8bit int main() { int a = 10; int * p = &a; cout << "int *:" << sizeof(int*) << endl; cout << "char *:" << sizeof(char*) << endl; cout << "p:" << sizeof(p) << endl; }
空指针和隐指针
空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以被访问的
野指针:指针变量指向非法的内存空间
#include <iostream> using namespace std; int main() { // 空指针 // 空指针用于给指针对象初始化 int* p1 = NULL; // 空指针不能被访问,其被系统占用 // 野指针 // 在程序中一定要避免野指针 int * p = (int *)0x1100; }
const修饰指针
const修饰指针有三种情况
- const修饰指针 --常量指针
const int * p = &a
- 指针的指向可以修改,但是指向的值不可以修改
- const修饰常量 --指针常量
int * const p = &a
- 指针的指向不可以改,指针的值可以改
- const即修饰指针 ,又修饰常量
#include <iostream> using namespace std; int main() { int a = 10; int b = 10; // 常量指针 const int* p = &a; // 指针指向的值不可以改,指向的位置可以修改 // * p = 20; 错误 p = &b; // 正确 // 指针常量 int* const p1 = &a; // 指针指向的值可以修改,指向的位置不可以修改 *p1 = 20; // 正确 // p = &b; 错误 }
记忆方法:看const右侧紧跟的是指针还是常量,是指针就是常量指针,是常量就是指针常量
指针和数组
作用:利用指针访问数组中的元素
#include <iostream> using namespace std; int main() { // 指针和数组 // 利用指针访问数组中的元素 int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; cout << "第一个元素为:" << arr[0] << endl; int* p = arr; // arr就是数组的首地址 cout << "利用指针来访问第一个元素:" << *p << endl; p++; // 让指针偏移4bit cout << "利用指针访问第二个元素:" << *p << endl; // 利用指针来访问数组,也可以通过p1[索引值来访问] int* p1 = arr; for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) { cout << *p1++ << " "; } for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) { cout << p1[i] << " "; } }
指针和函数
作用:利用指针做函数的参数,可以修改实参的值
#include <iostream> using namespace std; void swap(int* p1, int* p2) { int temp = *p1; *p1 = *p2; *p2 = temp; } int main() { // 函数和指针 // 地址传递 int a = 10; int b = 30; cout << "a:" << a << " b:" << b << endl; swap(&a, &b); cout << "after a:" << a << " b:" << b << endl; // 地址中的内存发生改变 }
指针、数组、函数
封装一个函数,利用冒泡排序,实现对整型数组的升序排序
例如,数组:int arr[] = { 4, 3, 6, 9, 1, 2, 10, 8, 7, 5 };
#include <iostream> using namespace std; // 冒泡排序函数 void sort(int * arr, int length) { // 参数为数组的内存地址 for (int i = 0; i < length - 1; i++) { for (int j = 0; j < length - i - 1; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } // 打印数组 void print(int* arr, int length) { for (int i = 0; i < length; i++) { cout << arr[i] << " "; } } int main() { int arr[] = { 4, 3, 6, 9, 1, 2, 10, 8, 7, 5 }; int length = sizeof(arr) / sizeof(arr[0]); sort(arr, length); print(arr, length); }
结构体
基本概念
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
定义和使用
语法:struct 结构体名 { 结构体成员列表 }
通过结构体创建变量的方式有三种
struct 结构体名 变量名
struct 结构体名 变量名 = { 成员值1, 成员值2, ... }
- 定义结构体是顺便创建变量
#include <iostream> #include <string> using namespace std; // 创建学生的数据类型:包括(姓名、年龄、分数) // 自定义数据类型,一些类型集合组成的一个数据类型 struct Student { // 成员列表 string name; // name int age; // age int score; // score }s3; // 顺便创建结构体变量 int main() { // 通过学生类型创建具体学生 // struct Student s1 struct Student s1; // struct关键字可以省略,但是定义的时候不能省略 // 给s1属性赋值,通过.访问结构变量中的属性 s1.name = "张三"; s1.age = 18; s1.score = 90; cout << "name:" << s1.name << " age:" << s1.age << " score:" << s1.score << endl; // struct Stufent s2 = { ... } struct Student s2 = { "李四", 18, 80 }; cout << "name:" << s2.name << " age:" << s2.age << " score:" << s2.score << endl; // 在定义接哦古体是顺便创建结构体变量 s3.name = "王五"; s3.age = 18; s3.score = 85; cout << "name:" << s3.name << " age:" << s3.age << " score:" << s3.score << endl; }
结构体数组
作用:将自定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名 [ 元素个数 ] = { {}, {}, ...{} }
#include <iostream> #include <string> using namespace std; // 结构体数组 // 定义结构体数组 struct Student { string name; int age; int score; }; int main() { // 创建结构体数组 struct Student stuArray[3] = { // 给结构体数组赋值 {"zhangsan", 18, 100}, {"lisi", 19, 99}, {"wangwu", 20, 85} }; // 修改值 stuArray[2].name = "lihua"; stuArray[2].age = 19; stuArray[2].score = 89; // 遍历数组 for (int i = 0; i < 3; i++) { cout << "name:" << stuArray[i].name << " age:" << stuArray[i].age << " score:" << stuArray[i].score << endl; }; }
结构体指针
作用:通过指针访问结构体中的成员
- 利用操作符
->
可以通过结构体指针访问结构体属性
#include <iostream> #include <string> using namespace std; // 结构体指针 // 定义学生的结构体 struct Student { string name; int age; int score; }; int main() { // 创建学生结构体变量 struct Student s = { "zhangsan", 18, 99 }; // 通过指针指向结构体变量 struct Student* p = &s; // 通过指针指向访问结构体变量中的数据 cout << "name:" << p->name << " age:" << p->age << " score:" << p->score << endl; }
结构体嵌套结构体
作用:结构体中的成员可以是另一个结构体
例如:每个老师辅导一个学生,一个老师的结构体,记录一个学生的结构体
#include <iostream> #include <string> using namespace std; // 结构体指针 // 定义学生的结构体 struct Student { string name; int age; int score; }; // 定义老师结构体 struct Treacher { int id; string name; int age; struct Student stu; // 辅导学生 }; int main() { // 结构嵌套结构体 // 创建老师对象 struct Treacher t; t.id = 100000; t.name = "老王"; t.age = 58; t.stu.name = "小王"; t.stu.age = 16; t.stu.score = 60; cout << "tea_name:" << t.name << " tea_id:" << t.id << " tea_age:" << t.age << "\nstu_name:" << t.stu.name << " stu_age:" << t.stu.age << " stu_score:" << t.stu.score << endl; }
结构体做函数参数
作用:将结构体作为参数向函数中传递
传递的方式有两种
- 值传递
- 地址传递
#include <iostream> #include <string> using namespace std; // 定义学生的结构体 struct Student { string name; int age; int score; }; // 打印学生信息的函数,值传递 void printStuInfo(Student stu) { stu.age = 100; cout << "name:" << stu.name << " age:" << stu.age << " score:" << stu.score << endl; }; // 地址传递:形参修改会引起实参的改变 void printStudentInfo2(Student* p) { cout << "name:" << p->name << " age:" << p->age << " score:" << p->score << endl; }; int main() { // 结构体做函数的参数 // 将学生传入到一个参数中,打印学生身上的所有信息 // 创建结构体变量 struct Student stu; stu.name = "zhangsan"; stu.age = 20; stu.score = 85; cout << "值传递" << endl; printStuInfo(stu); cout << "地址传递" << endl; printStudentInfo2(&stu); }
结构体中const使用场景
作用:用const来防止五操作
#include <iostream> #include <string> using namespace std; // 定义学生的结构体 struct Student { string name; int age; int score; }; // 地址传递,节省空间 void printStudentInfo2(const Student* p) { // 加入const之后,一旦有修改的操作就会报错,可以防止我们的误操作 cout << "name:" << p->name << " age:" << p->age << " score:" << p->score << endl; }; int main() { // const使用场景 // 创建结构体变量 struct Student stu; stu.name = "zhangsan"; stu.age = 20; stu.score = 85; printStudentInfo2(&stu); }
结构体案例
案例一
#include <iostream> #include <string> #include <ctime> using namespace std; // 定义学生的结构体 struct Student { string name; int score; }; // 老师结构定义 struct Teacher { string name; Student stuArray[5]; }; // 给老师和学生赋值的函数 void allocateSpace(Teacher tArray[], int len) { // 给老师赋值 string name = "abcde"; for (int i = 0; i < len; i++) { tArray[i].name = "Teacher_"; tArray[i].name += name[i]; // 字符串的取值 // 给每名学生赋值 for (int j = 0; j < 5; j++) { tArray[i].stuArray[j].name = "Student_"; tArray[i].stuArray[j].name += name[j]; int random = rand() % 61 + 40; // 40-99 tArray[i].stuArray[j].score = random; } }; }; // 打印学生和老师的信息 void printInfo(Teacher* tArray, int len) { for (int i = 0; i < len; i++) { cout << "teacher_name:" << tArray[i].name << endl; for (int j = 0; j < 5; j++) { cout << "stu_name:" << tArray[i].stuArray[j].name << " stu_score:" << tArray[i].stuArray[j].score << endl; }; cout << "--------------------------------------------------------------------------------" << endl; }; } int main() { // 随机数种子 srand((unsigned int)time(NULL)); // 三名老师数组 Teacher tArray[3]; // 通过函数给老师的信息赋值,并给老师带的学生信息赋值 int len = sizeof(tArray) / sizeof(tArray[0]); allocateSpace(tArray, len); printInfo(tArray, len); }
案例二
有五个学生,通过冒泡排序的方法,将数组中的学生按照年龄进行升序排序,最终打印排序后的结果
{ {"stu1", 23}, {"stu2", 22}, {"stu3", 20}, {"stu4", 21}, {"stu5", 19} }
#include <iostream> #include <string> using namespace std; // 定义学生的结构体 struct Student { string name; int age; }; // 排序 void sort(Student* stuArray, int len) { for (int i = 0; i < len - 1; i++) { for (int j = 0; j < len - i - 1; j++) { if (stuArray[j].age > stuArray[j + 1].age) { struct Student temp = stuArray[j]; stuArray[j] = stuArray[j + 1]; stuArray[j + 1] = temp; }; }; }; }; // 输出 void printInfo(const Student * stuArray, int len) { for (int i = 0; i < len; i++) { cout << "name:" << stuArray[i].name << " age:" << stuArray[i].age << endl; }; }; int main() { // 创建数组存放五名学生 Student stuArray[] = { {"stu1", 23}, {"stu2", 22}, {"stu3", 20}, {"stu4", 21}, {"stu5", 19} }; int len = sizeof(stuArray) / sizeof(stuArray[0]); sort(stuArray, len); printInfo(stuArray, len); };
本文来自博客园,作者:Kenny_LZK,转载请注明原文链接:https://www.cnblogs.com/liuzhongkun/p/15799465.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?