C语言数组全面解析:从初学到精通

数组

    • 1. 前言
    • 2. 一维数组的创建和初始化
    • 3. 一维数组的使用
    • 4. 一维数组在内存中的存储
    • 5. 二维数组的创建和初始化
    • 6. 二维数组的使用
    • 7. 二维数组在内存中的存储
    • 8. 数组越界
    • 9. 数组作为函数参数
    • 10. 综合练习
      • 10.1 用函数初始化,逆置,打印整型数组
      • 10.2 交换两个整型数组
      • 10.3 三子棋
      • 10.4 扫雷

在这里插入图片描述

1. 前言

大家好,我是努力学习游泳的鱼。今天我们来学习数组。
在这里插入图片描述
数组分为一维数组和二维数组,我们需要学习它们如何创建和初始化,如何使用,如何在内存中存储。话不多说,让我们开始对数组的学习吧。

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

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

一维数组的创建格式如下:
数组的元素类型 数组名[常量表达式];
int arr[100]; // 表示数组能存放100个int类型的数据
我们使用大括号来初始化数组。
完全初始化:对数组的所有元素都进行初始化。大括号里初始化的元素个数和数组最多存放的元素个数相同。
int arr[10] = {1,2,3,4,5,6,7,8,9,10}; // 完全初始化:数组最多存放10个元素,大括号内初始化了10个元素
不完全初始化:只初始化数组的部分元素,剩下的被初始化成0
int arr[100] = {0}; // 不完全初始化:第一个元素被手动初始化成0,剩下的元素默认被初始化为0
如果对数组初始化,数组大小可以省略,默认为初始化元素的个数。如下面两种写法效果是相同的。

int arr[5] = {1,2,3,4,5};
int arr[] = {1,2,3,4,5}; // 省略数组大小,默认是5

如果创建数组时不初始化,则数组大小不能省略,此时分为两种情况:

  1. 局部数组里存放的都是随机值。
  2. 全局数组会被默认初始化为0
int arr1[10]; // 默认初始化为0int main()
{int arr2[10]; // 存储的是随机值return 0;
}

对于一个变量,这两种情况也成立。

  1. 当一个局部变量不初始化时,存储的是随机值。
  2. 当一个全局变量或静态变量不手动初始化时,会被默认初始化成0
int a; // 默认初始化为0int main()
{static int b; // 默认初始化为0int c; // 存储的是随机值return 0;
}

本质上,这是存储位置的差异导致的。局部变量是存储在栈区的,栈区上的数据如果不初始化,存储的是随机值。全局变量和静态变量是存储在静态区的,静态区上的数据如果不手动初始化,会被默认初始化为0

C99中引入了变长数组的概念,允许数组的大小用变量来指定,如果编译器不支持C99中的变长数组,那就不能使用。

int n = 10;
int arr[n]; // 变长数组

变长数组不能初始化。

int n = 10;
int arr[n] = {0}; // 不能像这样初始化

3. 一维数组的使用

数组通过下标来访问,数组的下标是0开始的。
[]是下标引用操作符。

比如,int arr[] = {10,20,30,40,50};,10的下标是020的下标是130的下标是240的下标是350的下标是4
那么,arr[3]对应的就是40,如果我们想把40改成400,就这么写:arr[3] = 400;
我们如何计算数组的元素个数呢?很简单,用数组的总大小除以数组一个元素的大小就行了。比如对于arr数组,数组元素个数sz就可以这么算:int sz = sizeof(arr) / sizeof(arr[0]);
假设我们想存储1~100的整数并打印出来,就可以这么写:

#include <stdio.h>int main()
{int arr[100] = { 0 };int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (; i < sz; ++i){arr[i] = i + 1;}for (i = 0; i < sz; ++i){printf("%d ", arr[i]);}return 0;
}

4. 一维数组在内存中的存储

一维数组在内存中是连续存放的。
随着数组下标的增长,地址是由低到高变化的。

我们可以写个程序来验证。

#include <stdio.h>int main()
{int arr[10] = { 0 };int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (; i < sz; ++i){printf("&arr[%d] = %p\n", i, &arr[i]);}return 0;
}

