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

Cweek4+5

C语言学习

十.指针详解

6.有关函数指针的代码

代码1:(*(void (*)())0)();
void(*)()是函数指针类型,0是一个函数的地址
(void(*)())是强制转换
总的是调用0地址处的函数,传入参数为空


代码2:void (*signal(int, void(*)(int)))(int);
(int, void(*)(int))是函数的传参列表
signal是函数名
剩下的是函数的返回值类型
这段代码可以简化为:

typedef void(*pfun_t)(int); //命名一个函数返回类型
pfun_t signal(int,pfun_t);

![请添加图片描述](https://img-blog.csdnimg.cn/direct/3c6f08b356c74b1589775d6b351c2214.png)

以上四种输出都等价

7.函数指针数组

定义一个函数指针数组:int (*parr[4])(int, int) = {Add, Sub, Mul, Div};
函数指针数组的作用:转移表
int(*(*ppfArr) [4])(int, int) = \pfArr;,ppfArr是一个数组指针,指针指向的数组有4个元素,每个元素的类型是一个函数指针int(*)(int, int)

8.回调函数

定义:回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们说这是回调函数
例子:stdlib中的qsort函数,qsort是一个库函数,内部用函数指针调用了一个函数
语法:qsort(数组起始地址, 数组长度, sizeof元素, 函数指针(自定义的比较方法))
比较方法的例子:

int compare(const void* e1, const void* e2){return *(int*)e1 - *(int*)e2;
}

当返回的值小于0时,表示第一个元素应该排在第二个元素之前,所以上述代码是升序
其中:void*类型的指针可以接收任意类型的地址,但是void*类型的指针不能进行解引用操作和加减整数的操作
因为不能进行解引用操作,所以想要拿到e1中的数据就要先强转换再解引用
注意:compare函数传入的是指针,如果是结构体,调用元素要用->而不是.

指针题目

①int a[] = { 1, 2, 3, 4 };
sizeof(a+0):a是首元素地址,得到的是首元素的大小
sizeof(&a):&a取出的是数组的地址,但是数组的地址也是地址,也就是4/8个字节
sizeof(*&a):&a取得是数组的地址,*解的是数组的地址,所以得到的是16


②char a[] = { ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’};
strlen(arr):字符串数组以\0为结尾,a中没有,所以结果是随机值
strlen(arr+0):也是随机值,理由同上
strlen(*arr):会报错,字符存储时存储的是ASCII码,传给strlen的是a的ASCII码,所以会报错


③char a[] = “abcdef”;
sizeof(arr):sizeof计算的是数组的大小,所以是7
sizeof(arr+0):4/8,计算的是地址的大小


④char *p = “abcdef”;(p存储的是a的地址)
sizeof(*p):1,*p就是字符串的第一个字符
sizeof(p[0]):p[0] == *(p+0),所以是1


⑤int a[3][4] = { 0 };
sizeof(a + 1):首元素是第一行,a+1是第二行的地址,所以是4
sizeof(a[3]):不会报错,因为sizeof不会真的访问第四行,只会得到a[3]的类型,所以是16


⑥int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
*(ptr - 1):a是数组的地址,a+1得到一个地址后再减一就是5的地址



请添加图片描述

p + 0x1:因为Test类型的变量大小是20字节,转为16进制后是14,所以是0x00100014
(unsigned long)p + 0x1:强转为整型后p+0x1相当于p+1,整型大小为4个字节,结果为0x00100004


请添加图片描述

其中:(0, 1)等都是逗号表达式,取最后一个数字
所以p[0] == 1


请添加图片描述

首先会报一个警告,因为p的长度和a的长度不一样
p[4][2]等价于*(*(p+4)+2),所以p[4][2]就是a[3][3]
地址相减是-4,但是"%p"是把-4的补码的直接值打印出来,所以是0xFFFFFFFC


请添加图片描述

a是字符指针的数组,存放着三个字符串的首元素的地址
pa是a数组的地址,也就是首元素的地址
pa++使其指向第二个元素,所以输出的是at


请添加图片描述

unsigned char的范围是0-255,a+b超过范围,c会变成44


请添加图片描述

str1和str2的地址不同,所以不等于
str3和str4都指向一个常量字符串,所以地址相等

十一.字符函数和字符串函数

大多字符串函数都要引入头文件:<string.h>

1.strcat

语法:char *strcat(str1, str2);
作用;将str2追加到str1后面,返回一个指向结果字符串的指针
缺点:不能将自己添加到自己后面
注意事项:

  1. str2中必须包含\0
  2. str1必须足够大
  3. str1必须可修改

2.strncat

语法:char *strncat(str1, str2, size);
size是要追加的最大字符串
作用:将str2的size个字符追加到str1后面,返回一个指向结果字符串的指针

3.strstr

注意:该函数要引入的头文件是<stdio.h>而不是<string.h>
语法:char *strstr(str1, str2);
作用:在str1中查找str2的第一次出现位置。该函数返回指向找到的子字符串的指针,如果未找到,则返回NULL

4.strlen

语法:size_t strlen(const char* str);
作用:返回一个字符串从头到\0的字符的个数,\0不算进长度
注意:size_t就是一个被重命名的unsigned int,无符号数字永远大于0,所以size_t跟size_t相减的结果也只会是正数

5.strcpy

语法:char *strcpy(str1, str2);
作用:将str2中的字符按顺序一个一个替换str1中的字符,注意str2中的\0也会替换一个字符,返回结果字符串的指针
注意事项:

  1. str2中必须有\0
  2. str1必须足够大
  3. str1必须可修改

6.strncpy

语法:char *strcpy(str1, str2, size);
size是要拷贝的字符串的最大长度
将str2中的字符按顺序一个一个替换str1中的字符,替换size次注意str2中的\0也会替换一个字符,返回结果字符串的指针

7.strcmp

语法:int strcmp(str1, str2);
作用:比较两个字符串的ASCII码,若str1<\str2,则返回一个小于零的数字,若str1==str2,则返回一个等于零的数字,若str1>str2,则返回一个大于零的数字

8.strtok

语法:char *strtok(str, const char *sep);
sep是个字符串,定义了用分隔符的字符集合
作用:根据分隔符切割一次str字符串,返回一个子字符串的指针,如果str是NULL,则从上一次调用后的位置继续分割字符串
注意:strtok会直接修改传入的字符串,所以str一般是字符串的拷贝
使用例:

#include <stdio.h>
#include <string.h>int main() {char str[] = "Hello world, how are you?";char *p = " ";for (char *ret = strtok(arr, p); ret != NUll; ret = strtok(NULL, p)) {printf("%s\n", token);}return 0;
}

