[大师C语言(第二十四篇)]C语言指针探秘
引言
在C语言的学习和应用中,指针无疑是最重要、最难以掌握的概念之一。它为C语言提供了强大的功能和灵活性,同时也带来了不少的复杂性。本文将深入探讨C语言指针背后的技术,帮助你更好地理解和应用指针。
第一部分:指针的基本概念和操作
1.1 内存地址
计算机中的内存是由一系列连续的存储单元组成的,每个存储单元都有一个唯一的地址,用于访问该单元。在C语言中,我们使用指针来表示和操作内存地址。
1.2 指针的定义和声明
指针是一个变量,用于存储内存地址。在C语言中,定义一个指针变量需要使用星号(*)来表示该变量是一个指针。指针变量的类型表示它所指向的数据类型。
int *p; // 定义一个指向整数的指针变量
double *d; // 定义一个指向双精度浮点数的指针变量
1.3 指针的初始化和赋值
指针变量可以通过初始化和赋值来存储内存地址。初始化指针时,我们可以使用地址运算符(&)来获取变量的地址。
int a = 10;
int *p = &a; // 初始化指针p,使其指向变量a的地址
指针变量也可以通过赋值来改变其所存储的地址。
int b = 20;
p = &b; // 将指针p的值改为变量b的地址
1.4 指针的解引用
指针的解引用是指通过指针变量访问其所指向的内存单元。在C语言中,我们使用星号(*)来解引用指针。
int a = 10;
int *p = &a;printf("%d\n", *p); // 输出变量a的值,即10
1.5 指针的运算
指针可以进行一些基本的运算操作,如自增(++), 自减(–)和指针算术运算。这些运算可以用于访问内存中的连续存储单元。
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // 将指针p初始化为数组arr的首地址for (int i = 0; i < 5; i++) {printf("%d ", *(p + i)); // 输出数组arr的元素
}
1.6 指针与数组
在C语言中,数组名表示数组的首地址。因此,指针可以用于访问和操作数组元素。
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // 将指针p初始化为数组arr的首地址for (int i = 0; i < 5; i++) {printf("%d ", p[i]); // 使用指针访问数组元素
}
1.7 指针与函数
指针可以作为函数的参数和返回值,用于传递和返回内存地址。这使得我们可以通过指针在函数外部修改变量的值。
void swap(int *x, int *y) {int temp = *x;*x = *y;*y = temp;
}int main() {int a = 10, b = 20;swap(&a, &b); // 交换变量a和b的值printf("a = %d, b = %d\n", a, b);return 0;
}
总结
本文介绍了C语言指针的基本概念和操作,包括内存地址、指针的定义和声明、初始化和赋值、解引用、指针的运算以及指针与数组和函数的关系。掌握这些基本知识是深入理解C语言指针的关键。在下一部分中,我们将继续探讨指针的高级应用和技巧。
第二部分:指针的高级应用和技巧
2.1 指针与多维数组
在C语言中,多维数组可以通过指针来访问和操作。多维数组的元素在内存中是连续存储的,指针可以通过适当的偏移量来访问这些元素。
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
int (*p)[3] = arr; // p是一个指向包含3个整数的数组的指针for (int i = 0; i < 2; i++) {for (int j = 0; j < 3; j++) {printf("%d ", p[i][j]); // 使用指针访问二维数组元素}printf("\n");
}
2.2 指针数组和数组指针
指针数组是一个数组,其元素是指针。数组指针是一个指针,它指向一个数组。
int a = 10, b = 20, c = 30;
int *arr[3] = {&a, &b, &c}; // 指针数组,包含3个整型指针int (*p)[3]; // 数组指针,指向包含3个整数的数组
2.3 函数指针
函数指针是一个指针,它指向一个函数。在C语言中,函数名表示该函数的地址,因此可以用来初始化函数指针。
void func() {printf("Hello, World!\n");
}int main() {void (*fp)() = func; // 函数指针,指向函数funcfp(); // 通过函数指针调用函数return 0;
}
2.4 指针与动态内存分配
C语言提供了动态内存分配的功能,允许程序在运行时动态地分配和释放内存。动态内存分配通常与指针一起使用。
int *p = (int *)malloc(5 * sizeof(int)); // 分配5个整数的内存空间if (p != NULL) {for (int i = 0; i < 5; i++) {p[i] = i + 1; // 初始化动态分配的内存}for (int i = 0; i < 5; i++) {printf("%d ", p[i]); // 使用指针访问动态分配的内存}free(p); // 释放动态分配的内存
}
2.5 指针与字符串
在C语言中,字符串是通过字符数组实现的,指针可以用于访问和操作字符串。
char str[] = "Hello, World!";char *p = str; // 将指针p初始化为字符串的首地址while (*p) { // 循环遍历字符串,直到遇到空字符'\0'printf("%c", *p); // 输出字符串的字符p++; // 移动指针到下一个字符
}
printf("\n");
2.6 指针与结构体
结构体是C语言中一种用户自定义的数据类型,它允许将不同类型的数据组合在一起。指针可以用于访问和操作结构体变量。
struct Person {char name[50];int age;
};struct Person person = {"John", 30};
struct Person *p = &person; // 将指针p初始化为结构体变量person的地址printf("Name: %s, Age: %d\n", p->name, p->age); // 使用指针访问结构体成员
总结
在第二部分中,我们探讨了C语言指针的一些高级应用和技巧,包括指针与多维数组、指针数组和数组指针、函数指针、指针与动态内存分配、指针与字符串以及指针与结构体的关系。这些知识点进一步展示了C语言指针的强大功能和灵活性。在下一部分中,我们将继续探讨指针的深入话题和常见问题。
第三部分:指针的深入话题和常见问题
3.1 指针的类型转换
在C语言中,指针可以进行类型转换,但必须谨慎使用,因为不正确的类型转换可能导致数据损坏或程序崩溃。
int a = 10;
void *p = (void *)&a; // 将整型指针转换为void指针// 使用void指针时,需要转换为正确的类型
int *intPtr = (int *)p;
printf("%d\n", *intPtr);
3.2 指针的指针(多级指针)
C语言支持多级指针,即指向指针的指针。这可以在多层次的数据结构中使用,例如树、图等。
int a = 10;
int *p = &a; // 一级指针
int **pp = &p; // 二级指针printf("%d\n", **pp); // 输出10
3.3 指针与const关键字
const关键字可以与指针一起使用,用于定义指针本身、指针指向的数据或两者都是常量。
int a = 10;
int b = 20;// 指针指向的数据是常量,不能通过指针修改数据
const int *p1 = &a;
//*p1 = 30; // 错误,不能修改*p1// 指针本身是常量,不能修改指针的值
int *const p2 = &a;
//p2 = &b; // 错误,不能修改p2// 指针和指向的数据都是常量
const int *const p3 = &a;
3.4 指针与函数参数
指针作为函数参数时,可以实现函数内部对实参的修改,这是因为传递的是地址而不是数据的副本。
void increment(int *p) {(*p)++; // 修改指针指向的值
}int main() {int a = 10;increment(&a); // a的值现在为11printf("%d\n", a);return 0;
}
3.5 指针与数组的区别
虽然指针和数组名在某些情况下可以互换,但它们在底层还是有区别的。数组名是一个指向数组首元素的常量指针,而指针是一个变量,可以改变其指向。
int arr[3] = {1, 2, 3};
int *p = arr; // 数组名用作指向首元素的指针printf("%d\n", *arr); // 输出1,与*arr[0]相同
printf("%d\n", *p); // 输出1p++; // 合法,可以改变指针的值
// arr++; // 非法,不能改变数组名的值
3.6 指针与内存管理
C语言中的指针与内存管理紧密相关。正确管理内存可以避免内存泄漏和野指针等问题。
int *p = (int *)malloc(5 * sizeof(int)); // 分配内存if (p != NULL) {for (int i = 0; i < 5; i++) {p[i] = i + 1; // 使用内存}free(p); // 释放内存p = NULL; // 将指针设置为NULL,避免野指针
}
总结
在第三部分中,我们探讨了C语言指针的一些深入话题和常见问题,包括指针的类型转换、多级指针、指针与const关键字、指针与函数参数、指针与数组的区别以及指针与内存管理。这些知识点进一步加深了我们对C语言指针的理解,并强调了正确使用指针的重要性。在下一部分中,我们将通过一些实际的编程示例来巩固和运用这些知识。
第四部分:指针的编程示例和最佳实践
4.1 示例:动态创建和操作数组
在C语言中,指针可以用来动态地创建数组,这意味着数组的大小可以在运行时确定,而不是在编译时。
#include <stdio.h>
#include <stdlib.h>int main() {int size, i;printf("请输入数组的大小: ");scanf("%d", &size);// 动态分配数组int *array = (int *)malloc(size * sizeof(int));if (array == NULL) {fprintf(stderr, "内存分配失败\n");return 1;}// 初始化数组for (i = 0; i < size; i++) {array[i] = i;}// 打印数组for (i = 0; i < size; i++) {printf("%d ", array[i]);}printf("\n");// 释放内存free(array);array = NULL;return 0;
}
4.2 示例:字符串操作
指针在字符串操作中非常有用,因为字符串本质上是一系列字符的数组。以下是一个使用指针来复制字符串的示例。
#include <stdio.h>void myStrCopy(char *dest, const char *source) {while (*source) {*dest = *source;dest++;source++;}*dest = '\0'; // 添加字符串结束符
}int main() {char source[] = "Hello, World!";char dest[20];myStrCopy(dest, source);printf("原字符串: %s\n", source);printf("复制后的字符串: %s\n", dest);return 0;
}
4.3 示例:函数指针数组
函数指针数组可以用来存储多个函数的地址,这样就可以通过数组索引来调用不同的函数。
#include <stdio.h>void func1() {printf("Function 1 called.\n");
}void func2() {printf("Function 2 called.\n");
}int main() {// 函数指针数组void (*funcArray[])(void) = {func1, func2};// 通过函数指针调用函数funcArray[0]();funcArray[1]();return 0;
}
4.4 示例:结构体和指针
结构体和指针结合使用,可以创建复杂的数据结构,如链表、树等。
#include <stdio.h>
#include <stdlib.h>typedef struct Node {int value;struct Node *next;
} Node;Node *createNode(int value) {Node *newNode = (Node *)malloc(sizeof(Node));if (newNode != NULL) {newNode->value = value;newNode->next = NULL;}return newNode;
}int main() {Node *head = createNode(1);head->next = createNode(2);head->next->next = createNode(3);// 遍历链表并打印值Node *current = head;while (current != NULL) {printf("%d ", current->value);current = current->next;}printf("\n");// 释放链表内存current = head;while (current != NULL) {Node *temp = current;current = current->next;free(temp);}return 0;
}
4.5 最佳实践:避免野指针
野指针是指未初始化或未正确释放内存的指针。为了避免野指针,应该在声明指针时初始化为NULL,并在使用完毕后及时释放内存。
int *p = NULL; // 声明时初始化为NULL// ... 使用指针 ...free(p); // 释放内存
p = NULL; // 释放后重新初始化为NULL
总结
在第四部分中,我们通过一系列编程示例来展示了C语言指针的实际应用,包括动态创建和操作数组、字符串操作、函数指针数组以及结构体和指针的结合使用。这些示例不仅加深了我们对指针的理解,还提供了在实际编程中应用指针的最佳实践。在最后一部分中,我们将探讨指针在C语言中的高级数据结构和算法中的应用。
第五部分:指针在高级数据结构和算法中的应用
5.1 链表
链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表的灵活性和动态性使其在C语言中广泛使用。
typedef struct Node {int data;struct Node *next;
} Node;Node *createNode(int data) {Node *newNode = (Node *)malloc(sizeof(Node));if (newNode != NULL) {newNode->data = data;newNode->next = NULL;}return newNode;
}void insertAtBeginning(Node **head, int data) {Node *newNode = createNode(data);newNode->next = *head;*head = newNode;
}void displayList(Node *head) {Node *current = head;while (current != NULL) {printf("%d ", current->data);current = current->next;}printf("\n");
}int main() {Node *head = NULL;insertAtBeginning(&head, 3);insertAtBeginning(&head, 2);insertAtBeginning(&head, 1);displayList(head);// 释放链表内存Node *current = head;Node *next;while (current != NULL) {next = current->next;free(current);current = next;}return 0;
}
5.2 树
树是一种层次化的数据结构,由节点组成,每个节点包含数据和一个或多个指向子节点的指针。树结构在C语言中经常使用指针来实现。
typedef struct TreeNode {int data;struct TreeNode *left;struct TreeNode *right;
} TreeNode;TreeNode *createTreeNode(int data) {TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));if (newNode != NULL) {newNode->data = data;newNode->left = newNode->right = NULL;}return newNode;
}void insert(TreeNode **root, int data) {if (*root == NULL) {*root = createTreeNode(data);} else if (data < (*root)->data) {insert(&(*root)->left, data);} else {insert(&(*root)->right, data);}
}int main() {TreeNode *root = NULL;insert(&root, 5);insert(&root, 3);insert(&root, 7);insert(&root, 2);insert(&root, 4);insert(&root, 6);insert(&root, 8);// 中序遍历树// ...(中序遍历的实现省略)// 释放树的内存// ...(释放树的实现省略)return 0;
}
5.3 图
图是由节点和边组成的数据结构,节点之间可以通过边相互连接。在C语言中,图通常使用邻接表或邻接矩阵表示,这两种表示方法都涉及到指针的使用。
typedef struct Edge {int dest;struct Edge *next;
} Edge;typedef struct Vertex {char label;Edge *edges;
} Vertex;Vertex *createVertex(char label) {Vertex *newVertex = (Vertex *)malloc(sizeof(Vertex));if (newVertex != NULL) {newVertex->label = label;newVertex->edges = NULL;}return newVertex;
}void addEdge(Vertex *vertex, int dest) {Edge *newEdge = (Edge *)malloc(sizeof(Edge));if (newEdge != NULL) {newEdge->dest = dest;newEdge->next = vertex->edges;vertex->edges = newEdge;}
}int main() {Vertex *vertices = (Vertex *)malloc(3 * sizeof(Vertex));vertices[0].label = 'A';vertices[1].label = 'B';vertices[2].label = 'C';addEdge(&vertices[0], 1);addEdge(&vertices[0], 2);addEdge(&vertices[1], 2);// ...(添加更多边和操作)// 打印图for (int i = 0; i < 3; i++) {printf("Vertex %c: ", vertices[i].label);Edge *current = vertices[i].edges;while (current != NULL) {printf("%d ", current->dest);current = current->next;}printf("\n");}// 释放图的内存// ...(释放图的实现省略)return 0;
}
5.4 排序算法
指针在排序算法中扮演着关键角色,尤其是在交换元素和处理数组时。以下是一个使用指针的冒泡排序算法的示例:
#include <stdio.h>void bubbleSort(int *arr, int size) {int i, j, temp;for (i = 0; i < size - 1; i++) {for (j = 0; j < size - i - 1; j++) {if (*(arr + j) > *(arr + j + 1)) {temp = *(arr + j);*(arr + j) = *(arr + j + 1);*(arr + j + 1) = temp;}}}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int size = sizeof(arr) / sizeof(arr[0]);bubbleSort(arr, size);printf("Sorted array: \n");for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}
5.5 搜索算法
指针在搜索算法中也很重要,尤其是在二分搜索和链表搜索中。以下是一个使用指针的二分搜索算法的示例:
#include <stdio.h>int binarySearch(int *arr, int l, int r, int x) {while (l <= r) {int m = l + (r - l) / 2;if (*(arr + m) == x) {return m;}if (*(arr + m) < x) {l = m + 1;} else {r = m - 1;}}return -1;
}int main() {int arr[] = {2, 3, 4, 10, 40};int n = sizeof(arr) / sizeof(arr[0]);int x = 10;int result = binarySearch(arr, 0, n - 1, x);if (result == -1) {printf("Element is not present in array\n");} else {printf("Element is present at index %d\n", result);}return 0;
}
5.6 指针与递归
递归函数通常使用指针来操作数据结构,如链表和树。以下是一个使用指针的递归函数,用于计算链表的长度。
#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node *next;
} Node;int length(Node *head) {if (head == NULL) {return 0;} else {return 1 + length(head->next);}
}int main() {Node *head = NULL;// ...(链表的创建和插入操作省略)int len = length(head);printf("Length of the linked list: %d\n", len);// 释放链表内存// ...(释放链表的实现省略)return 0;
}
总结
在第五部分中,我们探讨了指针在高级数据结构和算法中的应用,包括链表、树、图、排序算法、搜索算法以及递归。这些示例展示了指针在C语言中的强大功能和灵活性,以及它在数据结构和算法实现中的关键作用。通过这些示例,我们可以更好地理解指针在C语言编程中的重要性,并能够在实际应用中更加有效地使用它。
总结:
本文详细介绍了C语言指针的各个方面,从基本概念和操作到高级应用和技巧。首先,我们探讨了指针的基本概念,包括内存地址、指针的定义和声明、初始化和赋值、解引用以及指针的运算。接着,我们深入研究了指针与数组、函数、动态内存分配、字符串和结构体的关系,这些都是C语言中指针常见的使用场景。
在第三部分,我们讨论了指针的深入话题和常见问题,如指针的类型转换、多级指针、指针与const关键字、指针与函数参数、指针与数组的区别以及指针与内存管理。这些知识点帮助读者更好地理解指针的复杂性和灵活性。
第四部分通过一系列编程示例,展示了指针在实际编程中的应用,包括动态创建和操作数组、字符串操作、函数指针数组以及结构体和指针的结合使用。这些示例不仅加深了我们对指针的理解,还提供了在实际编程中应用指针的最佳实践。
最后,在第五部分,我们探讨了指针在高级数据结构和算法中的应用,包括链表、树、图、排序算法、搜索算法以及递归。这些示例展示了指针在C语言中的强大功能和灵活性,以及它在数据结构和算法实现中的关键作用。
通过本文的学习,读者应该能够全面理解C语言指针的原理和应用,从而在编程实践中更加熟练和有效地使用指针。
相关文章:
[大师C语言(第二十四篇)]C语言指针探秘
引言 在C语言的学习和应用中,指针无疑是最重要、最难以掌握的概念之一。它为C语言提供了强大的功能和灵活性,同时也带来了不少的复杂性。本文将深入探讨C语言指针背后的技术,帮助你更好地理解和应用指针。 第一部分:指针的基本概…...
Docker命令总结
文章目录 Docker命令总结Docker环境Docker容器生命周期Docker容器运维Docker容器rootfsDocker镜像仓库Docker本地镜像管理Docker容器资源Docker系统日志 Docker命令总结 docker命令非常多,这里主要分为8类总结 Docker环境 可以查看Docker版本和自身的详细信息 d…...

