c++学习[02] 基础知识(中)
·
数组
连续内存,相同数据类型
数组名是地址
一维数组
定义 2.3.初始化
数组名
- 整个数组在内存中的长度
- 首地址
sizeof(arr) // 整个数组占用内存空间
sizeof(arr[0]) // 每个元素占用内存空间
sizeof(arr) / sizeof(arr[0]) // 数组中**元素个数**
// 首地址
cout<< arr <<endl; // 十六进制
cout<< (int)arr <<endl; // 转换为十进制
二维数组
定义:列数要确定![![[二维数组定义.png]]](https://i-blog.csdnimg.cn/direct/68dd4344f5c84979a3de6c4527c55d49.png)
数组名
- 查看二维数组所占内存空间
- 获取首地址
int arr[2][3] = {
{11,12,13},
{21,22,23}
};
// 1. 内存空间
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;
// 2. 首地址
cout<< arr <<endl; // 十六进制
cout<< (int)arr <<endl; // 转换为十进制
函数
函数定义
返回值类型 函数名 (参数列表)
{
// 函数体
return
}
函数声明
提前告诉编译器函数的存在
返回值类型 函数名 (参数列表);
函数调用
使用定义好的函数
语法:函数名(参数);
值传递
函数调用时,实参将数值传入给形参
值传递时,如果形参改变,不会影响实参
因为是另外开辟的空间,只不过将实参的值赋值给形参了而已
函数分文件编写
.h 头文件 : 函数声明
.cpp 源文件 :函数定义
指针
作用:间接访问内存
内存有地址编号,十六进制,从0开始记录
指针变量存的就是地址
定义和使用
// 数据类型 * 变量名
int a = 10;
int * p = &a; // & 取地址符,将变量a的地址,赋值给p
输出p:a地址
输出*p:解引用 ,输出地址指向的值(指针指向内存中的数据)
指针所占内存空间
指针也是一种数据类型
指针存的是地址(十六进制数),在32位操作系统(x86)下,占用4个字节空间(64位 x64占8个字节)
// 实验:
cout<<sizeof(char *)<<endl;
cout<<sizeof(int *)<<endl;
cout<<sizeof(float *)<<endl;
cout<<sizeof(double *)<<endl;
// 都是4个字节
空指针和野指针
- 空指针 NULL:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存不可访问
int * p = NULL;
cout<< *p << endl; // 访问空指针报错
内存编号0~255为系统占用内存,不允许用户访问
- 野指针:指针变量指向非法的内存空间
int * p = (int *)0x1100; // 指针变量p指向 内存编号为0x1100 的空间
cout<< *p << endl; // 访问野指针报错 没有申请内存
编译没问题(语法正确),但运行时报错
- 总结:空指针和野指针都不是我们申请的空间,因此不要访问
// 正确做法
// 1. 指向已有变量(见指针的定义和使用)
// 2. 动态申请(new)
int *p = new int(10);
// 3. 初始化为nullptr(c++11后)
int *p = nullptr;
const修饰指针
1.const修饰指针——常量指针
2.const修饰常量——指针常量
3.const既修饰指针,又修饰常量
int a = 10;
const int * p = &a;
// 指针的**指向**可以修改,但指针指向的**值**不能修改
p = &b; // ✅️
*p = 20; // ❌️
就是原先指向的值不能修改![![[常量指针.png]]](https://i-blog.csdnimg.cn/direct/d25e6be254d94e4aba24e610aff5a86d.png)
int * const p = &a; // 指针常量
// 指针的**指向不可以改**,指针指向的值可以改
相当于p是常量,它的指向不能改
const int * const p = &a;
指针的指向,和指向的值,都不能改
指针和数组
利用指针访问数组中元素
int * p = arr; // arr 数组名本身就是地址,不用 &
// 访问第一个元素
cout << * p << endl;
// 利用指针遍历数组
for(int i=0;i<10;i++){
cout<< *p <<endl;
p ++ ; // 移动几个字节 取决于指针类型(int-4 char-1)
}
指针和函数
指针作函数参数,可以修改实参
[[#值传递]]
vs
地址传递
void swap(int *p1, int *p2)
{
int temp = *p1; // 解引用 -> 指向a内存空间的值
*p1 = *p2;
*p2 = temp;
}
int main(){
int a = 10;
int b = 20;
swap(&a, &b); // 传递地址
cout<<a<<b; // a = 20 , b = 10 改变实参,完成交换
}
指针、数组、函数案例:冒泡排序
![![[指针、数组、函数:冒泡案例.png]]](https://i-blog.csdnimg.cn/direct/3ccd54004a2b42d6a6c7132896498c17.png)
结构体
用户自定义的数据类型,可以存储不同的数据类型
定义和使用
语法:struct 结构体名 {结构体成员列表};
通过结构体创建变量:![![[结构体变量.png]]](https://i-blog.csdnimg.cn/direct/9613c8977869466eb16b336eb08ff86a.png)
struct student
{
// 成员列表
}s1; // 结构体变量
操作符“."访问成员
结构体数组
语法:
struct 结构体名 数组名[元素个数] = {
{},
...
{}
}
结构体指针
通过指针访问结构体中成员
需要用操作符 ->
struct student{
// 结构体定义
string name;
int age;
};
int main(){
struct student s1 = {"吴彦祖",18}; // 定义结构体变量 s1
struct student *p = &s1;
cout << p->name <<endl<< p->age <<endl;
}
结构体嵌套结构体
在结构体中定义另一个结构体作为成员
结构体做函数参数
传递方式:
- 值传递:函数内部"."访问成员
- 地址传递:函数内部"->"访问成员(利用指针)
不想修改主函数中的数据,用值传递,反之用地址
地址传递还可以节省空间
结构体中const使用
用const:防止误操作
即不能修改
结语
由于程序流程结构过于简单,所以没有进行叙述,有c语言基础足够(如果没有可以去听一下网课进行掌握~)
下篇会讲程序中的内存分区~有助于理解实参和形参的区别
以及引用(语法上是指针的省略)、
函数的默认参数和重载~
更多推荐

所有评论(0)