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

【C语言】第八期——指针、二维数组与字符串

目录

1 初始指针

2 获取变量的地址

3 定义指针变量、取地址、取值

3.1 定义指针变量

3.2 取地址、取值

4 对指针变量进行读写操作

5 指针变量作为函数参数

6 数组与指针

6.1 指针元素指向数组

6.2 指针加减运算(了解)

6.2.1 指针加减具体数字 

6.2.2 指针加减指针

6.3 数组名与数组元素首地址的关系

6.4 数组作为函数参数

7 二维数组以及字符串与指针

7.1 二维数组的定义方法

7.1.1 定义一个二维数组 

7.1.2 访问二维数组

7.2 定义字符串的几种方法

7.3 字符串数组

7.4 strcat 连接字符串

7.5 strcpy 字符串复制(拷贝)函数


1 初始指针

通过前面的教程我们知道变量是用来存储数据的,变量的本质是给存储数据的内存地址起了一个好记的别名

比如我们定义了一个变量 int a= 10 ,这个时候可以直接通过a这个变量来读取内存中保存的10 这个值,在计算机底层a这个变量其实对应了一个内存地址

指针也是一个变量,但它是一种特殊的变量,它存储的数据不是一个普通的值,而是另一个变量的内存地址

每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表 示了在内存中的一个地址

刚开始学C语言的指针操作,我们只需要记住两个符号 :&(取地址) 和 *(根据地址取值 /定义指针变量)


2 获取变量的地址

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。C语言中使用&字符放在变量 前面对变量进行取地址操作

#include <stdio.h>
int main(void)
{int a = 10;printf("a的地址是:%p\n", &a);return 0;
}

3 定义指针变量、取地址、取值

3.1 定义指针变量

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

type *var-name;

在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。用 来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是 指针

以下是有效的指针声明:

int* ip;    //一个整型的指针
double* dp; //一个 double 型的指针
float* fp;  //一个浮点型的指针
char* ch    //一个字符型的指针

所有指针的值都是一个地址,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是 一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同


3.2 取地址、取值

#include <stdio.h>
int main(void)
{// 定义一个int变量aint a = 10;printf("a的地址是:%p\n", &a);// 定义int类型的指针变量pint* p_a = &a;printf("指针p_a的值:%p\n", p_a);printf("指针p_a的地址:%p\n", &p_a);printf("a的值:%d\n", a);printf("根据指针p_a的值去内存取值得到的结果为:%d", *p_a);return 0;
}

总结:

  • 取地址操作符&和取值操作符是一对互补操作符, & 取出地址, 根据地址取出地址指向的值
  • 对变量进行取地址(&)操作,可以获得这个变量的地址
  • 指针变量的值是地址
  • 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值

4 对指针变量进行读写操作

#include <stdio.h>
int main(void)
{int a = 10;int b = 20;int* p1, * p2; // 定义指针变量 p1、 p2p1 = &a;// p1 指向变量 ap2 = p1;// p2 指向变量 aprintf("&a=%p p1=%p p2=%p\n", &a, p1, p2);*p1 = 20;printf("a的值%d,取指针得到的值%d", a, *p1);return 0;
}

运行结果:

&a=000000612A17FA74 p1=000000612A17FA74 p2=000000612A17FA74
a的值20,取指针得到的值20


5 指针变量作为函数参数

在C语言中,函数参数不仅可以是字符型、整型、浮点型等,还可以是指针类型,作用是将变量地址传递给函数形参

#include <stdio.h> 
void modify1(int *c) 
{*c = 20;
}
int main(void) {int a = 10;modify1(&a);printf("%d", a);return 0;
}

6 数组与指针

6.1 指针元素指向数组

数组本质上是一片连续的内存空间,每个数组元素都对应一块独立的内存空间,它们都有相应的地址。

因此,指针变量既然可以指向变量,也就可以指向数组元素

数组的构成本质上是:数组名[偏移量]

数组名就代表第一个元素的地址,偏移量就是在此基础上偏移

数组的元素本质上完全可以当做是单独的变量对待,只不过没有名称而已

int a[5]={1,2,3,4,5}; //定义长度为5的int数组
int *p_a=&a[0]; //定义指向int变量的指针变量p_a,把a数组第0个元素地址赋给指针变量p_a

注意:&a[0]等价于&(a[0]),由于[ ]运算符比取地址运算符&优先级高,因此&(a[0])中的小括号可以省略,简写为:&a[0]

