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

c语言知识整理

一  数据的存储

    对于整形的存储    无论是正负在存储中都是使用补码进行存储的  那个一个数字的补码在转换正负时不同的   对于存储中 首位一定是符号位  如果是0  那么是正数  如果是1 那么是负数   (32位  除符号位 缺少的位数使用0补齐)

   如果是正数  那么其 原码 反码  补码都是相同的    原码就是这个数的二进制   

   如果是负数  那么原码是其二进制位时的表示    反码就是将原码除符号位之外进行按位去反

 补码就是再对求出的反码进行+1   也就是原码-> 转换为补码  就是取反之后+1    反之 补码变原码也是取反 +1 

大小端存储 在不同的编译器环境下 使用的存储可能是大端也可能是小端  

如果数据的小端 放在内存地址中的低地址   数据的大端 放在内存中高地址处 那么这样就是小端的存储方式  反之

数据的小端 放在内存地址中的高地址   数据的大端 放在内存中低地址处 那么这样就是小端的存储方式

写一段代码 判断这个环境下存储使用的是大端还是小端

#include<stdio.h>int func()
{int f = 1;return  (*(char*) & f);
}
int main()
{if (func() == 1){printf("小端存储\n");}else{printf("大端存储\n");}return 0;
}

此外还可以通过联合体公用同一块地址的方式 在判断使用的是大端还是小端存储

   

#include<stdio.h>
int func()
{union{int i;char  r;}s;s.i = 1;return s.r;
}

整形类型之间的互相赋值时会发生截断和提升问题

浮点数的存储问题

任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式

V   =  (−1) ∗  S M ∗ 2 E

• (−1) 表⽰符号位,当S=0,V为正数;当S=1,V为负数 S

• M表⽰有效数字,M是⼤于等于1,⼩于2的

• 2 表⽰指数位

32 位浮点数(单精度)
  • 符号位(S):1 位,最高位,0 表示正数,1 表示负数。

  • 指数位(E):8 位。

  • 尾数位(M):23 位。

64 位浮点数(双精度)
  • 符号位(S):1 位,最高位,0 表示正数,1 表示负数。

  • 指数位(E):11 位。

  • 尾数位(M):52 位。

为什么浮点数和整数的解读结果差别很大?

  1. 存储格式不同

    • 浮点数:存储的是符号位、指数位和尾数位。

    • 整数:存储的是直接的二进制数值。

  2. 解读方式不同

    • 浮点数:需要按照 IEEE 754 标准的公式 V=(−1)S×M×2E 来解读。

    • 整数:直接将二进制序列转换为十进制数值。

c语言中常见的库函数  

首先接受的字符串协函数

1.size_t strlen ( const char * str );

  这里的字符串中必须存在\0  

strlen函数会在找到\0 之后停止 并且返回 \0 之前的字符串长度

这里需要包含头文件string.h

模拟strlen函数

// 不使用临时变量模拟strlen
size_t mystrlen(const char* arr)
{assert(arr);if (*arr == '\0'){return 0;}else{return mystrlen(arr+1)+1;}}
int main()
{char s[] = "1231456";printf("%d\n", mystrlen(s));s[2] = '\0';printf("%d\n", mystrlen(s));return 0;
}

#include<stdio.h>
#include<string.h>
#include<assert.h>
size_t mystrlen(const char * arr)
{assert(arr);int ret = 0; while (*arr){ret++;arr++;}return ret;
}
int main()
{char s[] = "1231456";printf("%d\n", mystrlen(s));s[2] = '\0';printf("%d\n", mystrlen(s));return 0;
}

2.char* strcpy(char * destination, const char * source );

strcpy会将 source中的内容复制destination 

首先source 中必须存在'\0'      目标数组中必须是可以修改的

destination中必须有足够多的数组大小来存储source中的内容  并且最后会将源字符串中的\0也会拷贝到目的数组中

模拟strcpy函数

char* mystrcpy( char* din , const char*  sour  )
{assert(din);assert(sour);char* s1 = din;while (*din++ = *sour++){;}return s1;
}int main()
{char c1[] = "       123545";const char* c2 = "wqeqwr";mystrcpy(c1 , c2);printf("%s\n", c1);return 0;
}

3.char *my_strcat(char *dest, const char*src);

 使用这个函数 无论是dest 韩式 src字符串都要存在\0   且dest字符串时可以修改的   dest字符串的容量足以存下dest+src的容量

strcat 会将src中的内容追加到dest字符串中  从覆盖dest\0的位置开始追加

模拟strcat 函数


char* mystrcat(char* dest , const char* src)
{assert(dest);assert(src);char* ret = dest;while (*dest){dest++;}while (*dest++ = *src++){;}return ret;
}
int main()
{char c1[20] = "123545";const char* c2 = "wqeqwr";mystrcat(c1 , c2);printf("%s\n", c1);return 0;
}

4.int strcmp ( const char * str1, const char * str2 );

  这里是要比较两个字符串的大小  首先比较是按照字典序进行比较的  如果两者在第一位的字符相同  则继续比较第二位的字符  如果两个字符串 在前面的比较都相同 则字符串长度较长的大  如果两个字符串长度相同 且每一位的字符相同的话 则两个字符串时相同的

模拟 strcmp

int mystrcmp(const char * c1 , const char * c2)
{assert(c1);assert(c2);while (*c1 && * c2){if (*c1 > *c2)return 1;else if (*c1 < *c2)return -1;c1++;c2++;}if (*c1 == '\0' && *c2 == '\0')return 0;else if (*c1 == '\0')return -1;else if (*c2 == '\0')return 1;
}
int main()
{char c1[20] = "55511";char c2[] = "555111";int ret =   mystrcmp(c1 , c2);printf("%d\n", ret);return 0;
}