输出结果为

Hello
world,
how
are
you?

9.strerror

语法:char *strerror(错误码);
作用:根据错误码,打印错误信息,错误码一般是变量errno
errno是头文件<errno.h>中的一个全局的错误码的变量,当C语言的库函数在执行时,发生了错误,就会把对应的错误码赋值到errno中

10.字符判断函数

请添加图片描述

11.字符转换函数

函数:tolower()和toupper
作用:转换大小写,支持ASCII码转换

十二.内存函数

1.memcpy

语法:void *memcpy(void *destination, const void *source, int size);
作用:将一个任意类型的数组source拷贝到destination中,最多size个元素
注意事项:

  1. destination和source不能有内存重叠
  2. destination和source类型要相同
  3. destination的长度要大于source的长度

2.memmove

语法:void *memcpy(void *destination, const void *source, int num);
作用:将一个任意类型的数组source拷贝到destination中,最多size个元素
与memcpy的区别:在C语言标准中,memcpy只能处理不重叠的内存(某些编译器中可以处理重叠的),memmove用于处理重叠内存的拷贝

3.memcmp

语法:int memcmp(const void *p1, const void *p2, num);
作用:比较内存大小,若p1<\p2,则返回一个小于零的数字,若p1==p2,则返回一个等于零的数字,若p1>p2,则返回一个大于零的数字,一共比较size个字节

4.memset

