掘根宝典之C语言指针详解

目录

什么是指针?

与指针相关的运算符

指针类型的意义

 指针的大小

初始化

将指针直接指向一个已经存在的变量或内存地址:

使用malloc函数动态分配内存,并将指针指向新分配的内存:

使用calloc函数动态分配内存,并将指针指向新分配的内存,同时将内存初始化为0:

使用静态初始化:

赋值

直接赋值操作符(=):

使用malloc函数分配内存并赋值给指针:

使用calloc函数分配内存并赋值给指针:

解引用

指针和整数相加

指针和整数相减

递增指针

递减指针

指针求差

指针关系运算

空指针

const与指针

指向常量的指针:

常量指针:

指向常量的常量指针:

二级指针


什么是指针?

C语言中的指针是一个变量,用于存储另一个变量的内存地址。

通过指针,可以间接访问和修改变量的值。

我们口语中的指针是指的是指针变量,指针变量的值是个地址

指针变量的声明需要指定所指向的变量类型,例如int、char等。

指针变量的声明格式为:

指针变量所指向的变量类型 *指针变量名;

*和指针名之间的空格可有可无

与指针相关的运算符

通过取址操作符&,可以获得变量的内存地址。

例如,对于一个整型变量x,可以通过&x表示其内存地址。

解引用操作符*

*指针名代表该指针指向的地址

比如 int*a=&b;*a就代表变量b的地址

指针类型的意义

1,指针类型决定了指针在被解引用时访问几个字节;

比如

int*的指针被解引用时只能访问一个int类型的大小(即4个字节)

char*的指针被解引用时只能访问一个char类型大小(即1个字节)

2.指针类型决定了指针加减操作时跳过几个字节

比如

char*a,则a+1时跳过1个字节

int*a,则a+1时跳过4个字节

我们可以看个例子

int n[2] = { 1,2 };
int* w = n;
printf("%d %d", *w, *(w + 1));

运行结果

1 2

 指针的大小

在C语言中,不同类型的指针在内存中占用的大小是相同的,即指针的大小不依赖于指向的数据类型。

无论是指向char、int、float或其他类型的指针,在32位系统上占用4个字节(32位,即x86),在64位系统上占用8个字节(64位,即x64)。

 printf("%zd\n", sizeof(int*));printf("%zd\n", sizeof(char*));printf("%zd\n", sizeof(float*));

在64位上是

8
8
8

这是因为指针的作用是存储另一个变量的内存地址,而内存地址的大小是由系统的位数决定的。

指针存储的是一个地址值,不论指针指向的数据类型的大小如何,指针本身的大小都是固定的。

指针大小的固定性使得在C语言中可以实现通用的指针操作和类型转换。

需要注意的是,指针变量本身的大小是固定的,但指针所指向的内存区域的大小取决于指针指向的数据类型。对于一个指向int类型的指针,它所指向的内存区域大小是sizeof(int)。指针的大小只是存储指针所需的内存空间,而不是指针所指向的数据的大小。

 

初始化

在C语言中,指针可以通过以下方式进行初始化:

  1. 将指针直接指向一个已经存在的变量或内存地址:

    int num = 10;
    int *ptr = # // 将指针ptr指向变量num的地址
    

  2. 使用malloc函数动态分配内存,并将指针指向新分配的内存:

    int *ptr = (int*)malloc(sizeof(int));  // 分配一个整型变量所需的内存
    

  3. 使用calloc函数动态分配内存,并将指针指向新分配的内存,同时将内存初始化为0:

    int *ptr = (int*)calloc(1, sizeof(int));  // 分配一个整型变量所需的内存,并将内存初始化为0
    

  4. 使用静态初始化:

    int *ptr = NULL;  // 将指针初始化为空指针
    

需要注意的是,在使用指针之前,应该确保指针已经初始化,并且指向了有效的内存地址。

否则就将指针指向NULL

赋值

