IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 4.C语言数组 -> 正文阅读

[C++知识库]4.C语言数组

数组

本章重点

  1. 一维数组的创建和初始化
  2. 一维数组的使用
  3. 一维数组在内存中的存储
  4. 二维数组的创建和初始化
  5. 二维数组的使用
  6. 二维数组在内存中的存储
  7. 数组越界
  8. 数组作为函数参数
  9. 数组的应用实例1:三子棋
  10. 数组的应用实例2:扫雷游戏

1. 一维数组的创建和初始化

1.1 数组的创建

数组是一组相同类型元素的集合

数组的创建方式:

type_t   arr_name   [const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小

数组创建的实例:

//代码1
int arr1[10];
//代码2
int count = 10;
int arr2[count];//变长数组
//代码3
char arr3[10];
float arr4[1];
double arr5[20];

:数组创建, [] 中要给一个常量才可以,不能使用变量(C99支持变长数组)

1.2 数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。

数组如果既不初始化也不指定大小,err!

#include <stdio.h>
int main()
{	
	//int arr[];/err
    //int arr6[5];//创建数组
	//初始化
	int arr1[20] = {1,2,3};//不完全初始化,初始化前3个值,剩余的默认初始化为0
	int arr2[] = {1,2,3};//大小不指定,由初始化内容决定
    int arr3[3] = {1,2,3,4,5};//err,初始化项太多

	return 0;
}

image-20210727163551069

//字符串初始数组
char arr3[] = "abc";
char arr4[] = { 'a', 'b', 'c' };
char arr5[] = { 'a', 98, 'c' };//char类型,b的ASCII值:98

image-20210727164441647

int arr[5];//全局变量的数组不初始化,默认为0
		   //局部变量的数值不初始化,随机值
#include <stdio.h>
int main()
{
	int arr6[5];//创建数组
	return 0;
}

image-20210727165047814

1.3 一维数组的使用

对于数组的使用我们之前介绍了一个操作符: [] ,下标引用操作符

它是数组访问的操作符

总结:

  1. 下标从0开始

  2. 数组使用下标来访问元素——arr[下标]

  3. 数组的大小可以通过计算得到

#include <stdio.h>
int main()
{
	float sc[5] = {0.0f, 3.0f};
	//结构体数组也可以创建

	int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13};
	//下标 0~9
	//printf("%d\n", arr[4]);//打印下标为4的元素
	
	int i = 0;
	//计算数组元素个数
	int sz = sizeof(arr) / sizeof(arr[0]);//数组总大小/数组第一个元素大小
	//输出数组的内容
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

1.4 一维数组在内存中的存储

image-20210727195407338

#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
//计算元素数组个数
int sz = sizeof(arr) / sizeof(arr[0]);
//打印元素地址
for (i = 0; i < sz; i++)
{
	printf("%p\n", &arr[i]);
}
return 0;
}

image-20210727195453117

指针保存地址:

image-20210727195910045

2. 二维数组的创建和初始化

2.1 二维数组的创建

image-20210727202159169

//数组创建;指定行、列
int arr[3][4];
char arr[3][5];
double arr[2][4];

2.2 二维数组的初始化

#include <stdio.h>
int main()
{
	//数组创建      指定行、列
	int arr1[3][5] = {1,2,3,4,5,6,7,8,9,10,11};//依次顺序放入,空余写0
	int arr2[3][5] = { {1,2},{3,4},{5,6} };//指定放入某一行
	int arr3[][5] = { {1,2},{3,4},{5,6} };//初始化时,可以省略行不能省略列

 
	char ch1[4][6] = {'a', 'b'};
	char ch2[4][6] = { {'a'},{ 'b'} };
	char ch3[4][6] = {"abc", "def", "qwe"};

	//double d[4][7];
	return 0;
}

//数组内空部分   int型  ‘0’---ASCII---48
//			   char型 ‘\0'---ASCII--0

image-20210727203112223

image-20210727203636224

image-20210727203921201

2.3 二维数组的使用

image-20210727204456382

image-20210727205006609

