指针进阶大冒险:解锁C语言中的奇妙世界!
目录
引言
第一阶段:🔍 独特的字符指针
什么是字符指针?
字符指针的用途
演示:使用字符指针拷贝字符串
字符指针与字符串常量
小试牛刀
第二阶段:🎯 玩转指针数组
指针数组是什么?
指针数组的用途
演示:创建和使用指针数组
第三阶段:🎯 探索数组指针的神奇之旅
数组指针:是指针还是数组?
数组指针的定义
解释数组指针的应用
小试牛刀
int *p1[10];:指针数组
int (*p2)[10];:数组指针
&数组名 与 数组名:剖析引用与地址
&数组名:取地址操作
数组名:首元素的指针
比较一下
代码解释
数组指针的使用
print_arr1 函数解释
print_arr2 函数解释
练习
第四阶段:🔗 数组参数、指针参数的传递方式
一维数组传参
二维数组传参
一级指针传参
二级指针传参
第五阶段:🔗 探索函数指针的神奇世界
函数指针简介
使用函数指针
函数指针数组
指向函数指针数组的指针
第六阶段:🔗 回调函数:让程序更灵活
回调函数简介
回调函数的应用
结语:尖叫指针,飞跃编程界!🚀
引言
🌟📚 "指针是编程的魔法棒,它们能在内存中画出绚丽的图景。而在今天的探索中,我们将穿越指针的彩虹,解锁高级的指针魔法!就像在魔法学校里学习新的咒语,我们将探索字符指针、数组指针、函数指针等进阶内容,为你的编程技能注入更多的魔力。快来加入我们的奇妙旅程吧,一起解开指针的高级谜团!" 🌈✨
第一阶段:🔍 独特的字符指针
欢迎来到指针大冒险的第一站!在本阶段,我们将揭开字符指针的神秘面纱,探索它在C语言中的精彩应用。
什么是字符指针?
字符指针是指向字符数据的指针,它的灵活性和用途让人惊叹不已。在C语言中,字符串实际上是以字符数组的形式存在的,而字符指针则是指向字符串首字符的指针。
字符指针的用途
字符指针的应用极其广泛,尤其在字符串处理方面。它能够让我们以一种高效的方式操作字符串,实现诸如字符串拷贝、连接、比较等操作。此外,字符指针还为我们提供了一种遍历字符串的简洁方法。
演示:使用字符指针拷贝字符串
让我们通过一个示例来演示如何使用字符指针拷贝一个字符串。以下是一个自定义的字符串拷贝函数:
#include <stdio.h>void stringCopy(char *dest, const char *src) {while (*src != '\0') {*dest = *src;dest++;src++;}*dest = '\0'; // 添加字符串结尾的空字符
}int main() {char source[] = "Hello, World!";char destination[20];stringCopy(destination, source);printf("Copied string: %s\n", destination);return 0;
}
在这个例子中,我们使用字符指针 src
和 dest
分别指向源字符串和目标字符串。通过逐个字符地拷贝,我们可以将源字符串的内容复制到目标字符串中,然后在末尾添加一个空字符。
字符指针与字符串常量
字符指针也常用于处理字符串常量,这些常量是以字符数组的形式存储在内存中。通过字符指针,我们可以轻松地访问和操作这些常量:
#include <stdio.h>int main() {const char *message = "Hello, C Pointers!";printf("Message: %s\n", message);return 0;
}
小试牛刀
#include <stdio.h>int main() {char str1[] = "Hello, World!";char str2[] = "Hello, World!";const char *str3 = "Hello, World!";const char *str4 = "Hello, World!";if (str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if (str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return 0;
}
在这段代码中,我们比较了字符数组和指向字符串常量的字符指针之间的区别。以下是代码的详细解释:
在
main
函数中,我们定义了两个字符数组str1
和str2
,它们都包含相同的字符串"Hello, World!"
。我们还定义了两个指向字符串常量的字符指针
str3
和str4
,同样指向字符串"Hello, World!"
。接下来,我们使用
==
运算符分别比较str1
和str2
,以及str3
和str4
。注意,str1
和str2
是字符数组,而str3
和str4
是指向字符串常量的指针。当比较
str1
和str2
时,由于它们分别是不同的字符数组,它们的地址也是不同的,因此条件为假,将输出 "str1 and str2 are not same"。当比较
str3
和str4
时,由于它们指向相同的字符串常量,它们的地址也是相同的,因此条件为真,将输出 "str3 and str4 are same"。
第二阶段:🎯 玩转指针数组
欢迎来到指针大冒险的第二站!在本阶段,我们将深入探讨指针数组的奥秘,适合各位小白朋友学习,让我们一起探索它在C语言中的精彩应用。
指针数组是什么?
首先,让我们来理解一下什么是指针数组。在C语言中,指针数组是一种特殊的数组类型,它的每个元素都是指针。每个指针可以指向不同的数据,如整数、字符、字符串等。这意味着,指针数组实际上是存储了多个指针的数组。
指针数组的用途
指针数组在许多编程场景中都扮演着关键角色。它的灵活性使得它在多种情况下都非常有用:
字符串数组:一个常见的应用是创建字符串数组,其中每个元素指向不同的字符串。这使得我们能够轻松地管理和操作多个字符串。
函数参数:当我们需要将多个数据项作为参数传递给函数时,指针数组是一个不错的选择。它可以帮助我们将不同类型的数据集合在一起传递给函数。
多项选择题:在编程中,有时我们需要处理多个选项,指针数组可以用来存储这些选项的指针,便于处理和操作。
演示:创建和使用指针数组
让我们通过一个示例来演示如何创建和使用指针数组,并展示它在字符串数组中的应用:
#include <stdio.h>int main() {char *fruits[] = {"Apple","Banana","Orange","Grapes"};int numFruits = sizeof(fruits) / sizeof(fruits[0]);for (int i = 0; i < numFruits; i++) {printf("Fruit %d: %s\n", i + 1, fruits[i]);}return 0;
}
在这个例子中,我们创建了一个指针数组 fruits
,其中的每个元素都是指向字符串的指针。我们使用花括号初始化语法,将几个水果名字的字符串赋值给指针数组。然后,我们通过循环遍历指针数组,并打印出每个水果的名称。
第三阶段:🎯 探索数组指针的神奇之旅
欢迎来到指针大冒险的第三站!在本阶段,我们将深入探讨数组指针的奥秘,为C语言新手们揭示其精彩应用。
数组指针:是指针还是数组?
在C语言中,数组指针是一种非常有趣的概念。虽然它名字中包含了"数组",但它实际上是一种指针。数组指针允许我们以一种更加灵活的方式来处理数组,从而克服了使用普通数组下标的一些限制。
数组指针的定义
以往,我们熟悉了整型指针和浮点型指针,它们分别指向整数和浮点数类型的数据。类似地,数组指针是一种能够指向数组的指针。通过使用数组指针,我们能够以更加自由和灵活的方式操作数组中的元素。
解释数组指针的应用
数组指针在处理数组时发挥着重要作用。它不仅仅是一个单纯的指针,它更像是一个为数组开辟的一扇智能门。它允许我们以指针的方式移动、访问和操作数组中的元素,无需受限于普通数组下标的顺序
小试牛刀
在该小节,我们将深入探索两种看似相似但实际截然不同的指针类型:int *p1[10];
和 int (*p2)[10];
。虽然它们都涉及指针和数组,但它们的应用和含义却截然不同。
int *p1[10];
:指针数组
首先,让我们揭开
int *p1[10];
的面纱。这段代码定义了一个数组,这个数组中有10个元素,每个元素都是指向整数的指针。具体来说,p1
是一个指针数组,它可以存储多个整数指针。这使得我们能够方便地管理多个整数指针,每个指针可以指向不同的整数。
int (*p2)[10];
:数组指针
接下来,我们来解释
int (*p2)[10];
。这行代码定义了一个指针,这个指针指向一个包含10个整数的数组。简而言之,p2
是一个数组指针,它可以帮助我们处理整数数组。通过操作这个指针,我们可以以更加灵活的方式访问整数数组中的元素。
注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。
&数组名
与 数组名:剖析引用与地址
&数组名
:取地址操作
首先,我们来解释
&数组名
的作用。&数组名
表示取得整个数组的起始地址,它不是数组本身,而是指向数组的指针。这种操作可以让我们获取整个数组在内存中的位置。
数组名:首元素的指针
数组名不仅仅是一个名称,它还是一个指向数组首元素的指针。因此,数组名可以用来表示整个数组,也可以用来访问数组中的元素。
比较一下
&数组名
:表示整个数组的起始地址,是指向数组的指针。- 数组名:指向数组首元素的指针,可以用来表示整个数组或访问数组元素。
举个例子,假设有一个整型数组
int numbers[5];
,我们可以使用&numbers
来获得整个数组在内存中的位置,而使用numbers
则是数组首元素的指针,可以用于遍历和访问数组中的元素。
代码解释
#include <stdio.h>int main() {int arr[10] = {0};printf("%p\n", arr); // 打印数组首元素的地址printf("%p\n", &arr); // 打印整个数组的起始地址return 0;
}
printf("%p\n", arr);
打印的是数组首元素arr[0]
的地址。由于数组名本身就是指向数组首元素的指针,所以arr
和&arr[0]
是等价的。因此,它们打印的地址是相同的,都是数组的首地址。
printf("%p\n", &arr);
打印的是整个数组arr
的起始地址。在内存中,数组占据了一段连续的内存空间,&arr
就是整个数组的起始地址。
再来一个
#include <stdio.h>int main() {int arr[10] = {0};printf("arr = %p\n", arr); // 打印数组首元素的地址printf("&arr = %p\n", &arr); // 打印整个数组的起始地址printf("arr+1 = %p\n", arr+1); // 打印数组第二个元素的地址printf("&arr+1 = %p\n", &arr+1); // 打印下一个数组的起始地址return 0;
}
printf("arr = %p\n", arr);
和printf("&arr = %p\n", &arr);
打印的都是数组arr
的起始地址。因为数组名arr
本身就是指向数组首元素的指针,所以这两者的值是相同的。
printf("arr+1 = %p\n", arr+1);
打印的是数组的第二个元素的地址。由于整型数组中每个元素占用4个字节(假设为32位系统),所以arr+1
就是arr
的起始地址加上4个字节,即指向数组的第二个元素。
printf("&arr+1 = %p\n", &arr+1);
打印的是下一个数组的起始地址。在内存中,相邻的数组之间有一个间隔,这个间隔的大小是整个数组的大小。因此,&arr+1
实际上是指向下一个数组的起始地址。
数组指针的使用
看一段代码.
#include <stdio.h>// 打印二维数组,使用数组作为参数
void print_arr1(int arr[3][5], int row, int col) {int i, j;for(i = 0; i < row; i++) {for(j = 0; j < col; j++) {printf("%d ", arr[i][j]);}printf("\n");}
}// 打印二维数组,使用数组指针作为参数
void print_arr2(int (*arr)[5], int row, int col) {int i, j;for(i = 0; i < row; i++) {for(j = 0; j < col; j++) {printf("%d ", arr[i][j]);}printf("\n");}
}int main() {int arr[3][5] = {{1, 2, 3, 4, 5},{6, 7, 8, 9, 10},{11, 12, 13, 14, 15}};printf("Printing using print_arr1:\n");print_arr1(arr, 3, 5);printf("\nPrinting using print_arr2:\n");print_arr2(arr, 3, 5);return 0;
}
print_arr1
函数解释
void print_arr1(int arr[3][5], int row, int col)
这个函数的参数
arr
是一个二维数组,它是一个3x5
的整数数组。参数row
和col
分别表示行数和列数。在函数内部,我们使用嵌套循环遍历二维数组的每个元素,并使用arr[i][j]
访问它们。
print_arr2
函数解释
void print_arr2(int (*arr)[5], int row, int col)
这个函数的参数
arr
是一个指向包含5个整数的数组的指针。参数row
和col
仍然表示行数和列数。在函数内部,我们同样使用嵌套循环遍历二维数组的每个元素,但是这里使用arr[i][j]
访问它们。
值得注意的是,尽管在 print_arr2
中,我们传递的是 arr
,但实际上传递的是指向第一行的指针。这是因为在 C 语言中,数组名作为函数参数传递时,会退化为指向数组首元素的指针。因此,print_arr2
函数可以通过指针来遍历整个二维数组。
练习
int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];
int arr[5];
:这是一个包含5个整数的一维数组。
int *parr1[10];
:这是一个数组,数组中包含了10个整型指针。每个元素parr1[i]
可以指向一个整数。
int (*parr2)[10];
:这是一个指向包含10个整数的数组的指针。通过parr2
可以访问整个数组。
int (*parr3[10])[5];
:这是一个数组,数组中包含了10个指向包含5个整数的数组的指针。每个元素parr3[i]
可以指向一个长度为5的整数数组。
第四阶段:🔗 数组参数、指针参数的传递方式
欢迎来到第四阶段!在这里,我们将继续深入探讨C语言中有关函数参数传递的话题,重点介绍一维数组、二维数组、一级指针和二级指针作为函数参数的传递方式。通过了解这些传参方式的独特特点和灵活应用,我们将在C语言编程的旅程中迈出坚实一步。
一维数组传参
当你将一维数组作为函数参数传递时,实际上传递的是数组的首地址。这种方式使得函数内部可以操作数组元素,但无法获取数组的长度。下面,我们一起来看一个生动的例子吧!
#include <stdio.h>void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}
}int main() {int arr[5] = {1, 2, 3, 4, 5};printArray(arr, 5); // 传递数组和数组长度作为参数return 0;
}
二维数组传参
在传递二维数组作为函数参数时,需要明确指定第二维的大小。这种传递方式在处理矩阵和图等二维数据结构时非常实用。让我们通过一个更详细的示例来深入理解!
#include <stdio.h>// 函数接受二维数组和行列数作为参数
void print2DArray(int arr[][3], int rows, int cols) {for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {printf("%d ", arr[i][j]);}printf("\n");}
}int main() {int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};printf("Original 2D Array:\n");print2DArray(arr, 3, 3); // 传递二维数组和行列数作为参数return 0;
}
在这个示例中,我们定义了一个函数
print2DArray
,它接受一个二维数组和行列数作为参数,然后按行列的方式输出二维数组的内容。在main
函数中,我们创建了一个3x3的二维数组,并通过print2DArray
函数将其内容打印出来。
一级指针传参
一级指针作为函数参数传递时,实际上传递的是指针的地址。这种方式允许在函数内部修改指针指向的内容,但无法修改指针本身。让我们看看一个有趣的例子!
#include <stdio.h>void modifyPointer(int *ptr) {*ptr = 42; // 修改指针指向的内容
}int main() {int num = 10;int *ptr = #modifyPointer(ptr); // 传递指针作为参数printf("Value: %d\n", *ptr); // 输出修改后的值return 0;
}
二级指针传参
二级指针是指向指针的指针。传递二级指针作为函数参数时,传递的是指针的地址,允许在函数内部修改指针本身的值。来看一个有趣的示例吧:
#include <stdio.h>void modifyDoublePointer(int **pptr) {int newVal = 42;*pptr = &newVal; // 修改二级指针指向的值
}int main() {int num = 10;int *ptr = #int **pptr = &ptr;modifyDoublePointer(pptr); // 传递二级指针作为参数printf("Value: %d\n", **pptr); // 输出修改后的值return 0;
}
第五阶段:🔗 探索函数指针的神奇世界
欢迎来到第五阶段!在这里,我们将深入研究C语言中的一个强大而神秘的概念——函数指针。函数指针为我们提供了更高级的编程能力,允许我们像操作数据一样操作函数。让我们一起探索函数指针的神奇世界吧!
函数指针简介
函数指针是指向函数的指针变量。与指向数据的指针类似,函数指针存储函数的地址,使我们能够通过指针调用该函数。这种能力在回调函数、动态函数调用和多态性等场景中非常有用。
使用函数指针
以下是一个简单的例子,演示如何声明、赋值和调用函数指针:
#include <stdio.h>// 声明函数指针类型
typedef int (*Operation)(int, int);// 加法函数
int add(int a, int b) {return a + b;
}// 减法函数
int subtract(int a, int b) {return a - b;
}int main() {Operation operationPtr; // 声明函数指针变量operationPtr = add; // 赋值为add函数int result = operationPtr(5, 3); // 通过指针调用函数printf("Result: %d\n", result); // 输出结果return 0;
}
函数指针数组
函数指针可以组成数组,称为函数指针数组。这使我们可以通过索引来选择不同的函数。以下是一个使用函数指针数组的示例:
#include <stdio.h>int add(int a, int b) {return a + b;
}int subtract(int a, int b) {return a - b;
}int multiply(int a, int b) {return a * b;
}int main() {int (*operationPtr[3])(int, int); // 声明函数指针数组operationPtr[0] = add;operationPtr[1] = subtract;operationPtr[2] = multiply;int result = operationPtr[1](10, 5); // 调用subtract函数printf("Result: %d\n", result);return 0;
}
指向函数指针数组的指针
我们可以声明指向函数指针数组的指针,让我们一起看看它的用法:
#include <stdio.h>int add(int a, int b) {return a + b;
}int subtract(int a, int b) {return a - b;
}int multiply(int a, int b) {return a * b;
}int main() {int (*(*operationPtrPtr)[3])(int, int); // 声明指向函数指针数组的指针operationPtrPtr = &operationPtr; // 赋值为函数指针数组的地址int result = (*operationPtrPtr)[2](7, 3); // 通过指针调用multiply函数printf("Result: %d\n", result);return 0;
}
第六阶段:🔗 回调函数:让程序更灵活
欢迎来到第六阶段!在这里,我们将深入探讨C语言中的另一个重要概念——回调函数。回调函数是一种让程序更灵活的技术,通过它,我们可以将函数作为参数传递给其他函数,从而实现更动态的操作。让我们一起探索回调函数的奇妙之处!
回调函数简介
回调函数是指传递一个函数的指针作为参数给另一个函数,然后在后者中调用这个传递进来的函数。这种方式使得我们可以在运行时决定要执行哪些函数,实现更灵活的程序逻辑。
回调函数的应用
以下是一个简单的示例,展示如何使用回调函数来排序一个整数数组:
#include <stdio.h>
#include <stdlib.h>// 比较函数:升序排列
int compareAsc(const void *a, const void *b) {return (*(int *)a - *(int *)b);
}// 比较函数:降序排列
int compareDesc(const void *a, const void *b) {return (*(int *)b - *(int *)a);
}// 使用回调函数对数组进行排序
void sortArray(int arr[], int size, int (*compare)(const void *, const void *)) {qsort(arr, size, sizeof(int), compare);
}int main() {int arr[5] = {5, 2, 8, 1, 3};sortArray(arr, 5, compareAsc); // 使用升序比较函数排序printf("Ascending Order: ");for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);}sortArray(arr, 5, compareDesc); // 使用降序比较函数排序printf("\nDescending Order: ");for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);}return 0;
}
在这个示例中,我们使用了两个不同的比较函数,分别用于升序和降序排序。通过将比较函数作为参数传递给 sortArray
函数,我们实现了动态选择排序方式的功能。
结语:尖叫指针,飞跃编程界!🚀
来到本篇博客的终点,你是否感受到了指针的神奇魅力呢?从字符指针到数组指针,从函数指针到回调函数,我们一路探索,揭开了指针的奥秘面纱。
指针,如同瞬间连接你与计算机内部的魔法纽带,让操作数据、调用函数变得轻松自如。无论是在数组的海洋中航行,还是在函数的宇宙中穿梭,指针都是你最忠实的伙伴。
相信你已经在这趟指针之旅中汲取了丰富的知识。保持好奇心,继续探索,愿你的编程旅程一路飞升,创造出更多令人惊叹的代码艺术!不忘初心,一起向编程的星辰大海进发吧!🌟
相关文章:

指针进阶大冒险:解锁C语言中的奇妙世界!
目录 引言 第一阶段:🔍 独特的字符指针 什么是字符指针? 字符指针的用途 演示:使用字符指针拷贝字符串 字符指针与字符串常量 小试牛刀 第二阶段:🎯 玩转指针数组 指针数组是什么? 指针…...

2.0 Maven基础
1. Maven概述 Maven概念 Apache Maven是一个软件项目管理工具,将项目开发和管理过程抽象程一个项目对象模型(POM,Project Object Model)。 Maven作用 项目构建 提供标准的、跨平台的自动化项目构建方式。 依赖管理 方便快捷…...

在Linux虚拟机内配置nginx以及docker
目录 1、nginx源码包编译以及安装依赖 1、配置安装所需的编译环境 2、安装函数库(pcre、zlib、openssl) 2、安装nginx 1、获取源码包 2、解压编译 3、启动nginx服务 1、关闭防火墙 2、运行nginx 3、使用本地浏览器进行验证 3、安装docker 1、…...

数据结构-带头双向循环链表的实现
前言 带头双向循环链表是一种重要的数据结构,它的结构是很完美的,它弥补了单链表的许多不足,让我们一起来了解一下它是如何实现的吧! 1.节点的结构 它的节点中存储着数据和两个指针,一个指针_prev用来记录前一个节点…...