在C语言中,可以使用以下方式将一个指针赋值给另一个指针:

  1. 直接赋值操作符(=):

    int *ptr1;
    int *ptr2;
    int num = 10;ptr1 = #  // 将ptr1指向num的地址
    ptr2 = ptr1;  // 将ptr2赋值为ptr1(即ptr2也指向num的地址)
    

  2. 使用malloc函数分配内存并赋值给指针:

    int *ptr1;
    int *ptr2;ptr1 = (int*)malloc(sizeof(int));  // 分配内存并将其地址赋值给ptr1
    *ptr1 = 10;  // 给ptr1指向的内存赋值ptr2 = ptr1;  // 将ptr2赋值为ptr1(两者指向同一块内存)
    

  3. 使用calloc函数分配内存并赋值给指针:

    int *ptr1;
    int *ptr2;ptr1 = (int*)calloc(1, sizeof(int));  // 分配内存并将其地址赋值给ptr1(内存初始化为0)
    *ptr1 = 10;  // 给ptr1指向的内存赋值ptr2 = ptr1;  // 将ptr2赋值为ptr1(两者指向同一块内存)
    

需要注意的是,在进行指针赋值操作时,应确保指针指向的内存是有效的,并且在使用指针之前进行了初始化。同时,指针赋值只是将指针指向的内存地址进行了复制,而不是复制内存中的内容

解引用

在C语言中,指针解引用是指通过指针获取指针所指向的变量的值。

可以使用*运算符来对指针进行解引用操作。

下面是使用指针解引用的示例:

int num = 10;  // 定义一个整型变量 num
int *ptr = #  // 定义一个指向 num 的指针 ptrprintf("num 的值为:%d\n", num);  // 直接输出 num 的值
printf("ptr 所指向的变量的值为:%d\n", *ptr);  // 通过指针解引用输出 num 的值

在上面的示例中,通过*ptr可以获取指针ptr所指向的变量num的值。在将指针解引用后,可以像操作普通变量一样使用解引用后的值。

需要注意的是,在对指针进行解引用之前,应确保指针指向的内存是有效的。否则,解引用无效的指针可能会导致程序崩溃或未定义的行为。

指针和整数相加

在C语言中,指针和整数是可以进行相加的。

当一个指针和一个整数相加时,指针的地址值会根据整数的值进行偏移。偏移的单位是指针所指向类型的字节大小。

例如,如果一个指针指向一个整型变量,该整型变量占用4个字节,则相加操作会根据整数值乘以4来改变指针的地址值。

下面是一个示例:

int arr[] = {1, 2, 3, 4, 5};  // 定义一个整型数组
int *ptr = arr;              // 定义一个指向数组的指针,初始指向数组的第一个元素// 将指针向前移动两个元素
ptr = ptr + 2;printf("ptr 所指向的值为:%d\n", *ptr);  // 输出 ptr 所指向的值(即数组的第三个元素)

ptr+2和&arr[2]等价

在上面的示例中,ptr指向整型数组arr的第一个元素。通过将ptr与整数2相加,可以使指针向前移动两个元素的偏移量,即指向数组的第三个元素。通过对指针进行解引用,可以获取到新的位置的值。

需要注意的是,指针与整数相加时,结果的类型仍然是指针类型。根据指针所指向的数据类型的大小,相加的整数会根据数据类型的大小进行调整。

指针和整数相减

在C语言中,指针减去一个整数的操作被称为指针的算术运算。其规则如下:

当一个指针减去一个整数时,整数的值将乘以指针指向的数据类型的大小,然后将所得结果从指针的值中减去。最终的结果是一个新的指针,指向原来指针所指向的位置减去整数的大小。

例如,假设有一个指针p指向一个int类型的数据,它的地址是0x1000,那么p - 2的结果将是一个新的指针,指向地址为0x1000 - 2 * sizeof(i的位置。nt)

看个例子

 int arr[] = { 1, 2, 3, 4, 5 };  // 定义一个整型数组int* ptr = &arr[2];              // 定义一个指向数组的指针,初始指向数组的第一个元素// 将指针向前移动两个元素ptr = ptr -2;printf("ptr 所指向的值为:%d\n", *ptr);

这里ptr-2相当于&arr[0]

运行结果是 

ptr 所指向的值为:1

同样需要注意,进行指针的算术运算时,必须确保指针指向的内存是有效的,否则结果是未定义的。此外,指针的算术运算还要遵守指针的合法性和边界条件,以避免访问非法内存。

递增指针

在C语言中,可以使用递增操作符(++)来递增指针。