语法:void *memset(void *destination, int c, size_t count);
c是要设置的字符,count是一个无符号数字,是要设置为指定值的字节数
作用:内存设置,将指定的内存区域设置为指定的值,常用于初始化数组或结构体等数据结构
注意点:

  1. memset函数是按字节进行设置的,因此在设置非字符类型(比如整型)的数组时,可能会导致数据不符合预期,特别是在涉及到字节序的情况下
  2. 在使用memset函数时,要确保不会越界访问内存,否则会导致未定义的行为
  3. memset函数的性能通常很高,因为它可以利用处理器的特殊指令进行优化

十三.结构体

1.基本使用

声明语法:

struct stu{成员列表;
}结构体变量列表; //最后的分号不能丢

创建一个结构体变量:struct stu s1;
初始化方法:struct stu s1 = {成员变量的值};

声明的特殊写法
struct{memberList;
}x;

匿名结构体类型,x是唯一的结构体变量

struct{}* p;

这样写,p就是结构体指针

结构体的自引用
struct student{struct student n;
};

这种自引用的写法的内存无法判断,运行就会报错
正确的写法:

struct student{struct student *p;
};

这种写法的结构体内存是确定的,所以可以这么写
写法2:

typedef struct student{ //不能写成匿名结构体struct student *p;
}student;

2.结构体内存对齐

结构体的对齐规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处
  2. 其它成员变量要对齐到对齐数的整数倍的地址处
  3. 对齐数=编译器默认的一个对齐数与该成员变量大小中的较小值,VS编译器的默认对齐数是8,编译器可能没有默认对齐数
  4. 结构体的总大小为最大对齐数的整数倍
  5. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

内存对齐存在的理由:

  1. 不是所有平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
  2. 数据结构(尤其是栈)应该尽可能在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对其的内存访问仅需一次

总的来说:内存对齐是拿空间换时间的做法


修改默认对齐数:

#pragma pack(对齐数) //设置默认对其数
代码
#pragma pack() //取消设置的默认对齐数(可以不写,但是对齐数就永远都会是设置的对齐数)

计算偏移量:size_t offsetof(结构体名, 成员变量名);

3.结构体传参

将结构体传给函数:

void Init(struct stu *s1){s1->name = "a";s1->sex = 1;
}
int main(){struct stu s1 = {0};Init(&s1); //最好传地址return 0;
}

4.位段

位段的声明和结构体是类似的,有两个不同:

  1. 位段的成员必须是int、unsigned int、signed int
  2. 位段的成员名后边有一个冒号和一个数字

位段的内存分配:

  1. 位段的成员可以是int、unsigned int、signed int和char(属于整型家族)
  2. 位段的空间是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段

位段的跨平台问题:
请添加图片描述

总结:跟结构体比,位段可以达到同样的效果,但是更省空间,但是有跨平台的问题
位段的应用:
请添加图片描述

5.枚举

枚举类型的声明:

enum sex{man,woman,helicopter
};

创建一个枚举变量:enum sex s = man;
枚举的优点:

  1. 可读性和可维护性强
  2. 防止命名污染
  3. 和#define定义的标识符比较枚举有类型检查,更加严谨
  4. 便于调试
  5. 使用方便,一次可以定义多个常量

6.联合

联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)
当我们修改其中一个成员时,其他成员的值也会发生变化,因为它们共享同一块内存空间
联合的内存计算:联合的大小至少是最大成员的内存,最终会是对齐数的整数倍
联合的声明:

union S{...
};

判断大小端存储模式:

int check_sys(){union{char c;int i;}u;u.i = 1;return u.c; //1是小端,0是大端
}

十四.内存动态分配

1.malloc

语法:void malloc(size_t);
size_t是要申请获取的字节大小
注意:malloc的返回值是void
,使用时最好强制转换一下
使用:

#include <errno.h>
#include <string.h>
#include <stdlib.h> //malloc和free都是声明在<stdlib.h>中的
#include <stdio.h>
int main(){int *p = (int*)malloc(20); //申请5个整型的空间if (p == NULL){printf("%s\n", strerror(errno)); //如果请求失败,则返回空指针}else{for (int i = 0; i < 5; i++){*(p + i) = i;}}return 0;
}

2.free

语法:void free(void* p)
作用:释放空间,将分配给指针p的空间返回栈区,p指针不会重置为NULL
注意:

  1. malloc在程序结束时也会自动释放空间,free是主动释放、
  2. 如果参数p指向的空间不是动态开辟的,那free函数的行为是未定义的
  3. 若果参数p是NULL指针,则函数什么都不做