把chatgpt当实习生,进行matlab gui程序编程
最近朋友有个项目需要整点matlab代码,无奈自己对matlab这种工科的软件完全是外行,无奈只有求助gpt这种AI助手了。大神们告诉我们,chatgpt等的助手已经是大学实习生水平啦,通过多轮指令交互就可以让他帮你完成工作啦!所…...

LabVIEW 与组态软件在自动化系统中的应用比较与选择
LabVIEW 确实在非标单机设备、测试和测量系统中有着广泛的应用,特别是在科研、教育、实验室和小型自动化设备中表现突出。然而,LabVIEW 也具备一定的扩展能力,可以用于更复杂和大型的自动化系统。以下是对 LabVIEW 与组态软件在不同应用场景中…...

html--万年历
<!DOCTYPE html> <html lang"zh_CN"><head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8" /><meta charset"utf-8" /><title>万年历</title><link rel"styles…...

2013年 阿拉斯加巴罗活动层厚度和土壤含水量
Pre-ABoVE: Active Layer Thickness and Soil Water Content, Barrow, Alaska, 2013 ABoVE前:阿拉斯加巴罗活动层厚度和土壤含水量,2013年 简介 文件修订日期:2018-01-10 数据集版本:1 摘要 该数据集提供了 2013 年 8 月在…...