char * strstr ( const char * str1, const char * str2); 

strstr是在str1中 找str2完全匹配的子字符串 并且将这个在str1中第一次找到位置进行返回  找寻的范围知道str1中第一次出现\0结束

模拟strstr

char* mystrstr(const char* c1 , const char*c2)
{char* cp = (char*)c1;if (!*c2) return (char*)c1;while (*cp){char* s1 = (char *)cp;char* s2 = (char*) c2;while (*s1 && *s2 && *s1 == *s2){s1++;s2++;}if (*s2 == '\0')return (char * )cp;cp++;}return (NULL);
}int main()
{char str[] = "This is a simple string";char* pch;pch = mystrstr(str, "simple");printf("%d\n", pch - str);return 0;
}

内存函数

1.void * memcpy ( void * destination, const void * source, size_t num );

memcpy 的行为

按字节复制

memcpy 会从 source 指定的内存位置开始,逐字节复制数据到 destination 指定的内存位置。

它会复制 num 个字节的数据。

不检查 '\0'

memcpy 不会检查数据中的内容,它不会在遇到 '\0'(空字符)时停止复制。这与 strcpy 函数不同,strcpy 会在遇到 '\0' 时停止复制。

内存重叠问题

如果 sourcedestination 有重叠部分,memcpy 的行为是未定义的。这意味着结果可能是不可预测的,具体行为取决于编译器和硬件实现

注意事项

            确保目标内存足够大

  在调用 memcpy 之前,确保目标内存有足够的空间来存储复制的数据,避免内存溢出。

避免内存重叠

   如果可能涉及内存重叠,使用 memmove 而不是 memcpy

检查指针有效性

    确保 sourcedestination 指针有效,避免野指针或空指针导致的运行时错误。

模拟实现memcpy

#include<stdio.h>
void* mymemcpy(void*dest ,const void* src , size_t num)
{void* ret = dest;assert(dest);assert(src);while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}
int main()
{int arr1[] = {1,2,3,4,5,6,7,8,9,10};int arr2[10] = {0};mymemcpy(arr2,arr1 , sizeof(int) * 7);for (int i = 0; i < 10; i++)printf("%d ", arr2[i]);return 0;
}

2. void * memmove ( void * destination, const void * source, size_t num );

这里的使用方式和上面的memcpy基本一致 但是memmove能够解决上面memcpy中的复制自己时产生的重叠问题

模拟memmove

void* mymemmove(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest);assert(src);if (dest <= src ||(char*)dest >=  (char*)src+ num ){while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{dest = (char*)dest + num - 1;src = (char*)src + num - 1;while (num--){*(char*)dest = *(char*)src;dest = (char*)dest -1;src = (char*)src -1;}}return ret;
}
int main()
{int arr1[] = {1,2,3,4,5,6,7,8,9,10};int arr2[10] = {0};mymemmove(arr1+2,arr1 , sizeof(int) * 5);for (int i = 0; i < 10; i++)printf("%d ", arr1[i]);return 0;
}

3.void * memset ( void * ptr, int value, size_t num );

#include <stdio.h>
#include <string.h>
int main ()
{char str[] = "hello world";memset (str,'x',6);printf(str);return 0;
}

输出的结果:xxxxxxworld

自定义类型 

    结构体  struct

      结构体是数据的集合   

         结构体内存对齐规则

         

    

  1. 第一个成员的对齐方式

    • 结构体的第一个成员总是对齐到与结构体变量起始位置偏移量为0的地址处。也就是说,第一个成员的地址就是结构体的起始地址。

  2. 其他成员的对齐方式

    • 其他成员变量需要对齐到某个数字(对齐数)的整数倍的地址处。

    • 对齐数 = 编译器默认的对齐数与该成员变量大小的较小值。

      • 在Visual Studio(VS)中,默认的对齐数为8。

      • 在Linux中,使用gcc编译器时,没有默认对齐数,对齐数就是成员自身的大小。

  3. 结构体总大小的计算

    • 结构体的总大小必须是结构体中最大对齐数的整数倍。

    • 如果结构体的最后一个成员的结束位置没有达到最大对齐数的整数倍,编译器会在结构体的末尾添加填充字节,以确保结构体的总大小符合对齐要求。

  4. 嵌套结构体的对齐方式

    • 如果结构体中嵌套了其他结构体,嵌套的结构体成员需要对齐到其成员中最大对齐数的整数倍处。

    • 结构体的整体大小是所有最大对齐数(包括嵌套结构体中成员的对齐数)的整数倍。

为什么要有内存对齐规则 ?

1.不同的硬件平台对内存访问有不同的要求和限制。这些限制主要源于硬件设计和指令集架构。

2.内存对齐可以显著提高内存访问的效率,从而提升程序的整体性能。如果数据未对齐,处理器可能需要进行两次内存访问,因为数据可能跨越两个内存块。

修改默认对⻬数 #pragma 这个预处理指令,可以改变编译器的默认对⻬数。

#pragma pack(1)//设置默认对⻬数为1 
struct S
{char c1;int i;char c2;
};
#pragma pack()//取消设置的对⻬数,还原为默认 
int main()
{//输出的结果是什么? printf("%d\n", sizeof(struct S));return 0;
}

结构体位段

位段的定义

