C语言指针与数组 进阶
本章主要是补充 指针和数组方面的指示,把前面指针的知识补充下。参考前面的C语言基础—指针
C语言指针与数组 进阶
- 用一级指针访问二维数组
- ❗易错点: 不能直接`指针变量=数组名`
- 指向数组的指针
- 1. 指向指针的指针
- 2. 指向一维数组的指针 (*P)[4]—行指针
- 二维数组名
- 指针数组
- ❗易错点: 区别行指针 (*ps)[10]— *ps[10] — *(ps[10])
- ❗❗指针数组的作用
- 指针数组表示二维数组的举例:p[i]=a[i]
- 动态申请和释放二维数组
- 动态一维数组实现
- 用指针数组实现
- - 为什么不用定义int *a[N]?
- 动态分配内存的过程
- 分配内存的图示
- 定义指针数组
- 动态申请指针数组
- 用指针数组处理多个字符串
- 二维字符数组存储多个字符串
- 使用指针数组存储多个字符串
- 下面举几个例子
- 字符串排序 (指针数组)
- 方法一: 二维字符数组
- 方法二:使用指针数组处理
- n个字符串排序(指针数组实现)
用一级指针访问二维数组
数组其实是按行排序在内存地址中的,所以可以省略行,不能省略列。
具体解释见C语言数组——多维数组
利用这一特性,可以通过指针偏移遍历数组
比如假设a是一个M行N列的数组,M,N列是预定义的常量,定义如下:
int a[M][N];
int *p=&a[0][0];
下面的语句段可以求出数组a中所有元素的累加和:
sum=0;
for(i=0;i<M*N;i++,p++)
sum+=p;
也可以通过行列号做循环变量,使用双重循环来实现:
求所有上三角元素的和:
for(i=0;i<M;i++)for(j=i;j<N;j++)sum+=*(p+i*N+j); //或者sum+= *(*(p+i)+j);
❗易错点: 不能直接指针变量=数组名
- 也就是说不能
p=&a[0][0]能写成p=a
二维数组名a可以被解释为指向第一行的指针,即a和&a[0]是等价的。
但是a并不是指向二维数组中第一个元素的指针,而是指向二维数组中第一行的指针。
因此,将指针p赋值为二维数组a是不正确的,因为它们指向的内存地址不同,不能直接相互赋值。
也就是说数组名在多维数组中指的是指向第一行的指针. a+1代表的是下一行的数据
指向数组的指针
1. 指向指针的指针
类型名 **变量名
比如下面:
int i,*p=&i;
int **dp;
dp=&p;
dp中存储的是指针变量p的地址
,我们说,dp指向指针变量p
,dp是指向指针(p)的指针(变量)
2. 指向一维数组的指针 (*P)[4]—行指针
比如二维数组: int a[3][4]
定义了一个3行4列的二维数组,可以看成a[0] a[1] a[2]三个元素组层的一维数组,每个元素a[i]都是一个有4个int型元素的值,定义一个指针p,我们已经知道P+1是下一行
- 如何定义这种已经知道列的二维数组的指针呢?
可以这样写: int (*p)[4]
;
声明了p是一个指向数组的指针,指向的是int[4]类型,
- 如何让p指向一维数组a[0]?
可以这样写:p=&a[0]
;
- (*p)[0] 即 a[0][0]的引用
- (*p)[1] 即 a[0][1]的引用
- 要想下一行,p+1
比如假设a是一个M行N列的数组,M,N列是预定义的常量,定义如下:
int a[M][N];
int *p=&a[0];
下面的代码可以求元素和:
sum=0;
for(i=0;i<M;i++,p++) //p++自增,将指向下一行for(j=0;j<N;j++)sum+=(*p)[j]; //p指向数组a[i],(*p)等价于a[i]
二维数组名
我们通过上面已经知道 a是指向一维数组a[0]的指针,类似这样 *(a+i)就是对a[i]的引用
我们知道数组在内存中是按竖着按行排列的
所以 *(a+i)+j
就是 第i行a[i]再+j 取得 a[i][j]的地址
也就是说如图:
指针 a[i]+1、 *(a+i)+1指向a[i][1]; *(a[i]+1)、*( *(a+i)+1)是对a[i][1]的引用
举例: 用指针访问二维数组 求元素和
#include <stdio.h>int main() {int i,j,m,n;int sum = 0;scanf("%d%d",&m,&n);int a[m][n];printf("\n");for (int i = 0; i < m; i++) for ( j = 0; j < n; j++)scanf("%d",*(a+i)+j); //这是指针for (int i = 0; i < m; i++)for ( j = 0; j < n; j++) sum += *(*(a+i)+j); //指针引用取值printf("三角元素的和为%d\n", sum);return 0;
}
指针数组
指针数组就是数组里面每个都是指针
格式:类型名* 数组名[数组长度]
数组元素是指针类型,用于存储地址
-
int a[10];
a是一个数组,它有10个元素
每个元素的类型都是整型 -
char *color[5];
color是一个数组,它有5个元素
每个元素的类型都是字符指针
❗易错点: 区别行指针 (*ps)[10]— *ps[10] — *(ps[10])
int *ps[10];
定义了含有10个元素的一维数组ps,每个元素都是int指针类型
区别于 int (*ps)[10]
,这个是一个指向10列的二维数组的一个指针变量.
因为[]的优先级高于*
,所以int *ps[10];
解释为int*(ps[10])
这样
❗❗指针数组的作用
指针数组的主要作用是表示二维数组,尤其是字符串数组
。
用指针数组表示二维数组的好处是:
二维数组的每一行或字符串数组的每个字符串可以具有不同的长度.
在二维数组中,每一行可以具有不同的长度,但是使用传统的二维数组表示方式,每一行的长度都必须相同,这给程序的编写带来了一定的限制。而使用指针数组来表示二维数组,则可以轻松地实现每一行具有不同长度的效果。例如,可以使用指针数组来表示一个3行不等长的二维数组,代码如下:
int a1[] = {1, 2, 3}; int a2[] = {4, 5}; int a3[] = {6, 7, 8, 9}; int *p[] = {a1, a2, a3};
在上面的例子中,指针数组p中的每个元素都是一个指向int类型的指针,每个指针指向一个长度不同的int类型数组,即一个二维数组的一行。在上面的例子中,第一行有3个元素,第二行有2个元素,第三行有4个元素。
另外,在字符串数组中,每个字符串的长度也可以不同,使用指针数组来表示字符串数组可以更加灵活地处理不同长度的字符串。
因此,使用指针数组来表示二维数组或字符串数组,可以具有不同的长度,从而更加灵活地处理数据。
指针数组表示二维数组的举例:p[i]=a[i]
在表示二维数组时,指针数组可以被用来代替二维数组。二维数组是一组连续的内存空间,元素的地址是连续的。而指针数组则是一组指针,每个指针指向一个内存空间,这些内存空间不一定是连续的。因此,指针数组可以用来表示非连续的二维数组。
例如,可以使用指针数组来表示一个3行4列的二维数组,代码如下:
int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int *p[3];
for (int i = 0; i < 3; i++) {p[i] = a[i];
}
在上面的例子中,指针数组p中的每个元素都是一个指向int类型的指针,每个指针指向一个长度为4的int类型数组,即一个二维数组的一行,比如p[0]指向a[0]第一行的。
在循环中,通过将指针数组p中的每个元素指向二维数组a的每一行,就可以使用指针数组p来表示整个二维数组。
使用指针数组表示二维数组的好处是,可以更加灵活地对数组进行操作。例如,可以通过修改指针数组中的元素来改变二维数组的大小和形状,而不需要创建一个新的二维数组。同时,指针数组的内存使用也更加灵活,可以根据需要动态分配内存。
动态申请和释放二维数组
输入整数n和n,然后输入m行n列的矩阵。然后输出矩阵。要求动态申请和释放二维数组
- 方法1:用
动态一维数组
的方法存储二维数组 - 方法2:用
指针数组
实现
动态一维数组实现
也就是申请的内存块是一维数组那样的,然后一个一个装进去。
代码如下:
#include <stdio.h>
#include <stdlib.h>int main() {int n, m,i,j;scanf("%d %d", &n, &m);// 动态申请一维数组 m*n个内存块int *p = (int *) malloc(n * m * sizeof(int));for (i = 0; i < m; i++){ for (j = 0; j < n; j++)scanf("%d",p+i*n+j);//scanf("%d",&p[i*n+j]);}for (i = 0; i < m; i++){ for (j = 0; j < n; j++)printf("%d ",p[i*n+j]);//指针也可以作为数组名printf("\n");
}return 0;
}
用指针数组实现
(1) 声明一个一维指针数组,存放每行的首地址
int **a; //指向指针数组的首地址
a=(int **)malloc(m*sizeof(int*));
(2) 用malloc为每一行元素申请空间
for(i=0;i<m;i++)
a[i]=(int*)malloc(n*sizeof(int));
(3) 读入m*n个元素
(4) 输出矩阵
(5) 释放每一个行指针所指空间
for(i=0;i<m;i++)
free(a[i]);
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define N 100int main() {int n, m,i,j;// 读入矩阵的行列数printf("请输入矩阵的行数和列数:\n");scanf("%d %d", &m, &n);// 动态分配指针数组,存放每行的首地址int **a=(int **)malloc(m * sizeof(int *)); //申请存储m个指针的内存块// 动态分配每一行的空间for (i = 0; i < m; i++) {a[i] = (int *)malloc(n * sizeof(int));}// 读入矩阵元素printf("请输入矩阵的元素:\n");for (i = 0; i < m; i++) {for (j = 0; j < n; j++) {scanf("%d", &a[i][j]);}}// 输出矩阵printf("您输入的矩阵为:\n");for (i = 0; i < m; i++) {for (j = 0; j < n; j++) {printf("%d ", a[i][j]);}printf("\n");}// 释放每一行的空间for(i=0;i<m;i++)free(a[i]);return 0;
}
下面解释下?
- 为什么不用定义int *a[N]?
实际上,定义 int *a[N] 可以用来定义一个指针数组,每个指针指向一个整型数组。在这个例子中,指针数组的长度为 N,但是在动态分配内存时使用的是一个 m 倍的空间,这可能会导致内存溢出。因此,指针数组的定义在这里并不适用。相反,需要使用一个指向指针的指针 int **a 来动态分配内存。
动态分配内存的过程
首先,通过调用 malloc() 函数来为存储指针的内存块分配空间。为了能够存储 m 个指针,需要分配 m * sizeof(int *)
字节的内存。然后,通过循环分配每一行的内存空间。每一行需要分配n * sizeof(int)
字节的内存。
总结一下,a[i] 可以直接使用是因为它在数组 a 中被定义为指向整型数组的指针。在动态分配内存时,首先需要为存储指针的内存块分配空间,然后循环为每一行分配内存。
也就是系统自动分配了指针数组,因为通过分配m * sizeof(int *)
字节的内存相当于知道 a[i]的地址,然后再通过n * sizeof(int)
分配每一行的列的内容的内存。
分配内存的图示
定义指针数组
动态申请指针数组
用指针数组处理多个字符串
二维字符数组存储多个字符串
char ccolor[][7]={"red","blue","yellow","green","purple"};
一个字符占一位,列数取决于最长的字符串
使用指针数组存储多个字符串
char *pcolor[]={"red","blue","yellow","green","purple"};
这时候指针数组里面每个指针指向字符串首地址
优点是更节省内存空间
下面举几个例子
字符串排序 (指针数组)
{“red”,“blue”,“yellow”,“green”,“purple”}; 请排序后输出
方法一: 二维字符数组
#include <stdio.h>
#include <string.h>int main(void)
{ char colors[][7] = {"red", "blue", "yellow", "green", "purple"}; int num_colors = sizeof(colors) / sizeof(colors[0]); //行// Sort the colors
for (int i = 0; i < num_colors - 1; i++) {for (int j = i + 1; j < num_colors; j++) {if (strcmp(colors[i], colors[j]) > 0) {char temp[7];strcpy(temp, colors[i]);strcpy(colors[i], colors[j]);strcpy(colors[j], temp);}}
}// Print the sorted colors
for (int i = 0; i < num_colors; i++) {printf("%s\n", colors[i]);
}return 0;
}
方法二:使用指针数组处理
本质是改变指针数组中每个指针的地址,改变指向方向
#include <stdio.h>
#include <string.h>int main(void) { char *colors[] = {"red", "blue", "yellow", "green", "purple"}; int num_colors = sizeof(colors) / sizeof(colors[0]);// Sort the colors
for (int i = 0; i < num_colors - 1; i++) {for (int j = i + 1; j < num_colors; j++) {if (strcmp(colors[i], colors[j]) > 0) {char *temp;temp = colors[i];colors[i] = colors[j];colors[j] = temp;}}
}// Print the sorted colors
for (int i = 0; i < num_colors; i++) {printf("%s\n", colors[i]);
}return 0;
}
n个字符串排序(指针数组实现)
输入n和n个字符串(每个字符串不超过80个字符)请排序后输出,要求使用指针数组(而不是二维字符数组)处理
可以使用指针数组和动态内存分配来实现,具体思路如下:
- 首先读入字符串的个数 n;
- 使用 malloc 函数动态分配一个指针数组 strArr,大小为 n;
- 然后使用 fgets 函数逐个读入字符串,将每个字符串的地址存储到指针数组中;
- 对指针数组中的字符串进行排序,可以使用 qsort 函数;
- 最后遍历指针数组,按照顺序输出每个字符串。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_LENGTH 80int cmp(const void *a, const void *b) {return strcmp(*(char **)a, *(char **)b);
}int main() {int n;printf("请输入字符串的个数:");scanf("%d", &n);// 动态分配指针数组char **strArr = (char **)malloc(n * sizeof(char *));if (strArr == NULL) {printf("动态分配内存失败!\n");exit(1);}// 逐个读入字符串for (int i = 0; i < n; i++) {strArr[i] = (char *)malloc((MAX_LENGTH + 1) * sizeof(char));if (strArr[i] == NULL) {printf("动态分配内存失败!\n");exit(1);}printf("请输入第%d个字符串:", i + 1);getchar(); // 去掉回车fgets(strArr[i], MAX_LENGTH + 1, stdin);// 如果字符串最后一个字符是 '\n',将其替换为 '\0'int len = strlen(strArr[i]);if (strArr[i][len - 1] == '\n') {strArr[i][len - 1] = '\0';}}// 排序指针数组qsort(strArr, n, sizeof(char *), cmp);// 输出排序后的字符串for (int i = 0; i < n; i++) { printf("%s\n", strArr[i]); }// 释放动态分配的内存
for (int i = 0; i < n; i++) {free(strArr[i]);
}
free(strArr);return 0;
}
解释下:
cmp 函数是一个用于比较两个字符串指针的函数,它的作用是在使用 qsort 函数对指针数组进行排序时,指定排序的规则。
qsort 函数的原型为:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)
(const void *, const void *));
其中,compar 参数
是一个指向比较函数的指针, 它接受两个指针参数
,分别指向数组中需要比较的两个元素。比较函数应该返回一个整数值,表示两个元素的大小关系。
在本例中,cmp 函数的作用是比较两个字符串指针所指向的字符串,返回它们的大小关系。具体地,cmp 函数的参数类型为 const void *
,也就是指向任意类型的指针。我们需要将它们转换为指向 char *
类型的指针,然后再进行字符串比较。
为了实现这个目的,我们首先将 a 和 b 转换为指向 char ** 类型的指针。然后使用 * 运算符来取出指针所指向的字符串,再使用 strcmp 函数进行比较。
因此,cmp 函数的实现如下:
int cmp(const void *a, const void *b) {return strcmp(*(char **)a, *(char **)b);
}
这样,在调用 qsort 函数时,我们可以将 cmp 函数的地址作为参数传递,qsort 函数会根据 cmp 函数的返回值来排序指针数组中的元素。
相关文章:

C语言指针与数组 进阶
本章主要是补充 指针和数组方面的指示,把前面指针的知识补充下。参考前面的C语言基础—指针 C语言指针与数组 进阶用一级指针访问二维数组❗易错点: 不能直接指针变量数组名指向数组的指针1. 指向指针的指针2. 指向一维数组的指针 (*P)[4]—行指针二维数组名指针数组…...

Java连接SqlServer错误
Java连接SqlServer错误 🏠个人主页:shark-Gao 🧑个人简介:大家好,我是shark-Gao,一个想要与大家共同进步的男人😉😉 🎉目前状况:23届毕业生,目…...

Elastic 可观察性 - 适用于当今 “永远在线” 世界的解决方案
作者:Bahubali Shetti 当今世界,我们的生活很大程度上由应用程序控制。 无论是用于商业用途还是个人用途,我们都希望这些应用程序 “始终在线” 并能够立即做出响应。 这些高期望对开发人员和运营人员提出了巨大的要求。 管理这些应用程序需…...

Temu病毒式营销,如何在大红利时期快人一步?
从去年9月开始,拼多多推出海外版Temu,大手笔烧钱买量、大手笔补贴消费者,通过令人难以置信的超低价(比如一件卫衣2.44美元,且包邮),在北美市场迅速打开局面,并引发海外网友“人传人”…...