递增指针会使指针指向下一个元素或下一个位置。

示例代码如下所示:

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr;  // 指向数组的第一个元素ptr++;  // 递增指针,指向数组的第二个元素printf("%d\n", *ptr);  // 输出:2

在上述示例中,开始时,指针ptr指向数组的第一个元素。通过递增操作符(++),指针ptr的值增加了一个元素的大小(假设int类型占4个字节),指针现在指向了数组的第二个元素。

需要注意的是,递增操作符(++)不仅可以递增指针,还可以递增指向数组、字符串或者任何连续内存块的指针。另外,递增操作也可以应用于指针变量本身,而不仅仅是指向的内容。

示例代码如下所示:

int x = 10;
int *ptr = &x;  // 指向整型变量xptr++;  // 递增指针,指向下一个整型变量的地址printf("%d\n", *ptr);  // 输出:未定义,因为ptr指向了未经初始化的内存

在上述示例中,指针ptr开始时指向整型变量x。通过递增操作符(++),指针ptr的值增加了一个整型变量的大小(假设int类型占4个字节),指针现在指向了未经初始化的内存。因此,对指针解引用会产生未定义的行为。

递减指针

在C语言中,可以使用递减操作符(--)来递减指针。递减指针会使指针指向上一个元素或上一个位置。

示例代码如下所示:

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = &arr[4];  // 指向数组的最后一个元素ptr--;  // 递减指针,指向数组的倒数第二个元素printf("%d\n", *ptr);  // 输出:4

在上述示例中,开始时,指针ptr指向数组的最后一个元素。通过递减操作符(--),指针ptr的值减少了一个元素的大小(假设int类型占4个字节),指针现在指向了数组的倒数第二个元素。

需要注意的是,递减操作符(--)不仅可以递减指针,还可以递减指向数组、字符串或者任何连续内存块的指针。另外,递减操作也可以应用于指针变量本身,而不仅仅是指向的内容。

示例代码如下所示:

int x = 10;
int *ptr = &x;  // 指向整型变量xptr--;  // 递减指针,指向上一个整型变量的地址printf("%d\n", *ptr);  // 输出:未定义,因为ptr指向了未经初始化的内存

在上述示例中,指针ptr开始时指向整型变量x。通过递减操作符(--),指针ptr的值减少了一个整型变量的大小(假设int类型占4个字节),指针现在指向了未经初始化的内存。因此,对指针解引用会产生未定义的行为。

指针求差

在C语言中,可以使用减法操作符(-)来计算两个指针之间的差值。这个差值表示两个指针之间相隔的元素个数,而不是它们之间的字节数。

具体用法如下:

int arr[5] = {1, 2, 3, 4, 5};
int *ptr1 = &arr[1];  // 指向数组的第二个元素
int *ptr2 = &arr[4];  // 指向数组的最后一个元素int diff = ptr2 - ptr1;  // 计算指针之间的差printf("%d\n", diff);  // 输出:3

在上述示例中,ptr1指向数组的第二个元素,ptr2指向数组的最后一个元素。通过将ptr2减去ptr1,可以得到它们之间的差值,即3。这表示从ptr1移动到ptr2需要3个元素的距离。

需要注意的是,两个指针只有在指向同一数组(或数组的结尾位置)中的元素时,才能进行指针相减操作。否则,结果将是未定义的。

另外,指针相减的结果是一个整数类型,表示两个指针相差的单位个数,并不是指向元素的实际大小。

指针关系运算

在C语言中,指针比较的规则如下:

  1. 相等性比较:使用"=="运算符可以比较两个指针是否指向同一个内存地址。如果两个指针指向同一个内存地址,比较的结果为真(1),否则为假(0)。

  2. 不等性比较:使用"!="运算符可以比较两个指针是否指向不同的内存地址。如果两个指针指向不同的内存地址,比较的结果为真(1),否则为假(0)。

  3. 大小比较:使用">"、">="、"<"和"<="等运算符可以比较两个指针所指向的内存地址的大小关系。这里的比较是基于内存地址的值的大小。

    • 如果两个指针指向数组中的不同元素,那么比较的结果取决于它们指向的元素在数组中的相对位置。
    • 如果两个指针指向同一个数组中的不同元素,那么比较的结果取决于它们指向的元素在数组中的索引位置。
    • 如果两个指针都指向不同的数组,那么它们之间的比较没有定义。