超详解——python数字和运算——小白篇
目录 1.位运算 2. 常用内置函数/模块 math模块: random模块: decimal模块: 3.内置函数: 总结: 1.位运算 位运算是对整数在内存中的二进制表示进行操作。Python支持以下常见的位运算符: 按位与&…...

LabVIEW图像采集处理项目中相机选择与应用
在LabVIEW图像采集处理项目中,选择合适的相机是确保项目成功的关键。本文将详细探讨相机选择时需要关注的参数、黑白相机与彩色相机的区别及其适用场合,帮助工程师和开发者做出明智的选择。 相机选择时需要关注的参数 1. 分辨率 定义:分辨率…...

Java——IO流(一)-(2/9):File类的常用方法(判断文件类型、获取文件信息、创建删除文件、遍历文件夹)
目录 常用方法1:判断文件类型、获取文件信息 方法 实例演示 常用方法2:创建文件、删除文件 方法 实例演示 常用方法3:遍历文件夹 方法 实例演示 常用方法1:判断文件类型、获取文件信息 方法 File提供的判断文件类型、获…...

电子设计入门教程硬件篇之集成电路IC(二)
前言:本文为手把手教学的电子设计入门教程硬件类的博客,该博客侧重针对电子设计中的硬件电路进行介绍。本篇博客将根据电子设计实战中的情况去详细讲解集成电路IC,这些集成电路IC包括:逻辑门芯片、运算放大器与电子零件。电子设计…...