位段是一种结构体或联合体中的成员,它允许指定每个成员占用的位数。位段的声明方式类似于普通结构体成员,但有两个主要区别:

  1. 成员类型限制

    • 位段的成员类型通常是intunsigned intsigned int

    • 在C99标准中,位段成员的类型可以扩展到其他整数类型(如charshort等),但具体支持情况取决于编译器。

  2. 位宽指定

    • 位段成员名后面必须有一个冒号和一个数字,表示该成员占用的位数。

struct BitField {unsigned int field1 : 3;  // 占用3位unsigned int field2 : 5;  // 占用5位int field3 : 4;           // 占用4位
};

总结 :跟结构相⽐,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。

联合体

union Un
{char c;int i;
};

联合体的特点  联合的成员是共⽤同⼀块内存空间的,这样⼀个联合变量的⼤⼩,⾄少是最⼤成员的⼤⼩(因为联合 ⾄少得有能⼒保存最⼤的那个成员)。

联合体⼤⼩的计算

联合的⼤⼩⾄少是最⼤成员的⼤⼩。

当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。

枚举

enum Day//星期
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};

{}中的内容是枚举类型的可能取值,也叫 枚举常量 。 这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。

优点总结

  • 可读性和可维护性:枚举类型通过赋予常量有意义的名称,使代码更易于理解和维护。

  • 类型检查:枚举类型在编译时进行类型检查,避免错误的常量值被使用。

  • 调试方便:枚举类型的常量名称在调试时会保留,便于调试。

  • 使用方便:枚举类型可以一次性定义多个常量,自动赋值,减少代码量。

  • 作用域规则:枚举类型可以定义在函数内部,避免全局命名冲突,使代码更加模块化。

为什么使用枚举而不是#define

虽然#define可以定义常量,但它缺乏类型检查和作用域控制,容易导致错误和命名冲突。枚举类型提供了更强大的功能和更高的安全性,是定义一组相关常量的更好选择。

enum Color//颜⾊
{RED=1,GREEN=2,BLUE=4
};
enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值 

内存管理

为什么要有动态内存分配?

灵活的内存管理

  • 运行时确定大小:在许多情况下,程序在编译时并不知道需要多少内存。例如,用户输入的数据量、文件大小或网络传输的数据量等,这些信息只有在程序运行时才能确定。动态内存分配允许程序在运行时根据实际需要申请内存。

  • 调整内存大小:使用动态内存分配,程序可以根据需要增加或减少内存的使用。这对于处理可变大小的数据集非常有用。

 优化内存使用

  • 按需分配:动态内存分配允许程序仅在需要时才分配内存,这样可以避免不必要的内存浪费。

  • 内存重用:通过动态内存分配,程序可以释放不再使用的内存,这些内存可以被操作系统回收并重新分配给其他需要的程序,从而提高内存的利用率。

   malloc  realloc  calloc 区别

malloc 和 calloc 的区别

  1. 初始化

    • malloc:申请的内存空间不会进行初始化,其内容是不确定的,可能是之前使用过的内存中残留的数据。

    • calloc:会将申请的内存空间全部初始化为0。

  2. 参数

    • malloc:只需要传入一个参数,即申请的总字节数。

    • calloc:需要传入两个参数,第一个是元素个数,第二个是每个元素的大小。calloc会计算这两个参数的乘积,得到总字节数,并分配相应大小的内存。

realloc 和它们两个的区别

  1. 功能

    • realloc:用于对已经申请好的内存空间进行大小调整。它可以增加或减少已分配内存的大小,并返回一个新的指针。如果调整后的内存大小比原来的小,可能会丢失超出新大小的数据;如果比原来的大,新增加的部分内容是不确定的。

    • malloccalloc:用于申请新的内存空间,不涉及对已分配内存的调整。

  2. 参数

    • realloc:需要传入两个参数,第一个是已分配内存的指针,第二个是期望的总字节数。

    • malloccalloc:只需要传入一个参数(malloc)或两个参数(calloc),用于指定申请的内存大小。

C/C++中程序内存区域划分

栈区(stack):在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内 存容量有限。栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。 

  • 特点

    • 速度快:由于栈内存的分配和释放非常快速,因此适用于存储生命周期较短的数据。

    • 容量有限:与堆相比,栈的容量通常较小,过多的递归调用或大数组可能会导致栈溢出。

    • 后进先出(LIFO):栈是一种后进先出的数据结构,最后压入的数据会最先被弹出。

 2. 堆区(heap):⼀般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。分配⽅ 式类似于链表。动态分配的内存,如使用malloccallocreallocfree等函数分配的内存。

  • 特点

    • 灵活性高:堆内存的大小不固定,可以根据需要动态调整,适合存储生命周期较长的数据。

    • 分配速度较慢:相比栈内存,堆内存的分配和释放速度较慢,因为需要进行内存管理操作。

    • 碎片化问题:频繁的分配和释放可能导致堆内存碎片化,影响内存使用效率。

3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。

  • 特点

    • 生命周期长:静态内存的生命周期贯穿整个程序的运行过程,直到程序结束。

    • 初始化:未显式初始化的全局变量和静态变量会被自动初始化为0。

4. 代码段:存放函数体(类成员函数和全局函数)的⼆进制代码。  

  • 特点

    • 只读:代码段通常是只读的,以防止程序运行时被意外修改。

    • 共享:在某些系统中,多个程序可能会共享相同的代码段,以节省内存空间。

文件操作

 

程序文件