在计算机中内存的最小单位是字节,每个字节都对应一个地址

如果一个变量占用多个字节,就会占用 多个内存地址

例如: char 类型变量占1字节就对应1个地址,short 类型变量占2字节对应2个地址,int 类型变量占4 字节对应4个地址.....·其他类型依次类推

同理,数组元素类型不同占用的内存地址也不同

下面通过例子来验证以上分析

#include<stdio.h>
int main(void)
{char c[5];short s[5];int i;for (i = 0; i < 5; i++){printf("&c[%d]=%p ", i, &c[i]);printf("&s[%d]=%p \n", i, &s[i]);}return 0;
}

运行结果:

&c[0]=000000000061FE17 &s[0]=000000000061FE0C

&c[1]=000000000061FE18 &s[1]=000000000061FE0E

&c[2]=000000000061FE19 &s[2]=000000000061FE10

&c[3]=000000000061FE1A &s[3]=000000000061FE12

&c[4]=000000000061FE1B &s[4]=000000000061FE14

说明:不同设备上面输出的地址可能不一样的,数组中每个元素地址都是连续的


6.2 指针加减运算(了解)

6.2.1 指针加减具体数字 

指针本质上就是内存地址,在32 位操作系统下,内存地址是 4 字节的整数。既然是整数就可以进行 加、减、乘、除等算术运算。不过需要注意的是,在 C 语言中一般只讨论指针加、减运算,乘、除等其 他算术运算都没有意义

在实际开发中,指针加、减运算多用于数组(或连续内存空间)。当指针变量p 指向数组元素时,p+1 表 示指向下一个数组元素,p-1 表示指向上一个数组元素

#include <stdio.h>
int main(void)
{int a[3] = { 1, 2, 3 };int* p = &a[0];// 指针 p 指向 a[0]printf("%p %d\n", p, *p); // 输出 a[0] 的地址 和 a[0] 的值p = p + 1;// p 加 1printf("%p %d\n", p, *p); // 输出 a[1] 的地址 和 a[1] 的值return 0;
}

运行结果:

000000811557F968 1
000000811557F96C 2

注意:实现指针加减的时候需要注意越界问题


6.2.2 指针加减指针

在C语言中,两个指针相加是没有意义的,而两个指针相减却有特殊的意义,不过只有当两个指针都指向同一数组中的元素时才有意义

一个数组中的元素时,对它们进行减法运算,得到的结果是这两个指针所指向元素之间相隔的元素个数 (不是之间有的个数,之间有的元素数要在此基础上减一),而不是它们地址差值的字节数。其计算方式是用两个指针的地址差值除以指针所指向数据类型的大小

用公式表示为:(指针2的地址 - 指针1的地址) / sizeof(指针所指向的数据类型)


6.3 数组名与数组元素首地址的关系

C语言中,数组名与数组首元素地址等价。也就是说,在程序中,输出数组名与输出数组首元素地址是相同的

#include <stdio.h>
int main(void)
{int num[5];printf("%p\n", num);     // 输出数组名printf("%p\n", &num[0]); // 输出数组首元素地址return 0;
}

输出结果:

000000000061FE00

000000000061FE00

我们就可以通过把数组名复制给指针变量,来把数组首地址给指针变量

#include <stdio.h>int main(void){int num[5] = {1, 2, 3, 4, 5};int *p_num = num; // 把num的首地址赋值给指针变量printf("p_num指针的值=%p \n p_num对应数组元素的值%d", p_num, *p_num);return 0;}

我们也可以通过p_num来访问数组里面的每个元素

 #include <stdio.h>int main(void){int num[5] = {1, 2, 3, 4, 5};int *p_num = num; // 把num的首地址赋值给指针变量printf("p_num指针的值=%p ,num的地址是=%p  p_num对应数组元素的值%d\n", p_num, num, 
*p_num);printf("p_num访问第一个元素=%d\n", p_num[0]);printf("p_num访问第二个元素=%d\n", p_num[1]);return 0;}

运行结果:

p_num指针的值=000000000061FE00 ,num的地址是=000000000061FE00  p_num对应数组元素的值1

p_num访问第一个元素=1 p_num访问第二个元素=2


6.4 数组作为函数参数

函数参数不仅可以是变量,也可以是数组,数组作函数参数的作用是将数组首元素地址传给函数作形参。 在 C 语言中,数组作函数参数时,是没有副本机制的,只能传递地址。也可以认为,数组作函数参数时,会退化为指针