android Ndk Jni动态注册方式以及静态注册
目录 一.静态注册方式 二.动态注册方式 三.源代码 一.静态注册方式 1.项目名\app\src\main下新建一个jni目录 2.在jni目录下,再新建一个Android.mk文件 写入以下配置 LOCAL_PATH := $(call my-dir)//获取当前Android.mk所在目录 inclu...

MySQL中的索引
1.2.MySQL中的索引 InnoDB存储引擎支持以下几种常见的索引:B树索引、全文索引、哈希索引,其中比较关键的是B树索引 1.2.1.B树索引 InnoDB中的索引自然也是按照B树来组织的,前面我们说过B树的叶子节点用来放数据的,但是放什么数…...

idea中如何处理飘红提示
idea中如何处理飘红提示 在写sql时,总是会提示各种错误 查找资料,大部分都是说关提示,这里把错误提示选择为None即可 关掉以后,也确实不显示任何提示了,但总有一种掩耳盗铃的感觉 这个sms表明明存在,但是还…...
Elasticsearch使用中出现的错误
Elasticsearch使用中出现的错误 1、分页查询异常 在分页的过程中出现了一个问题是当查询的数据超过10000条的时候报了异常: from size must be less than or equal to: [10000]这个问题最快捷的解决方式是增大窗口大小: curl -XPUT http://127.0.0.…...