程序文件通常指的是包含程序代码的文件,它们可以是源代码文件、目标文件或可执行文件。这些文件在程序的编译和执行过程中起着重要作用。源程序文件(.c)目标文件(.obj)可执行程序(.exe)

数据文件

数据文件是程序运行时读写的数据文件,它们不包含程序代码,而是包含程序需要处理的数据。

数据文件 又可以分为二进制文件 和 文本文件

文本文件

以ASCII码的形式存储数据,每个数字由字符表示。文本文件可读性强,但可能包含额外的字符编码信息。

  1. 用途

    • 文本文件常用于存储配置信息、源代码、日志文件等。

    • 它们也常用于数据交换,如CSV文件可以被Excel等电子表格软件读取。

二进制文件

直接存储数据的二进制表示,不包含可读的字符。二进制文件不可读,但存储和传输效率更高。

  1. 用途

    • 二进制文件常用于存储图像、音频、视频等多媒体数据。

    • 它们也常用于存储复杂的数据结构和对象,如数据库文件、可执行文件等。

⽂件的随机读写

seek 根据⽂件指针的位置和偏移量来定位⽂件指针

ftell 返回⽂件指针相对于起始位置的偏移量

rewind 让⽂件指针的位置回到⽂件的起始位置

对⽐⼀组函数:scanf/fscanf/sscanf

                         printf/fprintf/sprintf

scanffscanfsscanf 用于从不同来源读取格式化输入,其中 scanf 从标准输入读取,fscanf 从文件读取,sscanf 从字符串读取。

printffprintfsprintf 用于输出格式化字符串,其中 printf 输出到标准输出,fprintf 输出到文件,sprintf 输出到字符串。

这些函数在参数和返回值上有所不同,但都遵循类似的格式化规则,使得它们可以灵活地处理各种输入输出任务。

头文件中的 #ifndef/#define/#endif 是干什么用的?

这三个预处理指令通常一起使用,用于防止头文件内容被重复包含,称为“包含保护”。这种结构确保了即使头文件被多次包含,其内容也只会被编译一次,避免了重复定义等问题。

  • #ifndef:表示“如果未定义”。预处理器会检查指定的宏是否已被定义,如果没有定义,则执行接下来的代码。

  • #define:用于定义一个宏。在包含保护中,通常定义一个与头文件名相关的宏。

  • #endif:表示“结束条件编译”。它标志着 #ifndef 块的结束。

#include <filename.h> 和 #include "filename.h" 有什么区别?

这两种指令都是用于包含头文件,但它们在搜索头文件时的路径不同:

  • #include <filename.h>:指示编译器在系统标准库路径中搜索头文件。这些路径通常是编译器安装时配置的,用户一般不需要修改。

  • #include "filename.h":指示编译器首先在当前源文件所在的目录中搜索头文件,如果没有找到,再在系统标准库路径中搜索。这种搜索方式更灵活,通常用于包含用户自定义的头文件。

C/C++程序编译链接过程?分别完成了什么事情?

  1. 预处理

    • 处理预处理指令,如 #include#define 等。

    • 删除注释和多余空格。

    • 生成预处理后的文件(通常以 .i.pre 为后缀)。

  2. 编译

    • 将预处理后的文件编译成汇编代码或目标代码。

    • 生成汇编文件(以 .s 为后缀)或目标文件(以 .o.obj 为后缀)。

  3. 汇编

    • 将汇编代码转换成机器代码。

    • 生成目标文件(以 .o.obj 为后缀)。

  4. 链接

    • 将多个目标文件链接成一个可执行文件。

    • 解决外部符号引用,生成可执行文件(以 .exe 为后缀)。

 宏的优缺点?C++中会使用什么技术去替代宏?

宏的优点:

  • 灵活性:宏可以在编译时展开,生成所需的代码。

  • 性能:宏展开后的代码在编译时生成,运行时不需要额外的函数调用开销。

    宏的缺点:

  • 调试困难:宏展开后的代码可能会使调试变得复杂。

  • 类型安全:宏不进行类型检查,可能导致类型错误。

  • 作用域问题(命名冲突):宏在预处理阶段展开,可能导致意外的命名冲突。

在C++中

  • 内联函数:使用 inline 关键字声明的函数,编译器会在调用处展开函数体,类似于宏。

  • 模板:提供了一种泛型编程的方式,可以在编译时生成所需的代码,同时保持类型安全。

关键字

volatile

  • 作用:用于声明一个变量的值可能会被程序之外的因素改变,例如硬件、操作系统或其他线程。这个关键字告诉编译器不要对这个变量进行优化,每次使用这个变量时都必须从其实际位置读取。

    volatile int sensorValue;

extern

  • 作用:用于声明一个变量或函数是在另一个文件中定义的,这样可以在当前文件中访问其他文件中定义的全局变量或函数。

    extern int globalVar; // 声明在其他文件中定义的全局变量

 

static

  • 作用:用于声明一个变量或函数的作用域仅限于声明它的文件或函数体内部。对于全局变量,static会限制其链接属性为内部链接(internal linkage),使其只能在定义它的文件中访问。

    static int localStaticVar; // 只能在定义它的函数内部访问

const

  • 作用:用于声明一个变量的值在初始化后不能被改变,即常量。const可以用于变量、函数参数和函数返回值,表示数据的不可变性。

    const int MAX_VALUE = 100; // 不能改变MAX_VALUE的值

 

typedef

  • 作用:用于为一个数据类型创建一个新的别名,简化复杂类型的声明,提高代码的可读性。

    typedef unsigned int uint;
    uint var = 10; // 使用新的别名uint