我们把数组元素的地址按照下标从低到高打印出来。
在这里插入图片描述

我们发现,相邻两个元素之间的地址都差4,这是因为数组在内存中是连续存放的,相邻元素的地址就差一个int,即4个字节。
并且,随着下标的增长,地址是由低到高变化的。

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

如我们想要创建一个三行五列的二维整型数组,就可以这么写:int arr[3][5];这个数组有三行五列,共15个元素,每个元素是int类型的。
int int int int int
int int int int int
int int int int int
对二维数组进行初始化要使用大括号,初始化时会一行一行放,一行放满后才会放下一行。若是不完全初始化,剩余元素会被默认初始化成0
如:int arr[3][5] = { 1,2,3,4,5,6 };的效果是:
1 2 3 4 5
6 0 0 0 0
0 0 0 0 0
由于二维数组的每一行都可以看作一个一维数组,如果要对每一行分别初始化,可以在大括号里使用大括号。
这么说有点抽象,举个例子:int arr[3][5] = { {1,2}, {3,4}, {5,6} };的效果是:
1 2 0 0 0
3 4 0 0 0
5 6 0 0 0
如果对二维数组初始化,二维数组的行可以省略,但是列不能省略。如果省略二维数组的行,编译器会根据初始化的内容来确定有几行。
如:int arr[][5] = {1,2,3,4,5,6};的效果是:
1 2 3 4 5
6 0 0 0 0
由于两行就够放了,编译器会默认行数为2
再比如:int arr[][5] = { {1,2}, {3,4}, {5,6} };的效果是:
1 2 0 0 0
3 4 0 0 0
5 6 0 0 0
由于3行就够放了,编译器会默认行数为3
如果我们想给数组的所有元素都初始化成0,就可以这么写:
int arr[3][5] = {0};数组的第一个元素被初始化成0,剩下的元素会被默认初始化成0,效果是,数组的全部元素都被初始化成0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

6. 二维数组的使用

二维数组也是用下标来访问的。和一维数组的区别是,二维数组有两个下标,行标和列标。行标和列标都是从0开始的。比如说,一个35列的数组arr,每个位置的元素的访问方式如下:
arr[0][0] arr[0][1] arr[0][2] arr[0][3] arr[0][4]
arr[1][0] arr[1][1] arr[1][2] arr[1][3] arr[1][4]
arr[2][0] arr[2][1] arr[2][2] arr[2][3] arr[2][4]
如果我们想把这些元素打印出来,可以用一层循环产生行标,另一层循环产生列标。每行打印完后,记得换个行。

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

当然,二维数组有几行几列也是可以通过代码计算出来的。
计算行数的方法:sizeof(arr) / sizeof(arr[0]);即数组的总大小除以数组第一行元素的大小。
计算列数的方法:sizeof(arr[0]) / sizeof(arr[0][0]);即数组第一行元素的大小除以数组第一行第一列的元素的大小。
上面的代码就可这样改进:

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

7. 二维数组在内存中的存储

我们用下面的程序把二维数组每个元素的地址打印出来。

#include <stdio.h>int main()
{int arr[3][5] = { 0 };int i = 0;for (; i < sizeof(arr) / sizeof(arr[0]); ++i){int j = 0;for (; j < sizeof(arr[0]) / sizeof(arr[0][0]); ++j){printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);}}return 0;
}

在这里插入图片描述
我们发现,每两个元素之间都差4个字节,每当发生换行,如第一行最后一个元素arr[0][4]到第二行第一个元素arr[1][0]也差4个字节。arr是一个整型数组,每两个元素之间差1int类型的大小。这说明:

二维数组在内存中也是连续存放的。
随着下标的增长,地址也是由低到高变化的。

除此之外,我们还可以把二维数组的每个元素理解成一维数组。如:对于三行五列的二维数组arrarr[0]就是这个二维数组的第一个元素,同时arr[0]也是一个有五个元素的一维数组,这五个元素分别是arr[0][0]arr[0][1]arr[0][2]arr[0][3]arr[0][4]

8. 数组越界