需要注意的是,指针比较操作只有在指针指向的内存地址属于同一个数组或同一个对象时才有意义。否则,比较的结果是未定义的。因此,在进行指针比较之前,应该确保指针引用的对象是有效的。

下面是一些C语言中指针关系运算的例子:

  1. 判断两个指针是否相等:
int* p1 = NULL;
int* p2 = NULL;
if (p1 == p2) {// 两个指针相等
}

  1. 判断两个指针是否不相等:
int* p1 = NULL;
int* p2 = NULL;
if (p1 != p2) {// 两个指针不相等
}

  1. 比较两个指针的大小关系:
int arr[5] = {1, 2, 3, 4, 5};
int* p1 = &arr[0];
int* p2 = &arr[2];
if (p1 < p2) {// p1指向的元素在p2指向的元素之前
}
if (p1 > p2) {// p1指向的元素在p2指向的元素之后
}
if (p1 <= p2) {// p1指向的元素在p2指向的元素之前或相等
}
if (p1 >= p2) {// p1指向的元素在p2指向的元素之后或相等
}

  1. 判断指针和NULL之间的关系:
int* p = NULL;
if (p == NULL) {// 指针为空
}
if (p != NULL) {// 指针不为空
}

这些例子演示了C语言中指针关系运算符的用法。需要注意的是,在进行指针关系运算之前,必须确保指针是有效的,即它指向的内存是有效的。否则,结果是未定义的。

空指针

在C语言中,空指针是指没有指向任何有效对象或函数的指针。空指针用NULL宏表示,其实质是一个整型常量0。

以下是一些关于空指针的常见用法:

  1. 声明空指针:
int* ptr = NULL;
char* str = NULL;

这里将指针ptr和str声明为空指针,即它们暂时不指向任何有效的内存地址。

  1. 判断指针是否为空:
if (ptr == NULL) {// 指针为空
}

可以使用相等运算符(==)将指针与NULL进行比较,来判断指针是否为空。

  1. 传递空指针到函数:
void foo(int* ptr) {if (ptr == NULL) {// 指针为空}// 其他操作
}int main() {int* ptr = NULL;foo(ptr);return 0;
}

可以将空指针作为参数传递给函数,并在函数内部判断指针是否为空。

需要注意的是,对空指针进行解引用操作(如*ptr)是非法的,会导致程序崩溃或未定义行为。因此,在使用指针之前,应始终确保它不为空。

const与指针

在C语言中,const关键字可以与指针结合使用,用于声明指向常量的指针或常量指针。

指向常量的指针:

使用const修饰指针所指向的内容,表明指针所指向的内容是不可修改的。

const int* p; // 指向常量的指针,p指向的内容不可修改,但p本身可修改
int num = 5;
p = &num; // 合法
*p = 10; // 非法,指针指向的内容不可修改

p可改,*p不可改

常量指针:

使用const修饰指针本身,表明指针本身是不可修改的。即指针指向的地址不可修改。

int* const p; // 常量指针,p本身不可修改,但p指向的内容可修改
int num = 5;
p = &num // 非法,不可改变指针指向
*p = 10; // 合法,指针指向的内容可修改

p不可改,*p可改

指向常量的常量指针:

既不允许修改指针本身,也不允许修改指针所指向的内容。

const int* const p; // 指向常量的常量指针,p本身和p指向的内容都不可修改
int num = 5;
p = &num // 非法,指针本身不可修改
*p = 10; // 非法,指针指向的内容不可修改

p和*p都不可改

通过使用const关键字可以灵活地控制指针所指向的内容是否可修改,以及指针本身是否可修改。常量指针和指向常量的指针在函数参数传递中特别有用,可以避免不必要的修改。

二级指针

在C语言中,二级指针(double pointer)也称为指向指针的指针。它本质上是一个指针变量,存储的是另一个指针的地址。

语法上,二级指针的声明和使用方式如下:

int** ptr2;  // 声明一个二级指针int main() {int num = 10;int* ptr1 = #  // 声明一个指针并将其指向变量num的地址ptr2 = &ptr1;     // 将指向ptr1的地址赋给二级指针ptr2printf("Value of num: %d\n", **ptr2);   // 通过二级指针访问变量num的值printf("Address of ptr1: %p\n", *ptr2); // 通过二级指针访问指针ptr1的地址return 0;
}