sizeof

  • 作用:用于计算一个表达式、类型或变量的大小(以字节为单位)。

    int a = 10;
    printf("Size of a: %zu\n", sizeof(a)); // 输出变量a的大小

 

什么是指针?什么是数组?数组和指针的联系和区别?

指针

  • 指针是一个变量,它的值是另一个变量的内存地址。

  • 指针可以用来间接访问和操作内存中的数据。

数组

  • 数组是存储在连续内存空间中的相同类型元素的集合。

  • 数组名实际上是指向数组第一个元素的指针。

数组和指针的联系

  • 数组名可以作为指针使用,它指向数组的第一个元素。

  • 通过指针运算可以访问数组中的元素。

数组和指针的区别

  • 数组是一个具体的数据结构,而指针是一个变量,用于存储地址。

  • 数组的大小是固定的,而指针可以指向任何类型的数据。

  • 数组有长度限制,而指针可以指向更大的内存区域。

 

什么是指针数组?什么是数组指针?

指针数组

  • 指针数组是一个数组,其元素都是指针。

  • 指针数组的每个元素都指向一个变量或一个数据结构。

数组指针

  • 数组指针是一个指针,它指向一个数组。

  • 通过数组指针可以访问数组中的所有元素。

 

&数组名和数组名分别代表的意义?

  • &数组名:表示数组的地址,即数组第一个元素的地址。

  • 数组名:表示数组第一个元素的地址,也可以表示整个数组。

什么是二维数组?二级指针?

二维数组

  • 二维数组是一个数组,其元素是数组,通常用于表示矩阵或表格。

  • 二维数组可以看作是数组的数组。

二级指针

  • 二级指针是一个指针,它指向一个指针。

  • 二级指针可以用来间接访问指针所指向的内存地址。

什么是函数指针?

  • 函数指针是一个指针,它指向一个函数。

  • 通过函数指针可以调用函数,实现函数的动态调用和回调机制。

相关文章:

c语言知识整理

一 数据的存储 对于整形的存储 无论是正负在存储中都是使用补码进行存储的 那个一个数字的补码在转换正负时不同的 对于存储中 首位一定是符号位 如果是0 那么是正数 如果是1 那么是负数 &#xff08;32位 除符号位 缺少的位数使用0补齐&#xff09; 如果是正数 …...

算法习题-力扣446周赛题解

算法可以调度思维&#xff0c;让程序员的思维发散&#xff0c;找到更好的解决方案。 第一题&#xff1a;执行指令后的得分 题目&#xff1a; 给你两个数组&#xff1a;instructions 和 values&#xff0c;数组的长度均为 n。你需要根据以下规则模拟一个过程&#xff1a; 从下标…...

基于共享上下文和自主协作的 RD Agent 生态系统

在llmangentmcp这个框架中&#xff1a; LLM&#xff1a; 依然是智能体的“大脑”&#xff0c;赋予它们理解、推理、生成和规划的能力&#xff0c;并且也用于处理和利用共享上下文。Agent&#xff1a; 具备特定 R&D 职能的自主单元&#xff0c;它们感知共享上下文&#xff0…...

Operating System 实验五 进程管理编程实验

实验目标: 写个多线程的程序,重现竞争条件,并通过信号量或者互斥量,解决临界区问题某工厂有两个生产车间和一个装配车间,两个生产车间分别生产A、B两种零件,装配车间的任务是把A、B两种零件组装成产品。两个生产车间每生产一个零件后,都要分别把它们送到装配车间的货架F…...

Deep Reinforcement learning for real autonomous mobile robot navigation

​​​​​​​https://www.youtube.com/watch?vKyA2uTIQfxw AI Learns to Park - Deep Reinforcement Learning https://www.youtube.com/watch?vVMp6pq6_QjI Q Learning simply explained | SARSA and Q-Learning Explanation https://www.youtube.com/watch?vMI8ByADM…...

计算机网络 | 应用层(4)--DNS:因特网的目录服务

&#x1f493;个人主页&#xff1a;mooridy-CSDN博客 &#x1f493;文章专栏&#xff1a;《计算机网络&#xff1a;自定向下方法》 大纲式阅读笔记_mooridy的博客-CSDN博客 &#x1f339;关注我&#xff0c;和我一起学习更多计算机网络的知识 &#x1f51d;&#x1f51d; 目录 …...

WPF核心技术解析与使用示例

