C++基础入门
1、创建项目
这里使用的是Visual Studio
输入好自己的项目名称,然后选择位置后即可
新建源文件,在这个位置右键
选择C++文件,取好名字添加即可
2、HelloWorld
那么我们就可以开始写第一个程序了,
#include <iostream>
using namespace std;int main()
{ cout << "hello C++" << endl;system("pause");return 0;
}
点击本地windows调试器,就输出了
3、注释
作用:在代码中加入一些说明和解释,方便自己或其他人阅读
在运行时,编译器会忽略这些注释的内容
两种格式
1、单行注释
//
通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明
2、多行注释
/* 这是多条注释*/
通常放在一段代码的上方,对该段代码做整体说明
4、变量
作用:给一段指定的内存空间起名,方便操作这段内存
注意这个变量顾名思义,就是可以改变的数值
语法:数据类型 变量名 = 初始值;
如上图所示,每块内存都有它自己的编号(0x0000),我们可以用编号来使用它,但是不便于管理,这时候我们将它取一个便于记住的名字(a),那么a
就是变量名
#include<iostream>
using namespace std;int main() {//变量创建的语法:数据类型 变量名 = 变量初始值int a = 10;cout << "a = " << a << endl;system("pause");return 0;
}
5、常量
作用:用于记录程序中不可更改的数据
注意:这里的值不可以改变
#define
宏常量: #define 常量名 常量值- 通常在文件上方定义,表示一个常量
const
修饰常量:const 数据类型 常量名 = 常量值- 通常在变量定义前加关键字const,修饰该变量为常量
#include<iostream>using namespace std;/*
常量的定义方式
1、#define 宏常量
2、const修饰的常量
*///1、#define 宏常量
#define Day 7int main() {//Day = 14 这是不可以修改的 Day为常量,一旦修改就会报错cout << "一周一共有:" << Day << "天" << endl;//2、const 修饰常量const int month = 30;// month = 24 这里也是不可以修改的cout << "一月一共有:" << month << "天" << endl;system("pause");return 0;
}
6、关键字
作用:关键字是C++中预先保留的单词
注意:在定义变量或者常量时不要使用
7、命名规则
- 标识符不能是关键字
- 标识符只能由字母、数字、下划线组成
- 第一个字符必须为字母或下划线
- 标识符中字母区分大小写
给变量取名的时候做到见名知意
8、数据类型
C++规定在创建一个变量或者常量时,必须要制定出相对应的数据类型,否则无法给变量分配内存
8.1、整型
作用:整型变量表示整数的数据
以下在C++中有几种类型方式表示整型,区别在于内存空间不同
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | (-215~215-1) |
int(整型) | 4字节 | (-231~231-1) |
long(长整型) | windos为4字节,linux为4字节(32位),8字节(64位) | (-231~s31-1) |
long long(长长整型) | 8字节 | (-263~263-1) |
值不可以超过这个取值范围不然会出错,c++会自动变成负数的第一位,依次类推
#include<iostream>
using namespace std;int main() {//1、短整型(-32768~32767) short num1 = 10;//2、整型int num2 = 10;//3、长整型long num3 = 10;//4、长长整型long long num4 = 10;cout << "num1 = " << num1 << endl;cout << "num2 = " << num2 << endl;cout << "num3 = " << num3 << endl;cout << "num4 = " << num4 << endl;system("pause");return 0;
}
8.2、sizeof关键字
作用:利用sizeof关键字可以统计数据类型所占内存大小
语法:sizeof(数据类型/变量
#include<iostream>
using namespace std;int main() {//利用sizeof求出数据类型占用的内存大小 short num1 = 10;cout << "short占用的内存空间为:" << sizeof(num1) << endl;int num2 = 10;cout << "int占用的内存空间为:" << sizeof(num2) << endl;long num3 = 10;cout << "long占用的内存空间为:" << sizeof(num3) << endl;long long num4 = 10;cout << "long long占用的内存空间为:" << sizeof(num4) << endl;system("pause");return 0;
}
8.3、实型(浮点型)
作用:用于表示小数
浮点型变量分为两种:
- 单精度float
- 双精度double
两者的区别在于表示有效数字的范围不同
数据类型 | 占用空间 | 有效数字范围 |
---|---|---|
float | 4字节 | 7位有效数字 |
double | 8字节 | 15~16位有效数字 |
有效数字
:例如3.14 这里的有效数字就为3位
c++中不管是单精度还是双精度默认只显示6位数字
#include<iostream>
using namespace std;int main() {//1、单精度 float//这里加f的意思是让C++当成单精度处理,不然会自动转成双精度再转换成单精度float f1 = 3.142131f;cout << "f1=" << f1 << endl;cout << "float的内存空间" << sizeof(f1) << endl;//2、双精度double f2 = 3.1322312;cout << "f2=" << f2 << endl;cout << "double的内存空间" << sizeof(f2) << endl;//科学计数法float f3 = 3e2; //3*10 ^ 2cout << "f2=" << f3 << endl;float f4 = 3e-2; //3*0.1 ^ 2cout << "f4=" << f4 << endl;system("pause");return 0;
}
8.4、字符型
作用:字符型变量用于显示单个字符
语法:char ch = ‘a’;
注意:
- 再显示字符型变量时,要用
单引号
括起来,不要用双引号 - 单引号内只能有一个字符,不可以是字符串
c和c++中字符型变量值占用1个字节
字符型变量并不帅把字符串本身放到内存中存储,而是将对应的ASCII编码
放入到存储单元
#include<iostream>
using namespace std;int main() {char a = 'a';cout << "char所占内存空间" << sizeof(a) << endl;//字符型变量的常见错误//char c = "b"; //创建字符型变量时候,要用单引号//char c = 'asdsad'; //创建字符型变量时候,单引号只能有一个//4、字符型变量对应的ASCII编码// a = 97// A = 65char ch1 = 'a';cout << "a的ASCII编码" << (int)ch1 << endl;char ch2 = 'A';cout << "A的ASCII编码" << (int)ch2 << endl;system("pause");return 0;
}
8.5、转义字符
作用:用于表示一些不能显示出来的ASCII字符
这里我只列举一些常用的
转义字符 | 含义 | ASCII码值 |
---|---|---|
\n | 换行 | 010 |
\ | 表示一个反斜杠字符"\" | 092 |
\t | 水平制表(跳到下个TAB位置) | 009 |
#include<iostream>
using namespace std;int main7() {//1、单精度 float//这里加f的意思是让C++当成单精度处理,不然会自动转成双精度再转换成单精度float f1 = 3.142131f;cout << "f1=" << f1 << endl;cout << "float的内存空间" << sizeof(f1) << endl;//2、双精度double f2 = 3.1322312;cout << "f2=" << f2 << endl;cout << "double的内存空间" << sizeof(f2) << endl;//科学计数法float f3 = 3e2; //3*10 ^ 2cout << "f2=" << f3 << endl;float f4 = 3e-2; //3*0.1 ^ 2cout << "f4=" << f4 << endl;system("pause");return 0;
}
8.6、字符串型
作用:用于表示一串字符
语法:string 变量名 = “字符串值”
#include<iostream>using namespace std;int main() {string str = "hello world";cout << str << endl;system("pause");return 0;
}
如果报错的话,可以加一个头文件#include<string>
8.7、布尔类型
作用:布尔数据类型代表真或者假的值
bool类型只有俩个值
- true 表示 真 可以用 1 来表示
- flase 表示 假 可以用 0 来表示
bool类型占1个字节大小
#include<iostream>
using namespace std;int main() {bool flag = true;cout << flag << endl;bool flag1 = false;cout << flag1 << endl;cout <<"bool占的内存空间:" << sizeof(flag1) << endl;system("pause");return 0;
}
8.8 、数据的输入
作用:用于从键盘获取数据
关键字: cin
语法: cin>>变量
9、数组
定义方式
- 数据类型 数组名 [数组长度];
#定义int arr[5];#存数组arr[0] = 10;#输出cout<<arr[0]<<endl;
- 数据类型 数组名[数组长度] = {值1,值2,…}
#定义#初始化没有定义值为0int arr2[5] = { 10,20,30,40,50 };cout << arr2[1] << endl;
- 数据类型 数组名[] = {值1,值2,…}
int arr3[] = { 30,20,10 };
9.1、一维数组
- 可以统计整个数组在内存中的长度
int arr[4] = { 1,2,3,4 };
cout << sizeof(arr) << endl;
//16
- 可以获取数组在内存中的首地址
cout << (int)arr << endl;
//& 元素的首地址cout << (int)&arr << endl;
冒泡排序
int arr[9] = { 4,2,8,0,5,7,1,3,9 };cout << "排序前:" << endl;for (int i = 0; i < 9; i++){cout << arr[i] << "";}for (int i = 0; i < 9 - 1; i++){for (int j = 0; j < 9-i-1; j++){if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}cout << "排序后:" << endl;for (int i = 0; i < 9; i++){cout << arr[i] << "";}
9.2、二维数组
//1.数据类型 数组名[行数][列数]int arr[2][3];//赋值arr[0][0] = 1;// 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 };
可利用循环来做打印或赋值
外层循环打印行,内层循环打印列
//行for (int i = 0; i < 2; i++){//列for (int j = 0; j < 3; j++){cout << arr[i][j] << " ";}cout << endl;}
9.2.1、二维数组名称
用途
- 查看二维数组所占用的内存空间
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;//第一行和第二行相差12字节cout << "二维数组第一行地址" << (int)arr[0] << endl;cout << "二维数组第二行地址" << (int)arr[1] << endl;//第一个和第二个元素相差4字节cout << "二维数组第一个元素地址" << (int)&arr[0][0] << endl;cout << "二维数组第二个元素地址" << (int)&arr[0][1] << endl;
10、函数
作用:将一段经常使用的代码封装起来,减少重复代码
10.1、函数的定义
- 函数值类型
- 函数名
- 参数表列
- 函数体语句
- return表达式
语法:
返回值类型 函数名(参数列表)
{函数体语句return表达式
}
//eg 加法
int add(int num1, int num2) {int sum = num1 + num2;return sum;
};
10.2、函数的调用
int main() {int a = 1;int b = 2;cout << add(a, b) << endl;system("pause");return 0;
}
10.3、 值传递
void 无类型,不需要返回值 不影响实参
//不影响实参
void swap(int num1, int num2) {int temp = num1;num1 = num2;num2 = temp;cout << "交换后" << endl;cout << "num1" << num1 << endl;cout << "num2" << num2 << endl;
}
10.4、函数的常见样式
常见的函数样式4种
- 无参无返
void test01() {cout << "1213" << endl;
}
int main() {//无参无返test01();system("pause");return 0;
}
- 有参无返
void test02(int a ) {cout << "有参无返" << a << endl;
}
int main() {//有参无返test02(1);system("pause");return 0;
}
- 无参有返
int test03() {cout << "123" << endl;return 100;
}
int main() {//无参有反test03();system("pause");return 0;
}
- 有参有返
//有参有返
int test04(int a) {return a + 1;
}
int main() {cout<<test04(3);system("pause");return 0;
}
10.5、函数的声明
提前告诉编译器函数存在,避免报错,可以把函数放在main的后面。
- 声明和定义的区别
- 声明没有具体代码
- 声明可以写多次,定义只能一次
//声明
int max(int a, int b);
int main() {int a = 1;int b = 2;cout<<max(a, b);system("pause");return 0;
}
//定义
int max(int a, int b) {return a > b ? a : b;
}
10.6、函数的分文件编写
使代码可读性更高,不堆积在一个文件中
创建步骤
- 创建.h后缀的头文件
- 创建.cpp后缀名的源文件
- 在头文件中写函数的声明
- 在源文件中写函数的定义
11、指针
作用:利用指针来访问内存(指针就是一个地址)
& 与 * 互为逆运算。& ,其作用是取变量的地址;* ,其作用是取地址对应的内存
- 定义
数据类型 * 指针变量名
int a = 10;//指针定义的语法:数据类型 * 指针变量名;int * p;//让指针记录变量a的地址p = &a;//输出cout << "a的地址:" << &a << endl;cout << "指针P为:" << p << endl;
- 使用
利用解引用
的方式来找到指针指向的内存
指针前加*
代表解引用
,找到指针指向内存中的数据
//使用指针*p = 1000;//此时a的值为1000cout << "a=" << a << endl;cout << "*p=" << *p << endl;
11.1、指针占用的内存
指针所占用的空间跟操作系统有关,32位和64位操作系统
- 64位操作系统
int a = 10;int* p = &a;cout << "64位操作系统下占用的内存空间int:" << sizeof(int *) << endl;cout << "64位操作系统下占用的内存空间float:" << sizeof(float *) << endl;cout << "64位操作系统下占用的内存空间double:" << sizeof(double *) << endl;cout << "64位操作系统下占用的内存空间char:" << sizeof(char *) << endl;
- 32位操作系统
11.2、空指针和野指针
空指针和野指针均不是我们所申请的空间,所以都不要访问
空指针
:指针变量指向内存中编号为0的空间(0~255为系统占用不可访问)
用途
:初始化指针变量
注意
:空指针指向的内存不可访问
//初始化
int *p = null;
//空指针访问(会报错)
*p = 100;
野指针
:指向一个非法内存空间(随意指向一个内存地址),不是自己申请的。
//指针变量p指向0x111的空间int * p = (int *)0x111;cout << *p<< endl;
11.3、const修饰指针
- coust修饰
指针
—常量指针
- coust修饰
常量
—指针常量
- coust修饰
指针
和常量
常量指针
(只能修改指针指向的地址,不能修改值)
int a = 10;int b = 20;const int * p = & a;//指向可修改,值不可被修改p = &b;*p = 20;//错误
指针常量
(只能修改值,不能修改指向地址)
int a = 10;int b = 20;int * const p = &a;//指向不可被修改,值可被修改*p = 20;p = &b;//错误
- coust修饰
指针
和常量
(俩个均不可被修改)
int a = 10;int b = 20;const int* const p = &a;//均不可被更改*p = 20;p = &b;
11.4、指针数组
利用指针访问数组中的元素
int arr[5] = { 1,2,3,4,5 };//利用指针指向数组首地址int * p = arr;for (int i = 0; i < 5; i++){cout << *p << endl;cout << &*p << endl;//使地址每次向后移p++;}
11.5、指针和函数
地址传递
:当我们函数传入的是地址时,可以改变实参的数据
void swap(int* p1, int* p2) {int temp = *p1;//将值赋给temp*p1 = *p2;//将值赋给p1*p2 = temp;
}
int main() {int a = 10;int b = 20;cout << "a:" << a << endl;cout << "b:" << b << endl;swap(a, b);cout << "改变后a:" << a << endl;cout << "改变后b:" << b << endl;system("pause");return 0;
}
值传递和地址传递区别
:值传递不改变值,地址传递改变参数的值
12.结构体
允许
用户自定义
的数据类型,允许用户存储不同的数据类型
-
语法
//自定义数据类型,一些类型的集合组成的一个类型 //语法:struct 类型名称{}
struct Student {//姓名string name;//年龄int age;//分数int score; };
-
赋值
- 通过声明一个名字给它的属性赋值
int main() {//直接声明赋值struct Student s1;s1.name = "张三";s1.age = 11;s1.score = 100;cout << "name:" << s1.name << "age:" << s1.age << "score:" << s1.score;system("pause");return 0; }
- 直接赋值
struct Student s2{"李四",17,200};cout << "name:" << s2.name << "age:" << s2.age << "score:" << s2.score << endl;;
- 创建结构体时创建结构体变量(不推荐)
struct Student {//姓名string name;//年龄int age;//分数int score; }s3;
struct
在c++中创建变量时可以可以省略,定义结构体不可被省略
Student s2{"李四",17,200};
12.1、结构体数组
将自定义的结构体放入到数组中方便维护
语法
:数据类型 数组名 = { {…},{…},… }
struct Student
{string name;int age;int score;};int main() {Student stdArray[3] = {{"张三",11,122},{"李四",12,111},{"王五",13,322}};//修改元素stdArray[2].age = 100;cout << stdArray[2].age << endl;//输出for (int i = 0; i < 3; i++){cout << "姓名:" << stdArray[i].name << endl;}system("pause");return 0;
}
12.2、结构体指针
通过指针访问结构体中的成员
- 利用操作符·
->
可以通过指针访问结构体属性
struct Student
{string name;int age;int score;};
int main() {Student s1 = { "张三",11,200 };Student * p = &s1;cout << p->name << p->age << p->score;system("pause");return 0;
}
12.3 、结构体嵌套结构体
结构体中的成员可以是另一个结构体
struct Student
{string name;int age;int score;};
struct Teacher
{string name;int age;Student stu;
};int main() {Teacher t;t.age = 1;//访问结构体中的结构体t.stu.age = 1;return 0;
}
12.4、结构体做函数参数
将函数体作为参数向函数中传递
传递的俩种方式
- 值传递
- 地址传递
想修改主函数中的数据地址传递,反之值传递
值传递
函数里面形参会发生变化,实参不会改变
//定义结构体
struct Student
{string name;int age;int score;};
//输出
void printStudent(Student stu) {stu.age = 100;cout <<"修改后age:" << stu.age<<endl;
}
int main() {Student s1 = {"zy",11,12};cout << "修改前age:" << s1.age << endl;printStudent(s1);cout << "执行完age:" << s1.age << endl;t.stu.age = 1;return 0;
}
地址传递
:可通过地址修改实参
//定义结构体
struct Student
{string name;int age;int score;};
//输出
void printStudent2(Student * p) {p->age = 200;cout << "修改后age:" << p->age << endl;
}
int main() {Student s1 = {"zy",11,12};cout << "修改前age:" << s1.age << endl;//printStudent(s1);printStudent2(&s1);cout << "执行完age:" << s1.age << endl;t.stu.age = 1;return 0;
}
12.5、结构体中const使用场景
用const来防止误操作
void printStudent(const Student * p) {//不可被修改//p->age = 100;cout <<"修改后age:" <<p->age<<endl;
}