当前位置: 首页 > news >正文

[大师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语言的学习和应用中&#xff0c;指针无疑是最重要、最难以掌握的概念之一。它为C语言提供了强大的功能和灵活性&#xff0c;同时也带来了不少的复杂性。本文将深入探讨C语言指针背后的技术&#xff0c;帮助你更好地理解和应用指针。 第一部分&#xff1a;指针的基本概…...

Docker命令总结

文章目录 Docker命令总结Docker环境Docker容器生命周期Docker容器运维Docker容器rootfsDocker镜像仓库Docker本地镜像管理Docker容器资源Docker系统日志 Docker命令总结 docker命令非常多&#xff0c;这里主要分为8类总结 Docker环境 可以查看Docker版本和自身的详细信息 d…...

把chatgpt当实习生,进行matlab gui程序编程

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

LabVIEW 与组态软件在自动化系统中的应用比较与选择

LabVIEW 确实在非标单机设备、测试和测量系统中有着广泛的应用&#xff0c;特别是在科研、教育、实验室和小型自动化设备中表现突出。然而&#xff0c;LabVIEW 也具备一定的扩展能力&#xff0c;可以用于更复杂和大型的自动化系统。以下是对 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前&#xff1a;阿拉斯加巴罗活动层厚度和土壤含水量&#xff0c;2013年 简介 文件修订日期&#xff1a;2018-01-10 数据集版本&#xff1a;1 摘要 该数据集提供了 2013 年 8 月在…...

超详解——python数字和运算——小白篇

目录 1.位运算 2. 常用内置函数/模块 math模块&#xff1a; random模块&#xff1a; decimal模块&#xff1a; 3.内置函数&#xff1a; 总结&#xff1a; 1.位运算 位运算是对整数在内存中的二进制表示进行操作。Python支持以下常见的位运算符&#xff1a; 按位与&…...

LabVIEW图像采集处理项目中相机选择与应用

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

Java——IO流(一)-(2/9):File类的常用方法(判断文件类型、获取文件信息、创建删除文件、遍历文件夹)

目录 常用方法1&#xff1a;判断文件类型、获取文件信息 方法 实例演示 常用方法2&#xff1a;创建文件、删除文件 方法 实例演示 常用方法3&#xff1a;遍历文件夹 方法 实例演示 常用方法1&#xff1a;判断文件类型、获取文件信息 方法 File提供的判断文件类型、获…...

电子设计入门教程硬件篇之集成电路IC(二)

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

Unity3D测量面积和角度实现方法(二)

系列文章目录 unity工具 文章目录 系列文章目录&#x1f449;前言&#x1f449;一、unity测量面积&#x1f449;1-1 视频效果&#x1f449;1-2 先创建预制体&#x1f449;1-3 在创建LineRenderer预制体&#x1f449;1-4 代码如下 &#x1f449;二、测量平面和测量空间切换&…...

vite 配置 typescript 环境

要在 Vite 项目中配置 TypeScript 环境&#xff0c;你需要遵循几个步骤来确保 TypeScript 被正确设置并可以与 Vite 一起工作。以下是一个基本的指南&#xff1a; 初始化项目 如果你还没有初始化项目&#xff0c;可以使用 npm 或 yarn 初始化一个新的项目&#xff1a; npm i…...

ThreadCache线程缓存

一.ThreadCache整体结构 1.基本结构 定长内存池利用一个自由链表管理释放回来的固定大小的内存obj。 ThreadCache需要支持申请和释放不同大小的内存块&#xff0c;因此需要多个自由链表来管理释放回来的内存块.即ThreadCache实际上一个哈希桶结构&#xff0c;每个桶中存放的都…...

UE5_加载本地图片(jpg, png) 转 UTexture

UE5_加载图片到UTexture __Desc使用方式源码 __Desc __Time__: 2024-06-05 16:30 __Author__: Yblackd __Desc__: UE5.2 加载本地图片 转 UTexture2D, 给材质 和 UMG 使用使用方式 新建继承BlueprintFunctionLibrary c 类复制下面源码&#xff0c;修改类名实测加载 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 隧道技术&#xff1a;解决不出网协议上线的问…...

彩虹易支付最新版源码

源码简介 彩虹易支付最新版源码&#xff0c;更新时间为5.1号 2024/05/01&#xff1a; 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短浮点数格式&#xff08;32位&#xff09;&#xff0c;我们需要按照以下步骤进行&#xff1a; IEEE 754标准结构 IEEE 754标准的单精度浮点数&#xff08;32位&#xff09;格式如下&#xff1a; 1位符号位&#xff08;S&#xff09;8位指…...

JVM内存分析之JVM分区与介绍

JVM&#xff08;Java Virtual Machine&#xff09;作为Java平台的核心组件&#xff0c;为Java应用程序的运行提供了一个虚拟的计算机环境。为了更好地理解和优化Java应用程序的性能&#xff0c;对JVM的内存管理进行深入分析是至关重要的。本文将详细介绍JVM的内存分区及其功能。…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

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

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...