3.calloc

作用:开辟一个数组空间,并初始化为0
语法:void *calloc(size_t num, size_t size);
num是元素个数,size是一个元素的大小
如果开辟失败,则返回NULL指针
和malloc的区别:初始化为0

4.realloc

作用:调整动态开辟的空间的大小
语法:void *realloc(void *空间指针, size_t newSize);
newSize是新的空间大小
注意事项:

  1. 如果p指向的空间之后有足够的内存空间可以追加,则直接追加,后返回p
  2. 如果p指向的空间之后没有足够的内存空间可以追加,则返回一个新的地址
  3. 建议用一个新的变量来接受realloc函数的返回值
常见的动态内存错误

①对空指针解引用
②对动态开辟内存的越界访问
③对非动态开辟的空间使用free
④使用free释放动态内存的一部分
⑤对同一块动态内存的多次释放
⑥动态开辟内存忘记释放(内存泄露)

经典的笔试题

①:
请添加图片描述

输出结果是程序崩溃,原因是str是将自己的值而不是自己的地址传给GetMemory函数,也就是说p是str的一份拷贝,给p赋值不会传递给str,str始终是空指针
其次这段代码中有内存泄露的问题
请添加图片描述

返回栈空间的地址的问题:str指向p但是p在执行完函数后就会被销毁,于是str指向未知地址
所以不能返回栈空间地址,可以用static修饰,但是堆空间不会被及时销毁,所以也可用malloc分配空间

5.柔性数组

C99规定:结构中的最后一个元素允许是未知大小的数组,这就叫柔性数组成员
例:

struct S{int n;int arr[0]; //未知大小的柔性数组成员
};
int main(){struct S* ps = (struct S*)malloc(sizeof(struct S)+5*sizeof(int));  //第一个sizeof不会计算柔性数组的大小,结果是4if (ps != NULL) {  // 检查内存是否成功分配ps->arr[0] = 0; // 将arr的第一个元素赋值为0// 在程序结束前释放动态分配的内存free(ps);}return 0;
}

连续内存访问效率高,比如上述代码中的n和arr
柔性数组的特点:

  1. 结构中的柔性数组成员前面必须至少有一个其它成员
  2. sizeof返回的这种结构大小不包括柔性数组的内存
  3. 包含柔性数组成员的结构用malloc函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

优点:方便内存释放,访问速度高

十五.文件操作

1.文件

文件分为程序文件和数据文件
数据文件根据数据的组织形式,数据文件被称为文本文件(ASCII码)或二进制文件
文件缓冲区:ANSIC标准采用缓冲文件系统处理数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块文件缓冲区
缓冲区分输出缓冲区和输入缓冲区,缓冲区的大小由C编译系统决定
文件指针(文件类型指针):
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,为FILE
一般都是通过一个FILE的指针来维护这个FILE结构的变量:FILE *pf;

2.文件的打开和关闭

ANSIC规定使用fopen函数来打开文件,fclose关闭文件(都是stdio中的函数)
语法:
FILE *fopen(const char *文件名, const char *打开方式);
int fclose(FILE *stream);
打开方式:
请添加图片描述

文件的顺序读写:
请添加图片描述

fgetc的语法:int fgetc(FILE *stream);(如果stream是stdin,则表示从键盘读取文本行,fgets同理)
fputc的语法:int fputc(int character, FILE *stream);(character参数是要写入的字符,以ASCII码形式表示)
fgets的语法:char *fgets(char *str, int n, FILE *stream);(n表示要读取的最大字符数,返回的是指向str的指针)
fputs的语法:int fputs(const char *str, FILE *stream);
fscanf的语法:int fscanf(FILE *stream, const char *format, …);(根据指定的格式字符串从文件中读取数据,format是"%s"之类的)
fprintf的语法:int fprintf(FILE *stream, const char *format, …);(根据指定的格式字符串将数据写入到文件中)
fread的语法:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);(ptr是存储数据的指针,size是每个数据项的大小,nmemb是要读取或写入的数据项的数量,返回的指针指向ptr)
fwrite的语法:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