数组的下标是有范围限制的。
数组的下标规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1
所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,所以程序员写代码时,最好自己做越界的检查。
如下面的程序,当i10时就越界了。

int main()
{int arr[10] = {0};int i = 0;for (; i<=10; ++i){arr[i] = i;}return 0;
}

二维数组的行和列也可能存在越界。

9. 数组作为函数参数

数组名表示什么?看看下面的代码:

#include <stdio.h>int main()
{int arr[10] = { 0 };printf("arr = %p\n", arr);printf("arr + 1 = %p\n", arr + 1);printf("&arr[0] = %p\n", &arr[0]);printf("&arr[0] + 1 = %p\n", &arr[0] + 1);printf("&arr = %p\n", &arr);printf("&arr + 1 = %p\n", &arr + 1);printf("sizeof(arr) = %d\n", sizeof(arr));return 0;
}

运行结果:
在这里插入图片描述
由运行结果可知,数组名(arr)和数组首元素地址(&arr[0])是完全相同的,且+1之后也是完全相同的,都跳过了4个字节(1int)。数组的地址(&arr)和前两者值是相同的,但+1之后跳过了40个字节(即跳过了整个数组),这是因为,如果写arr&arr[0]都表示首元素地址,即第一个整型元素的地址,+1会跳过一个整型;如果写&arr,取出的是整个数组的地址,+1自然也跳过了整个数组。注意:以上所有计算都是十六进制的计算,如所谓的跳过40个字节其实是+0x28,再转换成十进制后得到的40
并且,sizeof(arr)计算的是整个数组的大小,即40

数组名一般表示数组首元素的地址。但是有两个例外:

  1. sizeof(数组名),数组名不是数组首元素的地址,数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,数组名不是数组首元素的地址,数组名表示整个数组,取出的是整个数组的地址。

题目:写一个函数,对一个整型数组进行冒泡排序。

冒泡排序:对数组中2个相邻的元素进行比较,如果不满足就交换。

比如,一个数组里存放的是
9 8 7 6 5 4 3 2 1 0
我想把它排成升序,也就是左边的数要比右边的数小。
首先比较98,因为98大,不满足升序,就交换。
8 9 7 6 5 4 3 2 1 0
接着比较97,因为97大,不满足升序,就交换。
8 7 9 6 5 4 3 2 1 0
接着比较96,因为96大,不满足升序,就交换。
8 7 6 9 5 4 3 2 1 0
……
这一趟冒泡排序下来,数组就排序成
8 7 6 5 4 3 2 1 0 9
9的位置就正确了。接下来进行下一趟冒泡排序。由于9的位置处在正确的位置上,下一趟冒泡排序就不需要考虑9了,只需排序除了9之外的数字。
首先比较87,因为87大,不满足升序,就交换。
7 8 6 5 4 3 2 1 0 9
接着比较86,因为86大,不满足升序,就交换。
7 6 8 5 4 3 2 1 0 9
……
这一趟冒泡排序下来,数组就排序成
7 6 5 4 3 2 1 0 8 9
8的位置就正确了。
有没有发现,一趟冒泡排序,可以使一个数字的位置正确。那么,假设有10个数字,总共需要几趟冒泡排序呢?答案:10个数字需要9趟冒泡排序。因为一趟冒泡排序搞定一个数字,9趟冒泡排序就搞定9个数字,最后一个数字的位置自然也是正确的。
那么一趟内部又需要多少次比较呢?假设有10个数字,第一趟就需要比较9次,第一趟结束后就搞定了其中一个数字,只需排序剩下9个数字,所以第二趟需要比较8次。由于每趟排序都能够搞定一个数字,每趟排序都会比上一趟少一次比较,这样就知道每一趟需要几次比较了。
有了以上的分析,我们需要写两层循环。外层循环负责控制冒泡排序的趟数,假设数组有sz个元素,就需要排序sz-1趟;内层循环控制一趟内部冒泡排序的比较,第一趟需要sz-1次比较,第二趟需要sz-2次比较,后面每趟都比前一趟少一次比较,如果外层循环的循环变量(假设是i)是从0开始的,那第i趟就需要sz-1-i次比较。
如果一趟比较完后没有发生交换,则数组就已经有序了,就不需要继续排序了。我们可以定义一个flag并初始化为1,假设数组已经有序。如果发生交换,则把flag改成0。如果一趟冒泡排序中没有发生交换,则flag仍然是1,就已经有序了,不需要继续排序了。
数组元素个数怎么知道呢?一定要在数组创建的局部范围内计算数组的元素个数int sz = sizeof(arr) / sizeof(arr[0]);因为如果传参给别的函数后,我们使用数组名传参,由前面的知识可知,数组名表示数组首元素的地址,传递过去的是一个指针,所以sizeof(arr)就是4或者8sizeof(arr) / sizeof(arr[0])这个表达式是无法计算出数组元素个数的。