#include <stdio.h>
void getSize(int nums[10]) // 定义 getSize 函数
{int size = sizeof(nums); // 计算数组 nums 的总字节数printf("指针 size=%d\n", size);
}
int main(void)
{int nums[10] = { 1, 2, 3, 4, 5 };int size = sizeof(nums); // 计算数组 nums 的总字节数printf("外部 size=%d\n", size);getSize(nums); // 调用 getSize 函数return 0;
}

 运行结果:

外部 size=40

指针 size=8

所以直接把函数的形参的类型设置为指针,来接收数组的第一个地址: 

#include <stdio.h>
void getSize(int* nums) // 定义 getSize 函数
{int size = sizeof(nums); // 计算数组 nums 的总字节数printf("指针 size=%d\n", size);
}
int main(void)
{int nums[10] = { 1, 2, 3, 4, 5 };int size = sizeof(nums); // 计算数组 nums 的总字节数printf("外部 size=%d\n", size);getSize(nums); // 调用 getSize 函数return 0;
}

运行结果:

外部 size=40

指针 size=8

分析:

32位系统中指针变量占4个字节,64位系统中指针变量占8个字节,所以getSize中num的字节数是8。在 C 语言中,数组作函数参数时,是没有副本机制的,只能传递地址,所以 的形参 int *nums应该是指针变量, void getSize方法 getSize(nums) 传入的nums并不是数组的副本,而是数组首元素的地址 

注意:因为没有副本机制,所以如果在函数内部修改数组内容,数组的内容会直接被修改,而不是修改副本

#include <stdio.h>
void getSize(int* nums) // 定义 getSize 函数
{nums[0] = 3;
}
int main(void)
{int nums[10] = { 1, 2, 3, 4, 5 };printf("%d\n", nums[0]);    //加\n是为了换行getSize(nums); // 调用 getSize 函数printf("%d", nums[0]);return 0;
}

练习:封装比较数组最大值函数

#include <stdio.h>
int getMax(int* nums, int length) // 定义函数 getMax
{int i;int max = nums[0]; // 默认 nums[0] 为最大值for (i = 1; i < length; i++) // 下标从 1 开始遍历{if (max < nums[i]) // 比较大小{max = nums[i]; // 覆盖最大值}}return max; // 返回最大值
}int main(void)
{int nums[10] = { 11, 22, 3, 24, 15, 8, 99, 21, 35, 0 };int length = sizeof(nums) / sizeof(nums[0]); // 计算数组长度int max = getMax(nums, length); // 返回最大值printf(" 最大值为 :%d\n", max);return 0;
}

7 二维数组以及字符串与指针

7.1 二维数组的定义方法

C语言中二维数组和一维数组类似,简单理解就是:二维数组由多个一维数组构成

7.1.1 定义一个二维数组 

type arrayName[x][y];

例:

int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};

内部嵌套的括号是可选的,下面的初始化与上面是等同的:

int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

7.1.2 访问二维数组

#include <stdio.h>
#include <string.h>
void main(void)
{int a[3][4] = { {1, 3, 5, 7}, {9, 11, 13, 15}, {17, 19, 21, 23} };printf("a[0][2]=%d", a[0][2]);
}

运行代码:

a[0][2]=5


7.2 定义字符串的几种方法

我们已经学习的定义方法:

#include <stdio.h>
int main(void)
{char chs1[] = { 'i', 't', 'y', 'i', 'n', 'g', '\0' };char chs2[] = "itying";printf("%s\n", chs1);// 以 %s 格式输出 strprintf("%c\n", chs1[2]); // 以 %c 格式输出一个字符printf("%s\n", chs2);  // 以 %s 格式输出 strprintf("%c", chs2[2]); // 以 %c 格式输出一个字符return 0;
}

我们也可以使用字符指针引用字符串:

#include <stdio.h>
int main(void)
{char chs1[] = "itying";char* str1 = chs1;printf("%s\n", str1);  // 以 %s 格式输出 strprintf("%c\n", str1[2]);   // 以 %c 格式输出一个字符
//---------------------------------------------------------------------------char* str2 = "this is str";printf("%s\n", str2);  // 以 %s 格式输出 strprintf("%c\n", str2[2]); // 以 %c 格式输出一个字符return 0;
}

通过上面示例我们可以通过三种方法定义字符串了