几个scanf和printf的对比

scanf:
用于从标准输入(键盘)读取输入。
格式化输入函数,可以根据格式字符串从标准输入中读取数据。
例子:scanf(“%d”, &num);


printf:
用于向标准输出(屏幕)输出内容。
格式化输出函数,可以按照格式字符串将数据输出到屏幕。
例子:printf(“The value of num is %d”, num);


fscanf:
用于从文件中读取输入。
格式化输入函数,可以根据格式字符串从文件中读取数据。
例子:fscanf(file_ptr, “%d”, &num);


fprintf:
用于向文件中写入内容。
格式化输出函数,可以按照格式字符串将数据输出到文件中。
例子:fprintf(file_ptr, “The value of num is %d”, num);


sscanf:
用于从字符串中读取输入。
格式化输入函数,可以根据格式字符串从字符串中读取数据。
例子:sscanf(str, “%d”, &num);


sprintf:
用于将格式化的数据写入字符串中。
格式化输出函数,可以按照格式字符串将数据输出到字符串中。
例子:sprintf(str, “The value of num is %d”, num);


总的来说,scanf、printf用于标准输入输出,fscanf、fprintf用于文件输入输出,sscanf、sprintf用于字符串处理

3.其它函数

(1)fseek

语法:int fseek(FILE *stream, long offset, int origin);(stdio.h中的)
offset是偏移量,origin是文件指针的当前位置
作用:将文件指针从origin这个位置偏移offset个字节
一些常量:

  1. SEEK_CUR:文件指针的当前位置
  2. SEEK_END:文件的末尾位置
  3. SEEK_SET:文件起始位置
(2)ftell

语法:long int ftell(FILE *stream);
作用:获取stream的相对于文件开头的偏移量

(3)fwind

语法:void rewind(FILE *stream);
作用:将stream重新指向文件开头

(4)文件结束判定

feof函数的语法:int feof(FILE *stream);
feof函数的作用:在文件读取结束的时候,判断是读取失败还是遇到文件结尾结束,如果失败则返回0,如果遇到文件结尾,则返回非负值


函数perror(str);可以打印str+报错信息且是stdio中的函数,比sterror(errno)方便

十六.程序环境和预处理

1.翻译环境和运行环境

在ANSI C的任何一种实现中,存在两个不同的环境
第一个是翻译环境,在这个环境中源代码被转换为可执行的机器指令
第二个执行环境,它用于实际执行代码
每个源文件都会被编译器处理,编译成目标文件(add.c->add.obj)
然后目标文件通过链接器链接成可执行文件(add.obj->add.exe)
编译又分为三个阶段:

  1. 预编译(文本操作):将include引入的头文件展开成代码,并把注释删除,使用空格代替注释,替换#define的文本
  2. 编译:把c语言代码翻译成汇编代码(语法分析、词法分析、语义分析、符号汇总)
  3. 汇编

相关文章:

Cweek4+5

C语言学习 十.指针详解 6.有关函数指针的代码 代码1&#xff1a;(*(void (*)())0)(); void(*)()是函数指针类型&#xff0c;0是一个函数的地址 (void(*)())是强制转换 总的是调用0地址处的函数&#xff0c;传入参数为空 代码2&#xff1a;void (*signal(int, void(*)(int))…...

Segment Anything CSharp| 在 C# 中通过 OpenVINO™ 部署 SAM 模型实现万物分割

​ OpenVINO™ C# API 是一个 OpenVINO™ 的 .Net wrapper&#xff0c;应用最新的 OpenVINO™ 库开发&#xff0c;通过 OpenVINO™ C API 实现 .Net 对 OpenVINO™ Runtime 调用.Segment Anything Model&#xff08;SAM&#xff09;是一个基于Transformer的深度学习模型&#x…...

企业应如何选择安全合规的内外网文件摆渡系统?

网络隔离是一种安全措施&#xff0c;旨在将网络划分为不同的部分&#xff0c;以减少安全风险并保护敏感信息。常见的隔离方式像物理隔离、逻辑隔离、防火墙隔离、虚拟隔离、DMZ区隔离等&#xff0c;将网络隔离成内网和外网。内外网文件摆渡通常指在内部网络&#xff08;内网&am…...