#include <stdio.h>void bubble_sort(int arr[], int sz)
{int i = 0;for (; i < sz - 1; ++i){// 一趟冒泡排序int flag = 1; // 假设已经有序int j = 0;for (; j < sz - 1 - i; ++j){if (arr[j] > arr[j + 1]){flag = 0;// 交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}if (1 == flag)return;}
}int main()
{int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);// 冒泡排序bubble_sort(arr, sz);int i = 0;for (; i < sz; ++i){printf("%d ", arr[i]);}return 0;
}

当然,就一种情况是无法代表所有场景的。我写了个测试代码,在不同场景下测试这个冒泡排序是否正确,供大家参考。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>int test_bubble_sort()
{srand((unsigned int)time(NULL));const int sz = 100; // 数组元素个数int* arr = (int*)malloc(sz * sizeof(int));if (NULL == arr){perror("test_bubblesort::malloc");return 0;}int i = 0;for (; i < 1000; ++i){// 生成随机数组int j = 0;for (; j < sz; ++j){arr[j] = rand();}// 冒泡排序bubble_sort(arr, sz);// 检验排序是否成功for (j = 0; j < sz - 1; ++j){if (arr[j] > arr[j + 1]){free(arr);return 0; // 排序失败}}}free(arr);return 1; // 检验成功
}int main()
{int ret = test_bubble_sort();if (1 == ret)printf("检验成功\n");elseprintf("检验失败\n");return 0;
}

10. 综合练习

10.1 用函数初始化,逆置,打印整型数组

初始化和打印应该相当简单了吧,只需要产生所有的下标,遍历数组,就能够访问整个数组并初始化或打印了。唯一需要注意的是,整型数组无法在函数内部使用sizeof(arr) / sizeof(arr[0])计算元素个数,因为数组作为函数参数传递时,传递的是首元素的地址。
初始化函数(假设初始化为全0):

void init(int arr[], int sz)
{int i = 0;for (; i < sz; ++i){arr[i] = 0;}
}

打印函数:

#include <stdio.h>void print(int arr[], int sz)
{int i = 0;for (; i < sz; ++i){printf("%d ", arr[i]);}printf("\n");
}

接下来讲讲如何逆置。类似字符串的逆置,整型数组的逆置只需交换第一个元素和最后一个元素,再交换第二个元素和倒数第二个元素,接着交换第三个元素和倒数第三个元素……
如果用下标来访问数组,我们需要一个左下标left指向第一个元素,一个右下标right指向最后一个元素,交换后,left向后走,right向前走,当left还在right左边时,说明还有元素可以交换,否则就跳出循环。

void reverse(int arr[], int sz)
{int left = 0;int right = sz - 1;while (left < right){int tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;++left;--right;}
}

10.2 交换两个整型数组

如何交换两个整型数组arr1arr2(假设两个数组一样大)呢?
很简单,只需要遍历两个数组,把对应位置的元素交换就行了!

#include <stdio.h>int main()
{int arr1[] = { 1,3,5,7,9 };int arr2[] = { 2,4,6,8,0 };int i = 0;int sz = sizeof(arr1) / sizeof(arr1[0]);printf("交换前:\n");printf("arr1: ");for (i = 0; i < sz; ++i){printf("%d ", arr1[i]);}printf("\narr2: ");for (i = 0; i < sz; ++i){printf("%d ", arr2[i]);}printf("\n");// 交换arr1和arr2for (i = 0; i < sz; ++i){int tmp = arr1[i];arr1[i] = arr2[i];arr2[i] = tmp;}printf("交换后:\n");printf("arr1: ");for (i = 0; i < sz; ++i){printf("%d ", arr1[i]);}printf("\narr2: ");for (i = 0; i < sz; ++i){printf("%d ", arr2[i]);}printf("\n");return 0;
}