Unity3D测量面积和角度实现方法(二)
系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、unity测量面积👉1-1 视频效果👉1-2 先创建预制体👉1-3 在创建LineRenderer预制体👉1-4 代码如下 👉二、测量平面和测量空间切换&…...
vite 配置 typescript 环境
要在 Vite 项目中配置 TypeScript 环境,你需要遵循几个步骤来确保 TypeScript 被正确设置并可以与 Vite 一起工作。以下是一个基本的指南: 初始化项目 如果你还没有初始化项目,可以使用 npm 或 yarn 初始化一个新的项目: npm i…...

ThreadCache线程缓存
一.ThreadCache整体结构 1.基本结构 定长内存池利用一个自由链表管理释放回来的固定大小的内存obj。 ThreadCache需要支持申请和释放不同大小的内存块,因此需要多个自由链表来管理释放回来的内存块.即ThreadCache实际上一个哈希桶结构,每个桶中存放的都…...
UE5_加载本地图片(jpg, png) 转 UTexture
UE5_加载图片到UTexture __Desc使用方式源码 __Desc __Time__: 2024-06-05 16:30 __Author__: Yblackd __Desc__: UE5.2 加载本地图片 转 UTexture2D, 给材质 和 UMG 使用使用方式 新建继承BlueprintFunctionLibrary c 类复制下面源码,修改类名实测加载 jpg,jpeg,…...

