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不会计算柔性数组的大小,结果是4
  if (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. 汇编

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/694555.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AE电源pinnacle软件新款老款二款软件

AE电源pinnacle软件新款老款二款软件

高速USB转串口芯片CH343

CH343封装 截止目前&#xff0c;主要封装有 SOP16: CH343G QFN16: CH343P ESSOP10: CH343K,截止24年6月未生产 CH343串口速度 最高串口速度&#xff1a; 6Mbps,比CH340的2M&#xff0c;快3倍 1、概述 参考版本&#xff1a;1E CH343 是一个 USB 总线的转接芯片&#xff0c;…

国标GB/T 28181详解:校时流程详细说明

目录 一、定义 二、作用 1. 时间同步性 2. 事件记录的准确性 3. 跨平台、跨设备协作 4. 降低时间误差 5. 安全性提升 三、基本要求 四、命令流程 五、协议接口 六、校时效果 1、未校时的情况 2、校时后的效果 七、参考 一、定义 GB28181协议要求所有的监控设…

把系统引导做到U盘,实现插上U盘才能开机

前言 有个小伙伴提出了这样一个问题&#xff1a;能不能把U盘制作成电脑开机的钥匙&#xff1f; 小白稍微思考了一下&#xff0c;便做了这样一个回复&#xff1a;可以。 至于为什么要思考一下&#xff0c;这样会显得我有认真思考他提出的问题。 Windows7或以上系统均支持UEF…

Cannot access spring-snapshot (https://repo.spring.io/snapshot) in offline mode

Maven报错 这个选项是脱机工作&#xff0c;意思就是不读取远程仓库&#xff0c;只读取本地已有的仓库&#xff0c;之所以报错原因就是本地仓库是空的&#xff0c;然而选择了脱机工作

Android.mk文件生成的so工程文件并Debug调试native code

1.这里主要展示一下从最原始先新建一个工程 2.将hello的子工程文件放入上面新建好的工程里面&#xff0c;直接拷贝放置这里 3.修改根目录下的settings.gradle 加入hello 4.app工程下的build.gradle加入依赖&#xff0c;这样就可以识别hello中的java包文件 5.MainActivity 中来&…

Redis主从同步

master如何得知salve是否是第一次来同步呢&#xff1f;&#xff1f; 有几个概念&#xff0c;可以作为判断依据&#xff1a; Replication Id&#xff1a;简称replid&#xff0c;是数据集的标记&#xff0c;replid一致则是同一数据集。每个master都有唯一的replid&#xff0c;s…

C++初阶学习第六弹——探索STL奥秘(一)——标准库中的string类

前言&#xff1a; 在前面&#xff0c;我们学习了C的类与对象&#xff0c;认识到了C与C语言的一些不同&#xff0c;今天&#xff0c;我们将进入C的 关键部分——STL&#xff0c;学习完这部分之后&#xff0c;我们就可以清楚的认识到C相比于C语言的快捷与便利 目录 一、为什么有s…

【MySQL】(基础篇四) —— 检索数据

检索数据 检索数据是我们使用数据库时进行最多的操作&#xff0c;其中包括了检索条件、排序、过滤、分组等等。我会在后续的多篇博客中为你进行详细地介绍它们。 这次先让我们来粗略的了解一下SELECT&#xff0c;为了使用SELECT检索表数据&#xff0c;必须至少明确两点信息—…

Linux:动态库和静态库的编译与使用

目录 1.前言 2.静态链接库 3.静态链接库生成步骤 4.静态链接库的使用 5.动态链接库 6.动态链接库生成步骤 7.动态链接库的使用 8.动态链接库无法加载 9.解决动态链接库无法加载问题 前言 在《MinGW&#xff1a;从入门到链接库》博客中简单介绍了如何编译动态链接库和静态链接库…

python - pandas常用计算函数

文中所用数据集有需要的可以私聊我获取 学习目标 知道排序函数nlargest、nsmallest和sort_values的用法 知道Pandas中求和、计数、相关性值、最小、最大、平均数、标准偏差、分位数的函数使用 1 排序函数 导包并加载数据集 import pandas as pd ​ # 加载csv数据, 返回df对…

MySQL之多表查询—行子查询

一、引言 上篇博客学习了列子查询。 接下来学习子查询中的第三种——行子查询。 行子查询 1、概念 子查询返回的结果是一行&#xff08;当然可以是多列)&#xff0c;这种子查询称为行子查询。 2、常用的操作符 、 <> (不等于) 、IN 、NOT IN 接下来通过一个需求去演示和…

系统思考—心智模式

凯恩斯说&#xff1a;“介绍新观念倒不是很难&#xff0c;难的是清除那些旧观念。”在过去的任何一年&#xff0c;如果你一次都没有推翻过自己最中意的想法&#xff0c;那么你这一年就算浪费了。旧观念像是根深蒂固的杂草&#xff0c;即使在新知识的光照下&#xff0c;也需要时…

stream 流的一些底层实现原理

闭包 闭包的底层实现?外层的变量成为方法的一部分会生成一个lambda方法&#xff0c;将源本的2个参数转化3个参数此时变量就成为了方法的一部分值是如何传递的呢?会有一个专门的类用于存储此变量的值 流的切分后再并行 数组或者是集合&#xff0c;需要用到一个可切分的迷代器这…

如何一键拷贝PPT中的所有文字?

有时我们可能需要引用PPT的文字&#xff0c;但一个幻灯片一个幻灯片拷贝很是麻烦&#xff0c;我们想一键拷贝PPT中所有幻灯片中的内容&#xff08;最近我就遇到了这个需求&#xff09;。今天就来讲讲这个一键拷贝的技巧。因为大家可能会遇到同样的问题&#xff0c;所以在此记录…

[Vue-常见错误]浏览器显示Uncaught runtime errors

文章目录 错误描述正确写法具体如下 错误描述 当前端代码发生错误时&#xff0c;浏览器中出现以下错误提示。 正确写法 显然这不是我们所期望的&#xff0c;在vue.config.js中配置如下设置关闭Uncaught runtime errors显示 devServer: {client: {overlay: false}具体如下 …

Matlab|遗传粒子群-混沌粒子群-基本粒子群

目录 1 主要内容 2 部分代码 3 效果图 4 下载链接 1 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点&#xff08;重要的事情说三遍&#xff09;&#xff0c;对于采用智能算法的模型&#xff0c;可以采用算法改进的方式来达到提高整个文章创新水平的目的&…

二叉查找树详解

目录 二叉查找树的定义 二叉查找树的基本操作 查找 插入 建立 删除 二叉树查找树的性质 二叉查找树的定义 二叉查找树是一种特殊的二叉树&#xff0c;又称为排序二叉树、二叉搜索树、二叉排序树。 二叉树的递归定义如下&#xff1a; &#xff08;1&#xff09;要么二…

知识图谱的应用---智能电网

文章目录 智能电网典型应用 智能电网 智能电网以物理电网为基础&#xff0c;将现代先进的传感测量技术、通讯技术、信息技术、计算机技术和控制技术与物理电网高度集成而形成的新型电网。它以充分满足用户对电力的需求和优化资源配置、确保电力供应的安全性、可靠性和经济性、满…

代码随想录-Day28

93. 复原 IP 地址 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址&#xff0c;但是 “0.011.255…