10.3 三子棋

我们可以用已有的知识,实现一个三子棋小游戏。详细讲解戳这里

10.4 扫雷

再来实现一个扫雷小游戏。详细讲解戳这里

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/724480.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面试篇【MyCat】常见面试题(2024最新)

Mycat 1.Mycat 分库分表中间件&#xff0c;将存放在一个数据库的数据存放在不同的多个数据库中。来分散负载。 scheme 逻辑库&#xff0c;对应mysql的数据库&#xff0c;一个逻辑库定义了包含的所有table.是数据库集群对外的统一访问接口。table 逻辑表&#xff0c;和物理数…

【Java EE】文件内容的读写⸺数据流

目录 &#x1f334;数据流的概念&#x1f338;数据流分类 &#x1f333;字节流的读写&#x1f338;InputStream&#xff08;从文件中读取字节内容)&#x1f33b;示例1&#x1f33b;示例2&#x1f33b;利用 Scanner 进行字符读取 &#x1f338;OutputStream(向文件中写内容&…

00. Nginx总结-错误汇总

/www/wangmingqu/index.html" is forbidden (13: Permission denied) 错误图片 错误日志 2024/01/09 22:26:27 [error] 1737#1737: *1 "/www/wangmingqu/index.html" is forbidden (13: Permission denied), client: 192.169.1.101, server: www.wangmingqu.c…

算法:滑动窗口

文章目录 例题1&#xff1a;长度最小的子数组例题2&#xff1a;无重复字符的最长子串例题3&#xff1a;最大连续1的个数 III例题4&#xff1a;将 x 减到 0 的最小操作数例题5&#xff1a;水果成篮例题6&#xff1a;找到字符串中所有字母异位词例题7&#xff1a;串联所有单词的子…

碳视野|全国首个ESG区域行动方案通过,上海政府推进ESG有八“要”

引领绿色转型&#xff0c;共筑低碳未来&#xff01;AMT企源碳管理团队深入解读碳领域政策、概念及标准&#xff0c;分享实践经验&#xff0c;助力产业绿色发展。我们启动“碳视野、碳课堂、碳实践”三大专栏&#xff0c;紧跟碳行业政策动态&#xff0c;以“科普实践分享”为核心…

【python】六个常见爬虫案例【附源码】

大家好&#xff0c;我是博主英杰&#xff0c;整理了几个常见的爬虫案例&#xff0c;分享给大家&#xff0c;适合小白学习 一、爬取豆瓣电影排行榜Top250存储到Excel文件 近年来&#xff0c;Python在数据爬取和处理方面的应用越来越广泛。本文将介绍一个基于Python的爬虫程序&a…

STM32 GPIO的几种工作模式

介绍STM32 GPIO的几种工作模式 1、输出模式 STM32的引脚输出有两种方式&#xff1a; 1、推挽输出 2、开漏输出 1.1 推挽输出 当引脚设置为推挽输出时&#xff0c;P-MOS和N-MOS共同配合工作。 当使用HAL库 //该函数的作用就是将P-MOS导通&#xff0c;N-MOS关…

SqlServer中连续号及断号查询—附源码

效果如下图所示&#xff1a; SqlServer中连续号及断号查询SQL如下&#xff1a; --1.定义临时表 DECLARE TestTemp TABLE(TestCode NVARCHAR(50),TestNum INT )DECLARE DataTemp TABLE(TestCode NVARCHAR(50),TestNumStr NVARCHAR(100) )--2.插入测试数据 INSERT INTO TestT…

国产体脂方案——蓝牙体脂秤方案