一分钟有60秒,这个有趣的原因你知道吗?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

二叉树最大宽度

文章目录 前言二叉树最大宽度1.题目解析2.算法原理3.代码编写 总结 前言 二叉树最大宽度 1.题目解析 给你一棵二叉树的根节点 root &#xff0c;返回树的 最大宽度 。 树的 最大宽度 是所有层中最大的 宽度 。 每一层的 宽度 被定义为该层最左和最右的非空节点&#xff08;即…...

React@16.x(24)自定义HOOK

目录 1&#xff0c;介绍2&#xff0c;简单举例2.1&#xff0c;获取数据1.2&#xff0c;计时器 2&#xff0c;自定义 HOOK 相比类组件 1&#xff0c;介绍 将一些常用的&#xff0c;跨组件的函数抽离&#xff0c;做成公共函数也就是 HOOK。自定义HOOK需要按照HOOK的规则来实现&a…...

群体优化算法----树蛙优化算法介绍以及应用于资源分配示例

介绍 树蛙优化算法&#xff08;Tree Frog Optimization Algorithm, TFO&#xff09;是一种基于群体智能的优化算法&#xff0c;模拟了树蛙在自然环境中的跳跃和觅食行为。该算法通过模拟树蛙在树枝间的跳跃来寻找最优解&#xff0c;属于近年来发展起来的自然启发式算法的一种 …...

常见汇编指令

下面是一些包含汇编指令 MOV、PUSH、POP、LEA、LDS、ADD、ADC、INC、SUB、SBB、DEC、CMP、MUL、DIV、AND、OR、XOR、NOT、TEST、SHL、SAL、SHR、SAR、ROL、ROR、RCL、RCR、LODS、MOVS 的例题。这些例题展示了每条指令的用法及其作用。 1. MOV 指令 MOV AX, BX ; 将寄存器 B…...

Mysql学习(七)——约束

文章目录 四、约束4.1 概述4.2 约束演示4.3 外键约束 总结 四、约束 4.1 概述 概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。目的&#xff1a;保证数据库中数据的正确、有效性和完整性。分类&#xff1a; 4.2 约束演示 根据需求&…...

Redis实战篇02

1.分布式锁Redisson 简单介绍&#xff1a; 使用setnx可能会出现的极端问题&#xff1a; Redisson的简介&#xff1a; 简单的使用&#xff1a; 业务代码的改造&#xff1a; private void handleVoucherOrder(VoucherOrder voucherOrder) {Long userId voucherOrder.getUserI…...

怎么用PHP语言实现远程控制两路照明开关

怎么用PHP语言实现远程控制两路开关呢&#xff1f; 本文描述了使用PHP语言调用HTTP接口&#xff0c;实现控制两路开关&#xff0c;两路开关可控制两路照明、排风扇等电器。 可选用产品&#xff1a;可根据实际场景需求&#xff0c;选择对应的规格 序号设备名称厂商1智能WiFi墙…...

Docker面试整理-什么是多阶段构建?它的好处是什么?

多阶段构建是 Docker 在 Dockerfile 中引入的一个功能,允许你在单个 Dockerfile 中使用多个构建阶段,但最终只生成一个轻量级的镜像。这是通过在一个 Dockerfile 中定义多个 FROM 指令来实现的,每个 FROM 指令都可以使用不同的基础镜像,并开始一个新的构建阶段。 多阶段构建…...

ENSP校园网设计实验

前言 哈喽&#xff0c;我是ICT大龙。本次更新了使用ENSP仿真软件设计校园网实验。时间比较着急&#xff0c;可能会有错误&#xff0c;欢迎大家指出。 获取本次工程文件方式在文章结束部分。 拓扑设计 拓扑介绍---A校区 如图&#xff0c;XYZ大学校园网设计分为3部分&#xff0…...

【Spring框架全系列】SpringBoot_3种配置文件_yml语法_多环境开发配置_配置文件分类(详细)

文章目录 1.三种配置文件2. yaml语法2.1 yaml语法规则2.2 yaml数组数据2.3 yaml数据读取 3. 多环境开发配置3.1 多环境启动配置3.2 多环境启动命令格式3.3 多环境开发控制 4. 配置文件分类 1.三种配置文件 问题导入 框架常见的配置文件有哪几种形式&#xff1f; 比如&#xf…...