【IMX6ULL驱动开发学习】01.编写第一个hello驱动+自动创建设备节点(不涉及硬件操作)
目录 一、驱动程序编写流程 二、代码编写 2.1 驱动程序hello_drv.c 2.2 测试程序 2.3 编写驱动程序的Makefile 三、上机实验 3.1 NFS 挂载 3.2 测试示例 一、驱动程序编写流程 构造file_operations结构体 在里面填充open/read/write/ioctl成员 注册file_operations结…...

决策规划仿真平台搭建
决策规划仿真平台搭建 自动驾驶决策规划算法第二章第一节 决策规划仿真平台搭建 这部分的主要难点在于多个软件的连通与适配,环境的搭建总是折磨人的,主要是 4 个软件,各软件版本如下 Visual Studio2017PreScan8.5.0CarSim2019.0MATLAB2019b…...
计算图像哈希SHA-512
1、MATLAB实现 计算图像哈希值SHA-512,在文献[1]提到的算法如下: % Example Code: Create an MD5 crypto-hash of an arbitrary string, "str" % Main class of interest: System.Security.Cryptography.HashAlgorithm% Example String to hash with MD5 %…...

Android之消除APP图标的白色边框
有问题的效果: 解决方案: 第一步:app右键—>new—>Image Asset 第二步:上传Logo图标,选择每种分辨率,预览看效果,选择Resize,可以微调 第三步:点击 Nextÿ…...