在上面的例子中,我们声明了一个二级指针ptr2,它存储了指向ptr1的地址。

通过二级指针ptr2可以访问ptr1所指向的地址和值。通过两次解引用操作**ptr2,我们可以获得指向的变量num的值。通过一次解引用操作*ptr2,我们可以获得指针ptr1的地址。

二级指针通常用在需要传递指针的地址作为参数的函数中,可以通过传递二级指针来修改原始指针的值。

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

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

相关文章

Javascript:常量与数据类型

一、前言 介绍完变量之后我们来对常量进行了解一番&#xff0c;关于常量我们需要知道些什么呢&#xff1f; 二、正文 1.常量的基本使用 使用const声明的变量称为常量&#xff0c;当某个变量的字面量无需改动的时候就能够用到常量。 //声明一个常量 const G 9.8 //输出这个常量…

您的计算机已被pings勒索病毒感染?恢复您的数据的方法在这里!

导言&#xff1a; 在数字时代&#xff0c;数据是企业和个人生活中不可或缺的一部分。然而&#xff0c;随着勒索病毒的不断进化和传播&#xff0c;我们的数据面临着前所未有的威胁。其中&#xff0c;.pings 勒索病毒是最新一轮威胁之一&#xff0c;它以其独特的加密算法和无情的…

leetcode-字符串中的单词数

434. 字符串中的单词数 题解&#xff1a; 这个问题可以通过遍历字符串&#xff0c;当遇到非空格字符时&#xff0c;判断其前一个字符是否为空格&#xff0c;如果是&#xff0c;则说明这是一个新的单词的开始&#xff0c;计数器加一。最后返回计数器的值即可。 class Solutio…

【Redis | 第一篇】快速了解Redis

文章目录 1.快速了解Redis1.1简介1.2与其他key-value存储的不同处1.3Redis安装——Windows环境1.3.1下载redis1.3.2启动redis1.3.3进入redis客户端1.3.4修改配置 1.4Redis安装——Linux环境1.4.1安装命令1.4.2启动redis1.4.3进入redis客户端 1.5配置修改1.6小结 1.快速了解Redi…

MyBatis 学习(七)之 缓存

目录 1 MyBatis 缓存介绍 2 一级缓存 3 二级缓存 3.1 二级缓存介绍 3.2 二级缓存配置 3.3 二级缓存测试 4 参考文档 1 MyBatis 缓存介绍 MyBatis 缓存是 MyBatis 中的一个重要特性&#xff0c;用于提高数据库查询的性能。MyBatis 提供了一级缓存和二级缓存两种类型的缓存…

Git与GitHub:解锁版本控制的魔法盒子

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

cetos7 Docker 安装 gitlab

一、gitlab 简单介绍和安装要求 官方文档&#xff1a;https://docs.gitlab.cn/jh/install/docker.html 1.1、gitlab 介绍 gitLab 是一个用于代码仓库管理系统的开源项目&#xff0c;使用git作为代码管理工具&#xff0c;并在此基础上搭建起来的Web服务平台&#xff0c;通过该平…

(六)Dropout抑制过拟合与超参数的选择--九五小庞

过拟合 即模型在训练集上表现的很好&#xff0c;但是在测试集上效果却很差。也就是说&#xff0c;在已知的数据集合中非常好&#xff0c;再添加一些新数据进来效果就会差很多 欠拟合 即模型在训练集上表现的效果差&#xff0c;没有充分利用数据&#xff0c;预测准确率很低&a…

笨办法学 Python3 第五版(预览)(一)

原文&#xff1a;Learn Python the Hard Way, 5th Edition (Early Release) 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 模块 1&#xff1a;Python 入门 练习 0&#xff1a;准备工作 这个练习没有代码。这只是你完成的练习&#xff0c;让你的计算机运行 Python。…

Unity 游戏设计模式:单例模式