ChatGPT使用案例之写代码
ChatGPT使用案例之写代码 可以对于许多开发者而言又惊又喜的是我们可以使用ChatGPT 去帮我们完成一些代码,或者是测试用例的编写,但是正如我们提到的又惊又喜,可能开心的是可以解放一部分劳动力,将自己的精力从繁琐无聊的一些任务…...

蓝桥杯刷题第二十五天
第一题:全球变暖 题目描述 你有一张某海域 NxN 像素的照片,"."表示海洋、"#"表示陆地,如下所示: ....... .##.... .##.... ....##. ..####. ...###. ....... 其中"上下左右"四个方向上连在一起的一片陆地组成一…...

【牛客网】
目录知识框架No.1 前缀和NC14556:数圈圈NC14600:珂朵莉与宇宙NC21195 :Kuangyeye and hamburgersNC19798:区间权值NC16730:runNC15035:送分了qaqNo.2 字符串:小知识点:基于KMP算法的…...

SpringBoot中的事务
事务 Springboot有3种技术方式来实现让加了Transactional的方法能使用数据库事务,分别是"动态代理(运行时织入)"、“编译期织入”和“类加载期织入”。这3种技术都是基于AOP(Aspect Oriented Programming,面向切面编程)思想。(在网…...

Zookeeper客户端Curator5.2.0节点事件监听CuratorCache用法
Curator提供了三种Watcher: (1)NodeCache:监听指定的节点。 (2)PathChildrenCache:监听指定节点的子节点。 (3)TreeCache:监听指定节点和子节点及其子孙节点。…...

C++ using:软件设计中的面向对象编程技巧
C using:理解头文件与库的使用引言using声明a. 使用方法和语法b. 实际应用场景举例i. 避免命名冲突ii. 提高代码可读性c. 注意事项和潜在风险using指令a. 使用方法和语法b. 实际应用场景举例i. 将整个命名空间导入当前作用域ii. 代码组织和模块化using枚举a. C11的新特性b. 使用…...

修建灌木顺子日期
题目 有 N 棵灌木整齐的从左到右排成一排。爱丽丝在每天傍晩会修剪一棵灌 木, 让灌木的高度变为 0 厘米。爱丽丝修剪灌木的顺序是从最左侧的灌木开始, 每天向右修剪一棵灌木。当修剪了最右侧的灌木后, 她会调转方向, 下一天开 始向左修剪灌木。直到修剪了最左的灌木后再次调转方…...

深入学习JavaScript系列(七)——Promise async/await generator
本篇属于本系列第七篇 第一篇:#深入学习JavaScript系列(一)—— ES6中的JS执行上下文 第二篇:# 深入学习JavaScript系列(二)——作用域和作用域链 第三篇:# 深入学习JavaScript系列ÿ…...

Mybatis中的Map的使用和模糊查询的需求实现及其防SQL注入优化
文章目录一.Map的使用和模糊查询的需求实现及其防SQL注入优化1.1 Map的使用1.2 模糊查询的实现1.2.1 防SQL注入优化1.2.2 总结一.Map的使用和模糊查询的需求实现及其防SQL注入优化 1.1 Map的使用 替换之前的根据ID查询信息: 1.编写接口: User getUse…...

【redis】redis缓存更新策略
目录一、缓存更新策略二、主动更新策略三、Cache Aside Pattern3.1 删除缓存还是更新缓存?3.2 如何保证缓存与数据库的操作同时成功或失败?3.3 先操作缓存还是先操作数据库3.3.1 先删缓存再删库3.3.2 先删库再删缓存一、缓存更新策略 1.内存淘汰:不用自…...

LeetCode刷题--复制带随机指针的链表
复制带随机指针的链表1.题目2.解题思路3.完整代码1.题目 题目链接: https://leetcode.cn/problems/copy-list-with-random-pointer/ 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 …...

关于我的第一台电脑 华硕
2011年买的,第一台电脑是华硕 U36KI243SD 13.3英寸 白色 i5 1G独显 USB3.0 500G 当时花了5699,着实是一笔巨款,我同学看了一眼就说“我C,这本真好”。 买它主要还是因为好看。当时win7也才开始流行,感觉用上这个本&…...

【华为OD机试 2023最新 】 最大化控制资源成本(C++ 100%)
文章目录 题目描述输入描述输出描述备注用例题目解析C++题目描述 公司创新实验室正在研究如何最小化资源成本,最大化资源利用率,请你设计算法帮他们解决一个任务混部问题: 有taskNum项任务,每个任务有开始时间(startTime),结束时间(endTime),并行度(parallelism)…...

leetcode 有序数组的平方(977)
题目 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 示例 1: 输入:nums [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变…...

文本三剑客之awk
文本三剑客之awkawk命令的简要处理流程awk命令的执行过程NR输出分割符和输入分割符案例awk命令引用shell变量awk的几个内置函数流控数组awk命令的简要处理流程 awk命令的执行过程 awk BEGIN{commands} pattern{commands} END{commands}files 执行BEGIN {commands}语句块中的语…...

RK3568平台开发系列讲解(驱动基础篇)IS_ERR函数的使用
🚀返回专栏总目录 文章目录 一、IS_ERR函数二、内核错误码沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 IS_ERR 函数的使用。 一、IS_ERR函数 对于任何一个指针来说,必然存在三种情况: 一种是合法指针一种是 NULL (也就是空指针)一种是错误指针(也就…...

特殊的类之注解
注解🚙注解的入门和作用以及原理示例注解的方法名就是属性名Retention的作用Target的作用注解的属性设置默认值天生我材必有用,千金散尽还复来。——唐代李白《将进酒》 在Java中,注解实际上是特殊类型的接口,当我们使用注解时&am…...

商业分享:盲盒电商开启电商新可能
盲盒,顾名思义,一个看不出里面装着什么东西的盒子。当你看不见盲盒里的商品时,你会思考盲盒里可能装着什么,它会诱发你的好奇心,而在好奇心的促使下,你会不由自主地买一个拆开来看,刚好大多数盲…...

【计算机架构】如何计算 CPU 时间
目录 0x00 响应时间和吞吐量(Response Time and Throughput) 0x01 相对性能(Relative Performance) 0x02 执行时间测量(Measuring Execution Time) 0x03 CPU 时钟(Clocking) 0x…...

银行数字化转型导师坚鹏:银行行长如何进行数字化转型
银行行长如何进行数字化转型 ——数字化转型背景下重塑银行行长核心竞争力 授课背景: 很多银行存在以下问题:银行行长不知道如何进行数字化转型?银行行长不清楚银行数字化能力模型的内涵?银行行长不知道如何通过数字化转型提…...

N32G45x学习笔记--- gpio引脚复用
关于gpio的引脚复用需要开启复用时钟 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);官方引脚复用: 芯片上电默认使能 SWD-JTAG 调试接口,调试接口被映射到 GPIO 端口上 禁止 JTAG 使能SWJ-DP /* 禁止 JTAG 使能SWJ-DP */GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_S…...

ArcGIS Pro中使用深度学习的高分辨率土地覆盖制图
本文非常详细的讲解了利用深度学习在高分辨率土地覆盖制图的应用,本文作者:Amin Tayyebi,文章从数据准备到训练U-Net模型等等细节都有讲解。本译文只是使用谷歌翻译而成。文章可能有错误语句及不通顺情况,所以仅供参考学习。有需要…...

【学习笔记】「NOI2018」冒泡排序
从题解的角度来说,这是一道简单题。不过考场上在没有任何人提示的情况下要想出正确的结论其实并不容易。 我自己做这道题的时候,因为没有想清楚题目给出的下界能取到的充要条件是什么,所以到了很晚才猜到结论,以至于难以为继。 …...

【Ruby学习笔记】3.Ruby 语法及数据类型
前言 本章介绍Ruby的语法和数据类型。 Ruby 语法 让我们编写一个简单的 Ruby 程序。所有的 Ruby 文件扩展名都是 .rb。所以,把下面的源代码放在 test.rb 文件中。 实例 #!/usr/bin/ruby -wputs "Hello, Ruby!";在这里,假设您的 /usr/bin …...

华为OD机试题【字符匹配】用 Java 解 | 含解题说明
华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典本篇题目:字符匹配 题目 给你一个字符串…...

JavaScript数组对象的浅拷贝与深拷贝(二)实现对象深拷贝的方法(5种)
JavaScript实现对象深拷贝的方法(5种)知识回调(不懂就看这儿!)场景复现实现对象深拷贝的五种方法1.json暴力转化2.es6扩展运算符3.for in循环遍历对象4.Object.assign()对象的合并5.利用循环和递归的方式实现对象浅拷贝…...