蓝牙体脂秤采用的就是BIA生物电阻抗技术&#xff0c;用户仅需1次测量&#xff0c;就能知道身体的脂肪率&#xff0c;水分率&#xff0c;基础代谢率&#xff0c;肌肉量&#xff0c;骨量&#xff0c;蛋白质&#xff0c;BMI&#xff0c;体重&#xff0c;身体的得分&#xff0c;年龄…

Linux:kubernetes(k8s)pod的基础操作(6)

Linux&#xff1a;kubernetes&#xff08;k8s&#xff09;允许在任意节点使用kubectl命令&#xff08;5&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/136460090?spm1001.2014.3001.5501 我在前两张进行了基础环境的一系列搭建&#xff0c;现在就正…

深度学习_18_模型的下载与读取

在深度学习的过程中&#xff0c;需要将训练好的模型运用到我们要使用的另一个程序中&#xff0c;这就需要模型的下载与转移操作 代码&#xff1a; import math import torch from torch import nn from d2l import torch as d2l import matplotlib.pyplot as plt# 生成随机的…

NFTScan :什么是 ERC-404?深入解读 NFT 协议的未来

上月初&#xff0c;ERC-404 成为最首要热门的话题&#xff0c;ERC-404 是由 Pandora 团队在 2 月初为创作者和开发者等开源的实验性代币标准&#xff0c;其混合 ERC-20 / ERC-721 实现&#xff0c;具有原生流动性和碎片化等特点。伴随着早期的发展&#xff0c;越来越多参与者开…

win10安全中心误删文件怎么办?解析恢复与预防策略

在使用Windows 10的过程中&#xff0c;许多用户依赖于其内置的安全中心来保护电脑免受恶意软件的侵害。然而&#xff0c;有时安全中心的误判可能导致重要文件被错误地删除。当面对这种情况时&#xff0c;了解如何恢复误删的文件并掌握预防措施显得尤为重要。本文将为您详细解析…

java常用技术栈,java面试带答案

前言 我们从一个问题引入今天的主题。 在日常业务开发中&#xff0c;我们可能经常听到 DBA 对我们说“不要”&#xff08;注意&#xff1a;不是禁止&#xff09;使用 join&#xff0c;那么为什么 DBA 对 join 这么抵触呢&#xff1f;是 join 本身有问题&#xff0c;还是我们使…

私募证券基金动态-24年2月报

成交量&#xff1a;2月日均9492.60亿元 2024年2月A股两市日均成交9492.60亿元&#xff0c;环比增加30.38%、同比增加5.77%。2月整体15个交易日&#xff0c;有4个单日交易日成交金额过万亿&#xff0c;单日交易日最高成交金额为13576.43亿元&#xff08;2月28日&#xff09;&am…

MySQL 学习笔记(基础篇 Day1)

「写在前面」 本文为黑马程序员 MySQL 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。 目录 0 课程介绍 1 MySQL 概述 1.1 数据库相关概念 1.2 MySQL 数据库 2 SQL 2.1 SQL 通用语法 2.2 SQL 分类 2.3 DDL 2.4 图形…

【leetcode C++】电话号码的字母组合

17. 电话号码的字母组合 题目 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 题目链接 . - 力扣&#xff08;LeetCode&…

1.类和对象-友元

文章目录 1.全局函数做友元代码运行结果 2.类做友元代码运行结果 1.全局函数做友元 思路分析&#xff1a; 正常情况下&#xff0c;全局函数visit()中的ROOM 类变量r是访问不到Building类中的私有成员的。但是通过在Building类中添加使用全局函数做友元&#xff0c;即可访问私有…

什么是ElasticSearch的深度分页问题?如何解决?

在ElasticSearch中进行分页查询通常使用from和size参数。当我们对ElasticSearch发起一个带有分页参数的查询(如使用from和size参数)时,ElasticSearch需要遍历所以匹配的文档直到达到指定的起始点(from),然后返回从这一点开始的size个文档 在这个例子中: 1.from 参数定义…

代码学习记录13

随想录日记part13 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.06 主要内容&#xff1a;今天的主要内容是二叉树的第二部分哦&#xff0c;主要有层序遍历&#xff1b;翻转二叉树&#xff1b;对称二叉树。 102.二叉树的层序遍历226.翻转二叉树101. 对称二叉…