本文由 简悦 SimpRead 转码&#xff0c; 原文地址 mp.weixin.qq.com 单例模式 在 C# 游戏设计中&#xff0c;单例模式是一种常见的设计模式&#xff0c;它的主要目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点。单例模式在游戏开发中具有以下几个作用&#xf…

Matlab 机器人工具箱 Link类

文章目录 1 Link类1.1 机械臂Link类1.2 构造函数1.3 信息/显示方法1.4 转换方法1.5 操作方法1.6 测试方法1.7 重载操作1.8 属性(读/写)1.9 例子2 Link.Link2.1 创建机器人连杆对象2.2 OPTIONS2.3 注意2.4 旧语法2.5 例子3 Link的其他函数3.1 Link.A3.2 Link.char3.3 Link.displ…

unity学习(44)——选择角色菜单——顺利收到服务器的数据

本节的思路参考自&#xff0c;内容并不相同&#xff1a;13ARPG网络游戏编程实践&#xff08;十三&#xff09;&#xff1a;角色选择UI及创建面板制作&#xff08;四&#xff09;_哔哩哔哩_bilibili 现在的代码写在MessageManager.cs中&#xff0c;函数名UserHandler(是从OnMess…

Revit-二开之创建墙-(6)

Revit API窗间墙 protected override Result OnExecute(ExternalCommandData commandData, ref string message, ElementSet elements) {try{// 获取当前活动的文档

你是否知道Python的列表翻转、排序和多维列表

1.reverse() 表示翻转列表中的元素&#xff0c;不会生成新列表 list1 [2343, 55, 4, 345, 676, 768] list1.reverse() print(list1) # [768, 676, 345, 4, 55, 2343] 2.sort() 对原列表元素进行排序&#xff0c;默认是升序 list1 [2343, 55, 4, 345, 676, 768] list1…

腾讯云幻兽帕鲁服务器在Linux和Windows操作系统上的安全性对比如何?哪个更加安全?

腾讯云幻兽帕鲁服务器在Linux和Windows操作系统上的安全性对比如何&#xff1f; Linux因其资源利用率高、稳定性和安全性较强而受到许多专业用户的青睐。这表明在Linux操作系统上&#xff0c;腾讯云可能会更倾向于提供高安全性的服务环境。然而&#xff0c;并没有直接比较Linu…

MySql--死锁

一、什么是mysql死锁? MySQL中的死锁是指多个事务同时请求对同一资源进行操作(读或写),并且由于资源被互斥地锁定,导致彼此无法继续进行。当发生死锁时,MySQL会自动选择其中一个事务作为死锁的牺牲者,回滚该事务,并释放锁定的资源,从而解除死锁。 以下是一些处理MyS…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的夜视行人检测系统(Python+PySide6界面+训练代码)

摘要&#xff1a;开发高效的夜视行人检测系统对于提升夜间安全和监控效能至关重要。本篇博客详尽介绍了如何利用深度学习技术搭建一个夜视行人检测系统&#xff0c;并提供了完整的实现代码。本系统采用了先进的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5进行了性能比较…

嵌入式Linux中GPIO设置的一些基本指令和步骤

一、GPIO的介绍 嵌入式Linux中的GPIO&#xff08;General Purpose Input/Output&#xff0c;通用输入/输出&#xff09;是一种常用的接口&#xff0c;允许开发者直接控制硬件设备的某些引脚&#xff0c;进行诸如LED控制、传感器读取、设备状态监测等任务。 二、设置步骤和示例…

蓝桥杯复习之二分法与前缀和

题目&#xff1a;最佳牛围栏 题目链接&#xff1a;https://www.acwing.com/problem/content/104/ 题意&#xff1a;农夫约翰的农场由 N 块田地组成&#xff0c;每块地里都有一定数量的牛&#xff0c;其数量不会少于 1 头&#xff0c;也不会超过 2000 头。 约翰希望用围栏将一…

GEE学习笔记003-访问asset文件

在 Google Earth Engine (GEE) 中&#xff0c;您可以通过将 asset 文件的路径直接写入代码中来引用它。这是通过在文件路径前加上 ee.Image() 或 ee.FeatureCollection() 来实现的&#xff0c;具体取决于您想要导入的是影像还是矢量数据。 以下是导入 asset 文件并将其直接写入…