char chs1[] = {'i', 't', 'y', 'i', 'n', 'g', '\0'};
char chs2[] = "itying";
char *chs3 = "itying";

7.3 字符串数组

定义了一个指针数组,即数组中的每个元素都是一个 char 类型的指针:

char *arr[] 

例:

char *s[]={ "马总", "张总", "王麻子" };

当使用 { "马总", "张总", "王麻子" } 对这个数组进行初始化时,会把每个字符串常量的首字符地址分别赋给数组 arr 的各个元素:

  • arr[0] 被赋值为字符串 "马总" 的首字符地址,通过这个指针,就可以访问该字符串的所有字符
  • arr[1] 被赋值为字符串 "张总" 的首字符地址
  • arr[2] 被赋值为字符串 "王麻子" 的首字符地址

    在实际处理中文时,通常会使用多字节字符编码,比如常见的 UTF - 8 编码或 GBK 编码

    UTF - 8 是一种变长编码,一个中文字符通常用 3 个字节来表示。对于字符串 "张总",“张” 字在 UTF - 8 编码下会占用 3 个字节的存储空间,arr[1] 指向的就是这 3 个字节中第一个字节的存储地址


    7.4 strcat 连接字符串

    前面我们已经学习了 strlen 计算字符串数组有效长度、sprintf 字符串格式化函数、字符串拼接、整型转换成字符串等字符串知识,详细见【C语言】第七期——字符数组、字符串、类型转换

    现在我们继续学习相关知识

    原型:

    char *strcat(char *dest, const char *src);    //使用前需先引入头文件<string.h>

    参数:

    • dest:目标字符串的指针,拼接后的结果将存储在这个字符串中。dest 必须有足够的空间来容纳 src 字符串的内容以及拼接后的结果
    • src:源字符串的指针,它将被追加到 dest 字符串的末尾。src 字符串本身不会被修改

    返回值:

    函数返回一个指向目标字符串 dest 的指针

    工作原理:

    strcat 函数会从 dest 字符串的第一个空字符 '\0' 开始,将 src 字符串的内容复制到 dest 的末尾,直到遇到 src 字符串的空字符 '\0' 为止,最后,dest 字符串会以空字符 '\0' 结尾

    #include <stdio.h>
    #include <string.h>int main() {// 定义目标字符串和源字符串char dest[50] = "Hello, ";const char src[] = "World!";// 使用 strcat 函数将 src 追加到 dest 的末尾strcat(dest, src);// 输出结果printf("拼接后的字符串: %s\n", dest);return 0;
    }

    注意事项:

    • 内存空间:dest 数组必须有足够的空间来容纳 src 字符串的内容,否则会导致缓冲区溢出,这可能会引发程序崩溃或安全漏洞
    • 空字符:dest 字符串必须以空字符 '\0' 结尾,否则 strcat 函数无法确定从哪里开始追加
    • 字符串重叠:dest 和 src 所指向的字符串不能重叠,否则会导致未定义行为

    7.5 strcpy 字符串复制(拷贝)函数

    原型:

    char *strcpy(char *dest, const char *src);

    参数:

    • dest:指向目标字符数组的指针,用于存储复制后的字符串。目标数组必须有足够的空间来容纳源字符串及其终止的空字符 '\0'
    • src:指向源字符串的指针,即要被复制的字符串。该参数被声明为 const,表示在函数内部不会修改源字符串

    返回值:

    strcpy 函数返回指向目标字符数组 dest 的指针

    工作原理:

    strcpy 函数会将 src 指向的字符串(包括终止的空字符 '\0')复制到 dest 指向的字符数组中

    复制过程会一直进行,直到遇到源字符串的终止空字符 '\0',并将该空字符也复制到目标数组中

    #include <stdio.h>
    #include <string.h>int main() {// 定义源字符串char src[] = "Hello, World!";// 定义目标字符数组,确保有足够的空间char dest[20];// 使用 strcpy 函数复制字符串strcpy(dest, src);// 输出复制后的字符串printf("Copied string: %s\n", dest);return 0;
    }

    注意事项:

    • 缓冲区溢出风险:使用 strcpy 时需要确保目标数组有足够的空间来容纳源字符串及其终止空字符,否则可能会导致缓冲区溢出,引发未定义行为,为了避免这种风险,可以使用更安全的 strncpy 函数
    • 目标数组的初始化:在使用 strcpy 之前,不需要对目标数组进行初始化,因为 strcpy 会覆盖目标数组中的原有内容

    相关文章:

    【C语言】第八期——指针、二维数组与字符串

    目录 1 初始指针 2 获取变量的地址 3 定义指针变量、取地址、取值 3.1 定义指针变量 3.2 取地址、取值 4 对指针变量进行读写操作 5 指针变量作为函数参数 6 数组与指针 6.1 指针元素指向数组 6.2 指针加减运算&#xff08;了解&#xff09; 6.2.1 指针加减具体数字…...

    docker 运行claude 的computer use

    需要注意的是&#xff1a;这里claude操纵的是docker的虚拟服务器&#xff0c;不能访问本地url&#xff0c;需要进行端口转发 export ANTHROPIC_API_KEY%your_api_key% docker run \-e ANTHROPIC_API_KEY$ANTHROPIC_API_KEY \-v $HOME/.anthropic:/home/computeruse/.anthropi…...

    JAVA面试_进阶部分_23种设计模式总结

    1. 单例模式&#xff1a;确保某一个类只有一个实例&#xff0c;而且自行实例化并向整个系统提供这 个实例。 &#xff08;1&#xff09;懒汉式 public class Singleton { /* 持有私有静态实例&#xff0c;防止被引用&#xff0c;此处赋值为null&#xff0c;目的是实现延迟加载…...

    边缘计算收益低的三大指标

    边缘计算收益低的三大指标主要包括以下方面&#xff1a; 1. 资源贡献不足&#xff1a; 边缘计算的收益通常基于所提供的带宽、存储和计算资源来计算。如果设备的网络带宽有限、在线时间短或提供的存储容量较小&#xff0c;可能无法满足平台设定的最低贡献标准&#xff0c;从而导…...

    Linux网络之传输层协议(UDP,TCP协议)

    目录 重新认识端口号 端口号划分 netstat pidof UDP协议 UDP的特点 面向数据报 UDP的缓冲区 全双工和半双工 TCP协议 TCP的特点 TCP报头分析 源端口&#xff0c;目标端口&#xff0c;数据偏移(报文首部长度) 序号 确认号 窗口 6个标志位 ACK SYN …...

    傅里叶分析

    傅里叶分析之掐死教程&#xff08;完整版&#xff09;更新于2014.06.06 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析不仅仅是一个数学工具&#xff0c;更是一种可以彻底颠覆一个人以前世界观的思维模式。但不幸的是&#xff0c;傅里叶分析的公式看起来太复…...

    【前端基础】Day 3 CSS-2

    目录 1. Emmet语法 1.1 快速生成HTML结构语法 1.2 快速生成CSS样式语法 2. CSS的复合选择器 2.1 后代选择器 2.2 子选择器 2.3 并集选择器 2.4 伪类选择器 2.4.1 链接伪类选择器 2.4.2 focus伪类选择器 2.5 复合选择器总结 3. CSS的元素显示模式 3.1 什么是元素显示…...

    NAT 技术:网络中的 “地址魔术师”

    目录 一、性能瓶颈&#xff1a;NAT 的 “阿喀琉斯之踵” &#xff08;一&#xff09;数据包处理延迟 &#xff08;二&#xff09;高并发下的性能损耗 二、应用兼容性&#xff1a;NAT 带来的 “适配难题” &#xff08;一&#xff09;端到端通信的困境 &#xff08;二&…...

    Ollama下载安装+本地部署DeepSeek+UI可视化+搭建个人知识库——详解!(Windows版本)

    目录 1️⃣下载和安装Ollama 1. &#x1f947;官网下载安装包 2. &#x1f948;安装Ollama 3.&#x1f949;配置Ollama环境变量 4、&#x1f389;验证Ollama 2️⃣本地部署DeepSeek 1. 选择模型并下载 2. 验证和使用DeepSeek 3️⃣使用可视化工具 1. Chrome插件-Page …...

    【JavaSE-1】初识Java

    1、Java 是什么? Java 是一种优秀的程序设计语言,人类和计算机之间的交流可以借助 Java 这种语言来进行交流,就像人与人之间可以用中文、英语,日语等进行交流一样。 Java 和 JavaScript 两者有关系吗? 一点都没有关系!!! 前端内容:HTML CSS JS,称为网页三剑客 2、JDK 下…...

    《基于Django和ElasticSearch的学术论文搜索推荐系统的设计与实现》开题报告

    目录 一、选题的背景和意义 &#xff08;一&#xff09;选题背景 &#xff08;二&#xff09;选题意义 2.1.提升科研效率 2.2 促进学术创新 2.3优化资源配置 二、选题的国内外现状与总结 &#xff08;一&#xff09;国内现状 &#xff08;二&#xff09;国外现状 &am…...

    Dify在Ubuntu20.04系统的部署

    文章目录 一、dify 介绍1.核心功能优势2.应用场景 二、dify 安装(docker方式)1.代码库下载2.配置文件修改3.启动docker 容器 三、遇到问题与解决1.使用sudo docker compose up -d报错2.使用service docker start报错 一、dify 介绍 Dify 是一款开源的大语言模型&#xff08;LL…...

    第7天:结构体与联合体 - 复杂数据类型

    第7天&#xff1a;结构体与联合体 - 复杂数据类型 一、&#x1f4da; 今日学习目标 &#x1f3af; 掌握结构体&#xff08;struct&#xff09;的定义与使用&#x1f527; 理解联合体&#xff08;union&#xff09;的特性与适用场景&#x1f4a1; 完成图书馆管理系统实战&…...

    vue富文本 vue-quill-editor + 上传图片到阿里云服务器 + 修改富文本内容

    前言 使用富文本编辑器&#xff0c;需要将图片上传到服务器&#xff0c;完成之后&#xff0c;还需要在修改页面完成修改富文本内容&#xff0c;使用的富文本插件是vue-quill-editor, 一 、安装 vue-quill-editor npm i vue-quill-editor npm install quill --save npm inst…...

    Java常见设计模式(中):结构型模式

    &#x1f308; 引言&#xff1a;设计模式就像乐高积木 适配器&#xff1a;让不同形状的积木完美拼接装饰器&#xff1a;给积木添加炫酷灯光效果代理&#xff1a;遥控积木完成复杂动作组合&#xff1a;将小积木搭建成宏伟城堡 结构型模式 主要用于描述对象之间的关系&#xff…...

    DeepSeek R1 + 飞书机器人实现AI智能助手

    效果 TFChat项目地址 https://github.com/fish2018/TFChat 腾讯大模型知识引擎用的是DeepSeek R1&#xff0c;项目为sanic和redis实现&#xff0c;利用httpx异步处理流式响应&#xff0c;同时使用buffer来避免频繁调用飞书接口更新卡片的网络耗时。为了进一步减少网络IO消耗&…...

    【论文详解】Transformer 论文《Attention Is All You Need》能够并行计算的原因

    文章目录 前言一、传统 RNN/CNN 存在的串行计算问题二、Transformer 如何实现并行计算&#xff1f;三、Transformer 的 Encoder 和 Decoder 如何并行四、结论 前言 亲爱的家人们&#xff0c;创作很不容易&#xff0c;若对您有帮助的话&#xff0c;请点赞收藏加关注哦&#xff…...

    51c嵌入式~电路~合集12

    我自己的原文哦~ https://blog.51cto.com/whaosoft/12318429 一、单端、推挽、桥式拓扑结构变压器对比 单端正激式 单端&#xff1a;通过一只开关器件单向驱动脉冲变压器。 正激&#xff1a;脉冲变压器的原/付边相位关系&#xff0c;确保在开关管导通&#xff0c;驱动脉冲…...

    php 获取head参数

    php 获取head参数 在PHP中&#xff0c;获取HTTP头部&#xff08;head&#xff09;参数可以通过不同的方式实现&#xff0c;下面为你详细介绍几种常见的方法。 1. 使用$_SERVER超全局变量 $_SERVER 是PHP中的一个超全局变量&#xff0c;它包含了诸如头信息、路径、脚本位置等…...

    蓝桥杯嵌入式备赛

    前言 嘿&#xff0c;小伙伴们&#xff01;备战蓝桥杯嵌入式比赛的号角已经吹响啦&#xff01;如果你还在为如何入手STM32G431RB这块比赛板子而发愁&#xff0c;别担心&#xff0c;今天我就来给你全方位介绍这块板子&#xff0c;带你快速上手备赛&#xff0c;一起冲向蓝桥杯的赛…...

    微信小程序之bind和catch

    这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

    DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

    目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

    Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

    Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

    1688商品列表API与其他数据源的对接思路

    将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

    屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

    5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

    第25节 Node.js 断言测试

    Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

    【AI学习】三、AI算法中的向量

    在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

    html-<abbr> 缩写或首字母缩略词

    定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

    React---day11

    14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

    【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

    目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...