Linux操作系统:Spark在虚拟环境下的安装及部署
将Spark安装到指定目录 // 通过wget下载Spark安装包 $ wget https://d3kbcqa49mib13.cloudfront.net/spark-2.1.1-bin-hadoop2.7.tgz // 将spark解压到安装目录 $ tar –zxvf spark-2.1.1-bin-hadoop2.7.tgz –C /usr/local/ // 重命名 $ mv /usr/local/spark-2.1.1-bin-hado…...

内网安全--隧道技术代理技术
注:本文仅做技术交流,请勿非法破坏... 目录 项目: 1-Ngrok 用法 2-Frp 用法 3-Nps 用法 4-Spp 用法 工具: windows下: Proxifier(推荐~) Sockscap ccproxy Linux下: Proxychains 用法 http://t.csdnimg.cn/88Ew7 隧道技术:解决不出网协议上线的问…...

彩虹易支付最新版源码
源码简介 彩虹易支付最新版源码,更新时间为5.1号 2024/05/01: 1.更换全新的手机版支付页面风格 2.聚合收款码支持填写备注 3.后台支付统计新增利润、代付统计 4.删除结算记录支持直接退回商户金额 安装环境 1.PHP版本>7.4 2.Mysql数据库 安装教…...

python生成excel数据并实现隔行变色
代码 from openpyxl import Workbook from datetime import date from openpyxl.styles import PatternFilldef create_excel():wb Workbook()sh wb.activerows [[Date, Batch 1, Batch 2, Batch 3],[date(2024, 2, 1), 40, 30, 25],[date(2024, 2, 2), 40, 25, 30],[date(…...
IEEE754 十进制数转32位浮点数格式
为了将十进制数37.25转换为IEEE 754短浮点数格式(32位),我们需要按照以下步骤进行: IEEE 754标准结构 IEEE 754标准的单精度浮点数(32位)格式如下: 1位符号位(S)8位指…...
JVM内存分析之JVM分区与介绍
JVM(Java Virtual Machine)作为Java平台的核心组件,为Java应用程序的运行提供了一个虚拟的计算机环境。为了更好地理解和优化Java应用程序的性能,对JVM的内存管理进行深入分析是至关重要的。本文将详细介绍JVM的内存分区及其功能。…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...