华为坤灵路由器初始化的几个坑,含NAT配置

1、aaa密码复杂度修改&#xff1a; #使能设备对密码进行四选三复杂度检查功能。 <HUAWEI>system-view [HUAWEI]aaa [HUAWEI-aaa]local-aaa-user password policy administrator [HUAWEI-aaa-lupp-admin]password complexity three-of-kinds 2、本地用户名长度必须大…...

【RAG入门教程04】Langchian的文档切分

在 Langchain 中&#xff0c;文档转换器是一种在将文档提供给其他 Langchain 组件之前对其进行处理的工具。通过清理、处理和转换文档&#xff0c;这些工具可确保 LLM 和其他 Langchain 组件以优化其性能的格式接收数据。 上一章我们了解了文档加载器&#xff0c;加载完文档之…...

请求 响应

在web的前后端分离开发过程中&#xff0c;前端发送请求给后端&#xff0c;后端接收请求&#xff0c;响应数据给前端 请求 前端发送数据进行请求 简单参数 原始方式 在原始的web程序中&#xff0c;获取请求参数&#xff0c;需要通过HttpServletRequest 对象手动获取。 代码…...

技术周总结2024.06.03~06.09(K8S HikariCP数据库连接池)

文章目录 一、06.05 周三1.1) 问题01: 容器领域&#xff0c;Docker与 K8S的区别和联系Docker主要功能和特点&#xff1a;使用场景&#xff1a; Kubernetes (K8S)主要功能和特点&#xff1a;使用场景&#xff1a; 联系和区别联系&#xff1a;区别&#xff1a; 结合使用总结 二、…...

【JavaScript】了解 Sass:现代 CSS 的强大预处理器

我已经从你的 全世界路过 像一颗流星 划过命运 的天空 很多话忍住了 不能说出口 珍藏在 我的心中 只留下一些回忆 &#x1f3b5; 牛奶咖啡《从你的全世界路过》 在前端开发领域&#xff0c;CSS 是必不可少的样式表语言。然而&#xff0c;随着项目复杂度的…...

下载安装Thonny并烧录MicroPython固件至ESP32

Thonny介绍 一、Thonny的基本特点 面向初学者&#xff1a;Thonny的设计初衷是为了帮助Python初学者更轻松、更快速地入门编程。它提供了直观易懂的用户界面和丰富的功能&#xff0c;降低了编程的门槛。轻量级&#xff1a;作为一款轻量级的IDE&#xff0c;Thonny不会占用过多的…...

YOLOv5改进 | 主干网络 | 将主干网络替换为轻量化的ShuffleNetv2【原理 + 完整代码】

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 目标检测是计算机视觉中一个重要的下游任务。对于边缘盒子的计算平台来说&#xff0c;一个大型模型很难实现实时检测的要求。基于一系列消融…...

LeetCode:字母异位词分组

文章收录于LeetCode专栏 LeetCode地址 字母异位词分组 题目 给定一个字符串数组&#xff0c;将字母异位词组合在一起。字母异位词指字母相同&#xff0c;但排列不同的字符串。所有输入均为小写字母&#xff0c;且不考虑答案输出的顺序。   示例1&#xff1a; 输入: strs [“…...

技术与业务的完美融合:大数据BI如何真正提升业务价值

数据分析有一点经典案例 沃尔玛的啤酒和尿布案例 开始做BI的时候&#xff0c;大家肯定都看过书&#xff0c;那么一定也看过一个经典的案例&#xff0c;就是沃尔玛的啤酒和尿布的案例。这个案例确实很经典&#xff0c;但其实是一个失败的案例。为什么这么说呢&#xff1f;很明显…...

计网复习资料

一、选择题&#xff08;每题2分&#xff0c;共40分&#xff09; 1. Internet 网络本质上属于&#xff08; &#xff09;网络。 A.电路交换 B.报文交换 C.分组交换 D.虚电路 2.在 OSI 参考模型中,自下而上第一个提供端到端服务的是( )。 A.数据链路层 B.传输…...