java线程的优先级、守护线程的概念
1.线程的调度 抢占式调度 非抢占式调度 1.1 抢占式调度 优先级越高,抢到cpu的概率越高 1.2 守护线程 守护线程,非守护线程。当其他的非守护线程执行完毕以后,守护线程会陆续结束。 守护线程的应用场景...
asp.net core 6.0 efcore +sqlserver增删改查的demo
asp.net core 6.0 efcore sqlserver增删改查的demo 下面是一个使用ASP.NET Core 5.0和Entity Framework Core进行增删改查操作的示例。 首先,创建一个空的ASP.NET Core 6.0 Web应用程序项目。 然后,安装以下NuGet包: Microsoft.EntityFra…...

HC32L110B6芯片测试
到货之后,直观上感觉的确很小,小包装盒里面还装了说明书。 下载器单独在一个盒里面,但是这个T-U2T没用上,还是用的STLINK。 开发之前先去网上找了一些别人遇到的坑,的确不少。 涉及的方面也是挺全的,供电、…...
关于我乱删注册表导致电脑没有声音这件事
之前因为想彻底删除迅雷,照着网上进入注册表一顿乱删,也忘记删了啥,反正把一顿xmp的文件,和搜索出来迅雷的全删了。结果迅雷确实没了,被带走的还有电脑的声音。 很离谱,就试过了所有方法都没用,…...
Linux 命令 su 和 sudo 的区别
之前一直对 su 和 sudo 这两个命令犯迷糊,最近专门搜了这方面的资料,总算是把两者的关系以及用法搞清楚了,这篇文章来系统总结一下。 1. 准备工作 因为本篇博客中涉及到用户切换,所以我需要提前准备好几个测试用户,方…...
微信小程序:Mobx的使用指南
简要 微信小程序中有时需要进行全局状态管理,这个时候就需要用到Mobx.下面我们来看一下在小程序中是如何使用Mobx的 安装 pnpm i mobx-miniprogram4.13.2 mobx-miniprogram-bindings1.2.1 或 npm i mobx-miniprogram4.13.2 mobx-miniprogram-bindings1.2.1 或 yarn…...

【Spring Boot】Spring Boot项目的创建和文件配置
目录 一、为什么要学Spring Boot 1、Spring Boot的优点 二、创建Spring Boot项目 1、创建项目之前的准备工作 2、创建Spring Boot项目 3、项目目录的介绍 4、安装Spring Boot快速添加依赖的插件 5、在项目中写一个helloworld 三、Spring Boot的配置文件 1、配置文件的…...

Spring Cloud 智慧工地源码(PC端+移动端)项目平台、监管平台、大数据平台
智慧工地源码 智慧工地云平台源码 智慧建筑源码 “智慧工地”是利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术,彻底改变传统建筑施工现场参建各方现场管理的交互方式、工作方式和管理模式,实现对人、机、料、法、环的全方位实时监…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...