#include <stdio.h>
int main()
{
	int arr[3][5] = { {1,2,3},{4,5},{6,7,8,9,0} };
	int i = 0;
	for (i = 0; i < 3; i++)//0~2
	{
		int j = 0;
		for (j = 0; j < 5; j++)//0~4
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

2.4 二维数组在内存中的存储

image-20210727214151683

	int arr[3][5] = { {1,2,3},{4,5},{6,7,8,9,0} };
	int i = 0;
	for (i = 0; i < 3; i++)//0~2
	{
		int j = 0;
		for (j = 0; j < 5; j++)//0~4
		{
			printf("&arr[%d][%d] = %p\n",i,j, &arr[i][j]);
		}
	}

image-20210727215108401

int a[3] [5]; 可以认为二维数组a,有3个元素,每个元素是1个一维数组

我们可以分析到,其实二维数组在内存中也是连续存储的。

int arr[5] = { 1,2,3,4,5 };

printf("%p\n", arr);//打印数组名
printf("%p\n", &arr[0]);//打印数组的第一个元素

image-20210727220813893

int arr[5] = { 1,2,3,4,5 };
//指针访问
int* p = arr;
int i = 0;
for (i = 0; i < 5; i++)
{
    printf("%d ", *p);
    p++;
}

printf("\n");

//数组下标访问
for (i = 0; i < 5; i++)
{
    printf("%d ", arr[i]);
}

image-20210727221251221

image-20210727221401734

int arr[3][5] = { {1,2,3},{4,5},{6,7,8,9,0} };
int* p = &arr[0][0];
int i = 0;
for (i = 0; i < 15; i++)
{
    printf("%d ", *p);
    p++;
}

image-20210727221915685

**理解:**把所有元素放到1个一维数组内

image-20210728103000563

3. 数组越界

数组的下标有范围限制

下标规定从0开始,如果输入n个元素,最后一个元素的下标是n-1

数组下标小于0,或大于n-1,则数组越界访问

二维数组也存在越界,行列不能超出范围

#include <stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int i = 0;
	//越界
	for (i = 0; i <10; i++)
	{
		printf("%d ", arr[i]);//不会报错
		//arr[i] = 0;//err
	}

	return 0;
}

image-20210728104108524

4. 数组作为函数参数

往往我们在写代码的时候,会将数组作为参数传进函数。

4.1 冒泡排序

image-20210728152908452

错误示例

image-20210728154917150

数组名在传递给函数的时候,会降级变成首元素的地址

冒泡排序函数的正确设计

当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。

所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr

那么,函数内部的 sizeof(arr) 结果是4。

//正确代码
//排序方式:冒泡,选择,插入,快速排序
//冒泡排序

#include <stdio.h>

//void Sort(int arr[],int sz)
void Sort(int *arr, int sz)
{

	int i = 0;
	//冒泡排序的趟数
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序的过程
		int j = 0;
        int flag = 1;//假设已经有序
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				//交换
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;
			}
		}
		if (flag == 1)
		{
			break;
		}

	}		
}

void Print(int*p, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		//printf("%d ", p[i]);//p理解为数组名
		//printf("%d ", *(p + i));
		printf("%d ", *p++);//先解引用,后++
	}
}

int main()
{
	int arr[] = { 1,4,2,3,8,7,5,6,9,0 };

	//数组传参
	//排序
 
	//数组名单独放在sizeof内部的时候,如:sizeof(arr),这里的arr表示整个数组,不是首元素的地址。
	//数组名在传递给函数的时候,会降级变成首元素的地址
 	
	int sz = sizeof(arr) / sizeof(arr[0]);//函数外部求取元素个数,40/4,传参
 
	Sort(arr,sz); //Sort(arr[10]);err,访问第11个元素
	//数组传参-实际上传过去的数组首元素的地址-用int指针接收

	Print(arr,sz);

	return 0;
}

4.2 数组名是什么?

数组名就是首元素的地址
有2个例外

  1. sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小
  2. &数组名,这里的数组名表示整个数组,取出的是数组的地址

image-20210728171143089

image-20210728171158340

image-20210728171213523

#include <stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5};
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr);
	
	printf("------------------------\n");
	
	printf("%p\n", arr+1);
	printf("%p\n", &arr[0]+1);
	printf("%p\n", &arr+1);

	return 0;
}

5. 实例

实例1:三子棋

image-20210728172227218

实例2:扫雷

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-06 10:59:24  更:2021-09-06 11:01:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 5:06:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计