华为策略流控

以下脚本仅做参考&#xff0c;具体IP地址和接口请按照现场实际情况写入。 [Huawei]acl 3001 [Huawei-acl-adv-3001]rule permit ip source 192.168.1.10 0.0.0.0 destination 192.168.2.10 0.0.0.0 //匹配需要做测试的源和目标地址 [Huawei-acl-adv-3001]rule permit ip sour…...

刷代码随想录有感(98):动态规划——爬楼梯

题干&#xff1a; 代码&#xff1a; class Solution { public:int climbStairs(int n) {if(n 1)return 1;if(n 2)return 2;vector<int>dp(n 1);dp[0] 0;dp[1] 1;dp[2] 2;for(int i 3; i < n; i){dp[i] dp[i - 1] dp[i - 2];}return dp[n];} }; 其实就是斐波…...

零基础入门篇①⑦ Python可变序列类型--集合

Python从入门到精通系列专栏面向零基础以及需要进阶的读者倾心打造,9.9元订阅即可享受付费专栏权益,一个专栏带你吃透Python,专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇…学习不断,持续更新,火热订阅中🔥专栏限时一个月(5.8~6.8)重…...

基于NodeJs 的Vue安装和创建项目

基于NodeJs 的Vue安装和创建项目 一、Node.js的下载与安装 下载地址&#xff1a; https://nodejs.org/en/download/prebuilt-installer 安装完之后&#xff0c;启动 cmd命令行&#xff0c;验证 Node.js 是否安装成功 二、配置npm的全局模块的存放路径以及缓存的路径 注&…...

【简单介绍下DALL-E2,什么是DALL-E2?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…...

springboot+mqtt使用总结

1.软件的选型 1.1.使用免费版EMQX 1.1.1.下载 百度搜索的目前是会打开官网&#xff0c;这里提供下免费版的使用链接EMQX使用手册 文档很详细&#xff0c;这里不再记录了。 1.2.使用rabbitmq rabbitmq一般做消息队列用&#xff0c;作为mqtt用我没有找到详细资料&#xff0c…...

找客户在公司做网站/新闻报道最新消息今天

之前都是使用OpenCV/C来做的图像处理。因为python更轻量&#xff0c;更方便所以硕士毕业论文使用python处理下&#xff0c;做的过程中记录下使用python处理特征提取遇到的一些问题&#xff0c;以上为背景。 开发环境 windows8.1 pycharm anaconda2 (自带很多包) opencv2.4…...

在线播放视频网站怎么做/网站运营推广方案

转载于&#xff1a;https://blog.csdn.net/u011700186/article/details/109452658 相关环境 MacOS 10.15.4 SecureCRT 8.7.0 问题描述 当某一个用户登录某一台服务器之后&#xff0c;我们可能会想要执行某些特定的命令或者脚本。比如&#xff0c;连接后我们想要自动切换到某…...

做代练网站能备案/广西南宁市有公司网站设计

关于AVL树&#xff08;平衡二叉搜索树&#xff0c;高度为lgn&#xff09;的讲解&#xff0c;双手呈上某大佬博客&#xff1a;https://www.cnblogs.com/zhuwbox/p/3636783.html 我从这题get到一个新的结构体写法&#xff08;姿势&#xff09;&#xff1a; typedef struct treeNo…...

唐山网站建设自主开发/快速整站排名seo教程

点击下载 转载于:https://blog.51cto.com/19880614/933589...

北海手机网站建设/企业营销咨询

本文实例讲述了PHP使用mkdir创建多级目录的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;PHP中使用mkdir()可以创建多级目录&#xff0c;相比之前自己一级一级的创建&#xff0c;这个函数非常好用。下面是php手册上的函数介绍&#xff1a;bool mkdir ( string $…...

商城网站建设需要什么团队/怎么注册网站平台

七&#xff1a;桥接模式&#xff08;bridge&#xff09; 1.问题引出&#xff1a;商城系统中很多商品分类&#xff0c;以电脑为例&#xff1a;台式机&#xff0c;笔记本&#xff0c;平板电脑等&#xff0c;我们可以通过下图描述其关系 通过上面的图会发现很多问题&#xff1a; …...