WPF核心技术解析与使用示例 一、依赖属性(Dependency Property)详解 1. 依赖属性基础 ​​核心概念​​: 依赖属性是WPF实现数据绑定、样式、动画等特性的基础通过属性系统实现高效的内存管理和值继承​​标准定义模式​​: public class MyControl : Control {// 1. 定义…...

JVM运行机制全景图:从源码到执行的全过程

JVM运行机制全景图:从源码到执行的全过程 引言:你真的了解 Java 是怎么跑起来的吗? 许多开发者写完 Java 代码之后,就交给编译器和运行时去“神奇”地执行了。但你有没有想过,一段 .java 文件是如何一步步变成可运行的程序?今天,我们就从 源码 ➝ 字节码 ➝ 类加载 ➝…...

使用 AFL++ 对 IoT 二进制文件进行模糊测试 - 第二部分

在上一部分中,我们研究了如何使用 AFL++ 对简单的物联网二进制文件进行模糊测试。这些程序接受来自文件的输入,并且易于模糊测试。 在本文中,我们将研究套接字二进制文件。使用套接字进行网络通信的模糊测试二进制文件与使用基于文件 I/O 的模糊测试二进制文件不同。Vanill…...

在华为云平台上使用 MQTT 协议:构建高效可靠的物联网通信

&#x1f310; 在华为云平台上使用 MQTT 协议&#xff1a;构建高效可靠的物联网通信 随着物联网&#xff08;IoT&#xff09;技术的发展&#xff0c;设备间的高效通信变得尤为重要。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;作为一种轻量级的消息传输…...

基于STM32的物流搬运机器人

功能&#xff1a;智能循迹、定距夹取、颜色切换、自动跟随、自动避障、声音夹取、蓝牙遥控、手柄遥控、颜色识别夹取、循迹避障、循迹定距…… 包含内容&#xff1a;完整源码、使用手册、原理图、视频演示、PPT、论文参考、其余资料 资料只私聊...

H.264/AVC标准主流开源编解码器编译说明

An artisan must first sharpen his tools if he is to do his work well. 工欲善其事,必先利其器. 前言 想研究和学习H.264/AVC视频编解码标准的入门的伙伴们,不论是学术研究还是工程应用都离不开对源码的分析,因此首要工作是对各类编解码器进行编译,本文针对主流的一些符…...

Xilinx FPGA支持的FLASH型号汇总

以博主这些年的FPGA开发使用经验来看&#xff0c;FPGA开发的主流还是以Xilinx FPGA为主&#xff0c;贸易战关税战打了这么多年&#xff0c;我们做研发的也不可避免的要涉及一些国产替代的工作&#xff1b;这里把Xilinx FPGA官方支持的各类&#xff08;国产和非国产&#xff09;…...

【C++ 类和数据抽象】消息处理示例(1):从设计模式到实战应用

目录 一、数据抽象概述 二、消息处理的核心概念 2.1 什么是消息处理&#xff1f; 2.2 消息处理的核心目标 三、基于设计模式的消息处理实现 3.1 观察者模式&#xff08;Observer Pattern&#xff09; 3.2 命令模式&#xff08;Command Pattern&#xff09; 四、实战场景…...

LiveCharts.WPF图表模块封装

WPF LiveCharts.WPF 封装实现 下面是一个完整的 WPF LiveCharts.WPF 封装实现,提供了常用图表的简单使用方式,并支持数据绑定和更新。 一、LiveCharts.WPF 封装类 1. 图表基类 (ChartBase.cs) using LiveCharts; using LiveCharts.Wpf; using System.Collections.Generic;…...

微信小程序,基于uni-app的轮播图制作,轮播图本地文件图片预览

完整代码 <template><swiper class"banner" indicator-dots circular :autoplay"false"><swiper-item v-for "item in picture" :key"item.id"><view><image tap"onPreviewImage(item.img)" :…...

【QQmusic】复习笔记第四章分点讲解

4.1 音乐加载 功能概述 该部分实现了从本地磁盘加载音乐文件到程序中&#xff0c;并在界面上显示的功能。通过QFileDialog类创建文件选择对话框&#xff0c;用户可选择多个音乐文件&#xff0c;程序筛选出有效音频文件后&#xff0c;交由MusicList类管理&#xff0c;并更新到…...

设置右键打开VSCode

在日常的开发工作中&#xff0c;VSCode 是一款非常受欢迎的代码编辑器。为了更加便捷地使用它&#xff0c;我们可以将 VSCode 添加到右键菜单中&#xff0c;这样只需右键点击文件或文件夹&#xff0c;就能快速用 VSCode 打开&#xff0c;极大地提高工作效率。下面我就来介绍一下…...

数据结构和算法(八)--2-3查找树

目录 一、平衡树 1、2-3查找树 1.1、定义 1.2、查找 1.3、插入 1.3.1、向2-结点中插入新键 1.3.2、向一棵只含有一个3-结点的树中插入新键 1.3.3、向一个父结点为2-结点的3-结点中插入新键 1.3.4、向一个父结点为3-结点的3-结点中插入新键 1.3.5、分解根结点 1.4、2…...

JSAPI2.4——正则表达式

一、语法 const str 一二三四五六七八九十 //判断内容 const reg /二/ //判断条件 console.log(reg.test(str)); //检查 二、test与exec方法的区别 test方法&#xff1a;用于判断是否符合规则的字符串&#xff0c;返回值是布尔值 exec方法&…...

FPGA 100G UDP纯逻辑协议栈

随着器件等级的升高&#xff0c;高速serdes的线速率也随之提高&#xff0c;RFSOC 4x最大可支持100G&#xff0c;主流方案为RDMA方案&#xff0c;该方案相对比较复杂&#xff0c;除了需要负责逻辑端的开发&#xff0c;还需操作系统中开发RDMA的驱动&#xff0c;对于对丢包不那么…...

分享一个可以批量巡检GET和POST接口的Shell脚本

一、场景痛点与需求分析 在分布式系统架构中&#xff0c;服务接口的可用性和稳定性直接影响业务连续性。当面临以下场景时&#xff0c;需批量巡检GET和POST接口&#xff1a; 上线验证&#xff1a;新版本发布后批量验证核心接口 故障恢复&#xff1a;异常数据修复后的批量重试…...

机器学习之一:机械式学习

正如人们有各种各样的学习方法一样&#xff0c;机器学习也有多种学习方法。若按学习时所用的方法进行分类&#xff0c;则机器学习可分为机械式学习、指导式学习、示例学习、类比学习、解释学习等。这是温斯顿在1977年提出的一种分类方法。 有关机器学习的基本概念&#xff0c;…...

区分PROJECT_SOURCE_DIR, CMAKE_SOURCE_DIR,CMAKE_CURRENT_SOURCE_DIR

目录 示例工程 PROJECT_SOURCE_DIR的行为 CMAKE_SOURCE_DIR的行为 CMAKE_CURRENT_SOURCE_DIR 示例工程 根目录 |-----CMakeLists.txt |-----sub1 |--------CMakeLists.txt |-----sub2 |--------CMakeLists.txt 根目录下的CMakeList.txt: project(main)message("main …...

Python循环结构深度解析与高效应用实践

引言&#xff1a;循环结构在编程中的核心地位 循环结构作为程序设计的三大基本结构之一&#xff0c;在Python中通过while和for-in两种循环机制实现迭代操作。本文将从底层原理到高级应用&#xff0c;全面剖析Python循环机制的使用技巧与优化策略&#xff0c;助您掌握高效迭代的…...

25【干货】在Arcgis中根据字段属性重新排序并自动编号的方法(二)

上一篇关于属性表自动编号的文章因为涉及到代码&#xff08;【干货】在Arcgis中根据字段属性重新排序并自动编号的方法&#xff08;一&#xff09;&#xff09;&#xff0c;担心大家有些东西确实不熟悉&#xff0c;今天就更新一篇不需要代码也能达到这个目的的方法。主要的思路…...

SinSR模型剪枝实验报告

SinSR模型剪枝实验报告 实验概述 我成功地对SinSR模型进行了L1范式剪枝&#xff0c;剪枝比例为50%。通过分析剪枝前后的模型参数和性能&#xff0c;我们得出了以下结论。 剪枝实现方法 创建专用的main_prune.py脚本&#xff0c;用于剪枝训练。创建quick_prune.py脚本&#…...

IT社团分析预测项目(pandas、numpy、sklearn)

IT社团人数的增长陷入迟滞&#xff0c;同时不同目标任务和不同经营模式的社团更是层出不穷。在面临内忧外患的情况下&#xff0c;本社团希望结合社团行业现状&#xff0c;分析同学和出勤的数据&#xff0c;挖据数据中的信息&#xff0c;通过对人数流失进行预测寻找到相应的对策…...

C语言中位段的应用

一&#xff0c;位段的主要应用场景 硬件寄存器操作 嵌入式开发中&#xff0c;硬件寄存器通常以位为单位控制设备状态。位段可直接映射到寄存器&#xff0c;简化位操作&#xff1a; typedef struct {unsigned int enable : 1; // 使能位unsigned int mode : 3; // 模式选择&…...

【Linux网络#1】:网络基础知识

1、网络发展 在计算机发展历程中&#xff0c;经历过下面四个阶段&#xff1a; 1.独立模式 独立模式&#xff1a;计算机之间相互独立&#xff0c;每台计算机做自己的事情&#xff0c;彼此之间没有直接信息传递。如果两台计算机需要通信就需要将当前计算机的数据通过某种方式拷贝…...

基于物联网的园林防火监测系统

标题:基于物联网的园林防火监测系统 内容:1.摘要 随着全球气候变化和人类活动影响&#xff0c;园林火灾发生频率呈上升趋势&#xff0c;给生态环境和人类生命财产造成巨大损失。为有效预防和应对园林火灾&#xff0c;本文提出基于物联网的园林防火监测系统。该系统综合运用传感…...

华为云loT物联网介绍与使用

&#x1f310; 华为云 IoT 物联网平台详解&#xff1a;构建万物互联的智能底座 随着万物互联时代的到来&#xff0c;物联网&#xff08;IoT&#xff09;已成为推动数字化转型的关键技术之一。华为云 IoT 平台&#xff08;IoT Device Access&#xff09;作为华为云的核心服务之…...

Redis 数据类型全览:特性、场景与操作实例

Redis 是一款开源的内存数据库&#xff0c;支持多种数据类型&#xff0c;以下是对常见 Redis 数据类型的介绍&#xff1a; 1. String&#xff08;字符串&#xff09; 描述 字符串是 Redis 里最基础的数据类型&#xff0c;其值可以是简单的字符串、数字&#xff0c;甚至是二进…...

Qt动态库信号崩溃问题解决方案

在Qt中&#xff0c;当动态库向主程序发送信号导致崩溃时&#xff0c;通常涉及线程安全或对象生命周期问题。以下是逐步解决方案&#xff1a; 1. 检查线程上下文 问题&#xff1a;动态库所在的线程与主程序线程不同&#xff0c;跨线程信号未正确处理。解决方案&#xff1a; 显式…...

Go设计模式-观察者模式

简介 在软件开发中&#xff0c;我们常常会遇到这样的场景&#xff1a;一个对象的状态变化需要通知到多个其他对象&#xff0c;让它们做出相应的反应。观察者模式&#xff08;Observer Pattern&#xff09;就是解决这类问题的一种设计模式。在 Go 语言中&#xff0c;由于其简洁…...

《TCP/IP详解 卷1:协议》之第七、八章:Ping Traceroute

目录 一、ICMP回显请求和回显应答 1、ICMP回显请求 2、ICMP回显应答 二、ARP高速缓存 三、IP记录路由选项&#xff08;Record Route&#xff0c;RR&#xff09; 1、记录路由选项的工作过程 2、RR 选项的 IP 头部格式 2.1、RR 请求 2.2、RR响应 四、ping 的去返路径 五…...

Unity任务系统笔记

数据结构设计 任务基类包括的字段&#xff1a; string 任务内容&#xff1b; Transform 任务目的地&#xff1b; MyCharacter 任务开启后要更新对话的NPC&#xff1b; MyTalkData 任务开启后相关NPC要说的对话数据&#xff1b; 共同方法&#xff1a;开启任务、完成任务。…...

Three.js + React 实战系列-3D 个人主页:构建 Hero 场景组件(项目核心)✨

在本节中&#xff0c;我们将完成整个 3D 主业项目中最核心的组件 —— Hero.jsx。 这个组件作为首页的主视觉部分&#xff0c;整合了 3D 模型、动画相机、交互按钮与自适应布局&#xff0c;构建出一个立体、酷炫、可交互的主场景。 前置准备&#xff1a; ✅安装依赖&#xff…...

线程池(二):深入剖析synchronized关键字的底层原理

线程池&#xff08;二&#xff09;&#xff1a;深入剖析synchronized关键字的底层原理 线程池&#xff08;二&#xff09;&#xff1a;深入剖析synchronized关键字的底层原理一、基本使用1.1 修饰实例方法1.2 修饰静态方法1.3 修饰代码块 二、Monitor2.1 Monitor的概念2.2 Moni…...

网络原理 - 9

目录 数据链路层 以太网 以太网帧格式 MAC 地址 DNS&#xff08;Domain Name System&#xff09; 完&#xff01; 数据链路层 这里的内容也是简单了解&#xff0c;除非是做交换机开发&#xff0c;一般程序员不需要涉及~~ 以太网 ”以太网“不是一种具体的网络&#xf…...

springboot入门-业务逻辑核心service层

在 Spring Boot 中&#xff0c;Service 层是业务逻辑的核心&#xff0c;负责协调数据访问层&#xff08;Repository 或 Mapper&#xff09;和控制器层&#xff08;Controller&#xff09;&#xff0c;处理业务规则、事务管理以及数据转换。以下是 Service 层的详细说明、常用注…...

在RHEL 10上安装和配置TFTP服务器(不使用xinetd)

RHEL10已经废弃xinetd&#xff0c;使用下面的方式安装配置TFTP服务器。 1. 安装TFTP服务器和客户端 sudo dnf install tftp-server tftp -y 2. 配置TFTP服务器 创建TFTP根目录并设置权限 sudo mkdir -p /var/lib/tftpboot sudo chmod -R 777 /var/lib/tftpboot sudo chown -R…...

AIGC在游戏开发中的革命:自动化生成3A级游戏内容

一、智能游戏开发架构 1.1 传统开发痛点与AIGC创新 开发环节 传统痛点 AIGC解决方案 角色原画设计 美术资源产能瓶颈 文生图3D模型自动生成 场景搭建 重复劳动占比高 程序化生成风格迁移 NPC行为设计 模式化严重 强化学习驱动智能行为 任务系统 剧情线性缺乏变化 动态剧情生成系…...

ChatGPT、deepseek、豆包、Kimi、通义千问、腾讯元宝、文心一言、智谱清言代码能力对比

均使用测试时的最强模型 均是一次对话,对话内容一样 均开启深度思考 能联网的都联网了&#xff0c;但是作用不大&#xff0c;因为蓝桥杯刚考完&#xff0c;洛谷题目刚上传没多久 问题一测试了两遍 从问题三开始不再测试智谱清言&#xff08;它思考时间太长了&#xff0c;前两个…...

Linux扩展

目录 扩展 查找如何进行后台运行程序的指令 使用 & 符号 使用 nohup 命令 使用 screen 或 tmux find命令 基本语法 常用选项 grep 命令 基本语法 常用选项 如何使用 vim 直接定位到错误行 1. 使用 :make 和 :copen 2. 使用 :lineno 定位 3. 通过 :grep 或 :…...

Java Hotspot VM researcher

** therefore, careful design and understanding of modules are essential to fully reap the performance benefits. **...

java—基础

目标 ├── 第一阶段&#xff1a;内容清单 │ └── 目标&#xff1a;建立编程思想 ├── 第二阶段&#xff1a;内容清单 │ └── 目标&#xff1a;提升编程能力 └── 第三阶段&#xff1a;内容清单└── 目标&#xff1a;分析需求&#xff0c;代码实现能力以下是根…...

【OpenCV】第二章——图像处理基础

图像处理基础学习笔记 本章节详细介绍了图像处理的基础内容&#xff0c;包括图像的读取、显示、保存&#xff0c;基本属性的查看&#xff0c;图像的变换与操作&#xff0c;以及常用的图像处理方法。 目录 图像的读取与显示图像基本属性图像的灰度化与二值化图像的色彩空间转换…...

在WSL2+Ubuntu22.04中通过conda pack导出一个conda环境包,然后尝试导入该环境包

如何导出一个离线conda环境&#xff1f;有两种方式&#xff0c;一种是导出env.yml即环境配置&#xff0c;一种是通过conda pack导出为一个环境包&#xff0c;前者只是导出配置&#xff08;包括包名、版本等&#xff09;&#xff0c;而后者是直接将环境中所有的内容打包&#xf…...

C++:类和对象(上)---镜中万象:C++类的抽象之境与对象的具体之象

类&#xff08;Class&#xff09;是一种用户自定义的数据类型。 文章目录&#xff1a; 前言一、面向过程和面向对象初步认识 二、类的引入 三、类的定义 3.1类是什么&#xff1f; 3.2类的定义 四、类的访问限定符和封装 4.1类的访问限定符 4.2封装 五、类和对象的关系 六、类对…...