文章目录
一、指针
通过指针可以间接访问内存,对内存中的数进行读或写
-
内存编号是从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 = 1000;
cout << "a = " << a << endl;
cout << "*p = " << *p << endl;
system("pause");
return 0;
}
输出结果
解引用就是返回内存地址中对应的对象
在32位操作系统,指针是占4个字节空间大小,不管是什么数据类型
在64位操作系统下,指针是占个字节空间大小
空指针:指针变量指向内存中编号为0的空间,用于初始化指针变量
注 空指针指向的内存是不可以访问的(0~255之间的内存编号是系统占用的,因此不可以访问)
野指针:指针变量指向非法的内存空间
空指针和野指针都不是我们申请的空间,因此不要访问
1、const修饰指针
-
const 修饰指针——常量指针
-
const 修饰常量——指针常量
-
const 既修饰指针,又修饰常量
常量指针:指针的指向可以改,但是指针指向的值不可以改
const int * p = &a;
int a = 10;
int b = 10;
int *p = &a;
*p = 20; //错误,指针指向的值不可以改
p = &b; //正确,指针指向可以改
指针常量:指针的指向不可以改,指针指向的值可以改
int * const p = &a;
int a = 10;
int b = 10;
int *p = &a;
*p = 20; //正确,指针指向的值可以改
p = &b; //错误,指针指向不可以改
const 既修饰指针,又修饰常量:指针的指向和指针指向的值都不可以改
const int * const p = &a;
2、指针和数组
利用指针访问数组中的内容
示例
#include <iostream>
using namespace std;
int main()
{
int arr[9] = { 1,2,3,4,5,6,7,8,9 };
int *p = arr;
for(int i = 0; i < 9; i++)
{
cout << "利用指针输出数组中第" << i + 1<< "个数:" ;
cout << *p << endl;
p++;
}
system("pause");
return 0;
}
输出结果
3、指针和函数
利用指针作为函数参数,可以修改实参的值(地址传递)
示例
#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 = 20;
swap(&a, &b);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0;
}
输出结果
3、指针、数组、函数
封装一个函数,利用冒泡排序,实现对整型数组的升序排列
#include<iostream>
using namespace std;
//冒泡排序函数
void bubble(int *arr, int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main()
{
int arr[10] = { 4,6,9,5,3,2,7,8,1,10 };
int len = sizeof(arr) / sizeof(arr[0]);
bubble(arr, len);
for (int i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
system("pause");
return 0;
}
输出结果
二、结构体
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
1、结构体定义和使用
语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
-
struct 结构体名 变量名
-
struct 结构体名 变量名 = { 成员1值,成员2值…}
-
定义结构体时顺便创建变量
示例
#include<iostream>
#include<string>
using namespace std;
struct student
{
string name;
int age;
int score;
}s3; //定义结构体时顺便创建变量
int main()
{
// 1、struct 结构体名 变量名
struct student s1;
s1.name = "张三";
s1.age = 17;
s1.score = 90;
cout << "姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl;
// 2、struct 结构体名 变量名 = { 成员1值,成员2值... }
struct student s2 = { "李四",17,87 };
cout << "姓名:" << s2.name << " 年龄:" << s2.age << " 分数:" << s2.score << endl;
//3、定义结构体时顺便创建变量
s3.name = "王五";
s3.age = 18;
s3.score = 91;
cout << "姓名:" << s3.name << " 年龄:" << s3.age << " 分数:" << s3.score << endl;
system("pause");
return 0;
}
输出结果
2、结构体数组
将自定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名[ 元素个数 ] = { {},{},......}
示例
#include<iostream>
#include<string>
using namespace std;
//1、定义结构体
struct student
{
string name;
int age;
int score;
};
int main()
{
//2、创建结构体数组
struct student stu[2]=
{
{"张三", 18, 95},
{"李四", 17, 90}
};
//3、给结构体数组中的元素赋值
stu[1].name = "王五";
//4、遍历结构体数组
for (int i = 0; i < 2; i++)
{
cout << "姓名:" << stu[i].name
<< " 年龄:" << stu[i].age
<< " 分数:" << stu[i].score << endl;
}
system("pause");
return 0;
}
输出结果
3、结构体指针
通过指针访问结构体中的成员
利用操作符 -> 可以通过结构体指针访问结构体属性
==通过结构体指针访问结构体中的属性,需要利用 ’ -> ’ ==
#include<iostream>
#include<string>
using namespace std;
//定义结构体
struct student
{
string name;
int age;
int score;
};
int main()
{
//创建结构体变量
struct student s = { "张三", 18, 95 };
//通过指针指向结构体变量
struct student * p = &s;
//通过指针访问结构体变量
cout << "姓名:" << p->name
<< " 年龄:" << p->age
<< " 分数:" << p->score << endl;
system("pause");
return 0;
}
4、结构体嵌套结构体
示例
#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.id = 001;
t.name = "老王";
t.age = 50;
t.stu.name = "小王";
t.stu.age = 17;
t.stu.score = 90;
cout << "老师姓名:" << t.name
<< " 老师id:" << t.id
<< " 老师年龄:" << t.age<<endl
<< "学生姓名:" << t.stu.name
<< " 学生年龄:" << t.stu.age
<< " 学生分数:" << t.stu.score << endl;
system("pause");
return 0;
}
5、结构体做函数参数
将结构体作为参数像函数中传递
传递方式:
-
值传递
-
地址传递
示例
#include<iostream>
#include<string>
using namespace std;
//定义结构体
struct student
{
string name;
int age;
int score;
};
//打印学生信息
//1、值传递
void print01(struct student s)
{
s.age = 100;
cout << "print01学生姓名:" << s.name
<< " 学生年龄:" << s.age
<< " 学生分数:" << s.score << endl;
}
//2、地址传递
void print02(struct student *p)
{
p->age = 200;
cout << "print02学生姓名:" << p->name
<< " 学生年龄:" << p->age
<< " 学生分数:" << p->score << endl;
}
int main()
{
struct student s;
s.name = "张三";
s.age = 18;
s.score = 90;
print01(s);
cout << "main01学生姓名:" << s.name
<< " 学生年龄:" << s.age
<< " 学生分数:" << s.score << endl;
print02(&s);
cout << "main02学生姓名:" << s.name
<< " 学生年龄:" << s.age
<< " 学生分数:" << s.score << endl;
system("pause");
return 0;
}
输出结果
6、结构体中const使用场景
用const来防止误操作
将函数中的形参改为指针,可以减少内存空间,而且不用再复制副本
示例
#include<iostream>
#include<string>
using namespace std;
//定义结构体
struct student
{
string name;
int age;
int score;
};
void print(const student *s)
{
//加入const后,在函数中不可再修改结构体中数据属性
cout << "学生姓名:" << s->name
<< " 学生年龄:" << s->age
<< " 学生分数:" << s->score << endl;
}
int main()
{
struct student s = { "张三",20,90 };
//通过函数来打印结构体信息
print(&s);
system("pause");
return 0;
}
【注释】 学习课程为-黑马程序C++教程