深入理解C语言(2):字符、字符串与内存函数

标头风景图片


  • 文章主题:字符、字符串与内存函数🌏
  • 所属专栏:深入理解C语言📔
  • 作者简介:更新有关深入理解C语言知识的博主一枚,记录分享自己对C语言的深入解读。😆
  • 个人主页:[₽]的个人主页🏄🌊

前言

字符函数属于库文件ctype.h,而字符串与内存函数属于库文件string.h,那么它们分别具有什么样的功能呢?我们又能否在C语言中对其进行模拟呢?下面是我有关这些函数的介绍以及对其中的一些函数进行的模拟。

函数介绍

一. 字符函数

1. 字符分类函数

函数声明返回真的参数条件
int iscntrl ( int c );任何控制字符
int isspace ( int c );’ ‘(空白字符/空格), ‘\f’(换页), ‘\n’(换行), ‘\t’(制表符), ‘\v’(垂直制表符) , ‘\r’(回车)
int isdigit ( int c );十进制数字 ‘0’-‘9’
int isxdigit ( int c );十六进制数字,包括所有十进制数字,小写字母 ‘a’-‘f’,大写字母 ‘A’-‘F’
int islower ( int c );小写字母 ‘a’-‘z’
int isupper ( int c );大写字母 ‘A’-‘Z’
int isalpha ( int c );字母 ‘A’-‘Z’ ‘a’-‘z’
int isalnum ( int c );字母 ‘A’-‘Z’ ‘a’-‘z’ ‘0’-‘9’
int ispunct ( int c );标点符号,任何不属于数字或者字母的图形字符(可打印)
int isgraph ( int c );任何图形字符
int isprint ( int c );任何可打印字符,包括图形字符和空白字符

2. 字符转换函数

函数效果
int tolower ( int c );大写字母转成小写字母返回,小写字母仍以小写字母返回
int toupper ( int c );小写字母转成大写字母返回,大写字母仍以大写字母返回

二. 字符串函数

1. 求字符串长度

strlen
size_t strlen ( const void* str );
  • 字符串以'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数(不包含'\0')。
  • 参数指向的字符串必须要以'\0'结束。
  • 注意函数的返回值为size_t,是无符号的。(易错
  • 学会strlen函数的模拟实现。
例:
/* strlen example */
#include <stdio.h>
#include <string.h>int main ()
{char szInput[256];printf ("Enter a sentence: ");gets (szInput);printf ("The sentence entered is %u characters long.\n",(unsigned)strlen(szInput));return 0;
}
输出:
Enter sentence: just testing
The sentence entered is 12 characters long.

2. 长度不受限制的字符串函数

strcpy
char* strlen ( char* destination, const char* source );
  • source指向的 C 字符串复制到destination指向的数组中,包括'\0'(并在该点处停止)。

  • 为避免溢出,destination指向的数组的大小应足够长,以包含与source相同的 C 字符串(包括'\0'),并且不应在内存中与source重叠。

例:
/* strcpy example */
#include <stdio.h>
#include <string.h>int main ()
{char str1[]="Sample string";char str2[40];char str3[40];strcpy (str2,str1);strcpy (str3,"copy successful");printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);return 0;
}
输出:
str1: Sample string
str2: Sample string
str3: copy successful

strcat
char* strcat ( char* destination, const char* source );
  • source字符串的内容衔接到destination字符串之后。destination 中的'\0'被 source 的第一个字符覆盖,并且'\0'会包含在由destination中两者的串联形成的新字符串的末尾。
例:
/* strcpy example */
#include <stdio.h>
#include <string.h>int main ()
{char str1[]="Sample string";char str2[40];char str3[40];strcpy (str2,str1);strcpy (str3,"copy successful");printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);return 0;
}
输出:
these strings are concatenated.

strcmp
int strcmp ( const char* str1, const char* str2 );
  • 将 C 字符串 str1 与 C 字符串 str2 进行比较。

  • 此函数开始相同位置对应比较每个字符串的字符。如果它们彼此相等,则继续往下比较,直到字符不同或达到'\0'为止。

例:
/* strcmp example */
#include <stdio.h>
#include <string.h>int main ()
{char key[] = "apple";char buffer[80];do {printf ("Guess my favorite fruit? ");fflush (stdout);scanf ("%79s",buffer);} while (strcmp (key,buffer) != 0);puts ("Correct answer!");return 0;
}
输出:
Guess my favourite fruit? orange
Guess my favourite fruit? apple
Correct answer!

3. 长度受限制的字符串函数

strncpy
char* strncpy ( char* destination, const char* source, size_t num );
  • source的前 num 个字符复制到destination。如果在复制 num 个字符之前找到source C 字符串的末尾(由'\0'表示),则destination将用0(即0所代表的'\0')填充,直到总共写入 num 个字符。

  • 如果source的长度大于 num,则不会在目标末尾隐式追加'\0'。因此,在这种情况下,destination不一定能被视为以'\0'结尾的 C 字符串(这样读取它会溢出)。

  • destinationsource不得重叠(重叠时更安全的替代方案为Memmove)。

例:
/* strncpy example */
#include <stdio.h>
#include <string.h>int main ()
{char str1[]= "To be or not to be";char str2[40];char str3[40];/* copy to sized buffer (overflow safe): */strncpy ( str2, str1, sizeof(str2) );/* partial copy (only 5 chars): */strncpy ( str3, str2, 5 );str3[5] = '\0';   /* null character manually added */puts (str1);puts (str2);puts (str3);return 0;
}
输出:
To be or not to be
To be or not to be
To be 

strncat
char* strncat ( char* destination, const char* source, size_t num );
  • source的前 num 个字符衔接到destination之后,外加一个'\0'

  • 如果source中 C 字符串的长度小于 num,则仅复制'\0'之前的内容。

例:
/* strncat example */
#include <stdio.h>
#include <string.h>int main ()
{char str1[20];char str2[20];strcpy (str1,"To be ");strcpy (str2,"or not to be");strncat (str1, str2, 6);puts (str1);return 0;
}
输出:
To be or not

strncmp
int strncmp ( const char* str1, const char* str2, size_t num );
  • 将 C 字符串 str1 的字符数与 C 字符串 str2 的字符数进行比较。
  • 此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续往下比较,直到字符不同或达到'\0',或直到两个字符串中的num个字符相同。
例:
/* strncmp example */
#include <stdio.h>
#include <string.h>int main ()
{char str[][5] = { "R2D2" , "C3PO" , "R2A6" };int n;puts ("Looking for R2 astromech droids...");for (n=0 ; n<3 ; n++)if (strncmp (str[n],"R2xx",2) == 0){printf ("found %s\n",str[n]);}return 0;
}
输出:
Looking for R2 astromech droids...
found R2D2
found R2A6

4. 其他

strstr
const char* strstr ( const char* str1, const char* str2 );
  • 返回指向 str1 中第一次出现的 str2 的指针,如果 str2 不是 str1 的一部分,则返回一个NULL指针。

  • 匹配过程不包括'\0',但匹配会停止到此为止。

例:
/* strstr example */
#include <stdio.h>
#include <string.h>int main ()
{char str[] ="This is a simple string";char * pch;pch = strstr (str,"simple");if (pch != NULL)strncpy (pch,"sample",6);puts (str);return 0;
}
输出:
This is a sample string

strtok
char* strtok ( char* str, const char* delimiters );
  • 对此函数的一系列调用将 str 拆分为标记,这些标记是由分隔符中的任何字符分隔的连续字符序列。

  • 在第一次调用时,该函数需要一个 C 字符串作为 str 的参数,str 的第一个字符用作扫描delimiters的起始位置。在后续调用中,该函数需要一个NULL指针,并使用最后一个标记末尾之后的位置作为扫描的新起始位置。

  • 为了确定标记的开头和结尾,该函数首先从起始位置扫描delimiters中未包含的第一个字符(该字符成为标记的开头)。然后从标记的开头开始扫描分隔符中包含的第一个字符,该字符成为标记的末尾。如果找到'\0',扫描也会停止。

  • delimiters的这一末尾会自动替换为'\0',并且delimiters的开头由函数返回。

  • 在对 strtok 的调用中找到 str 的'\0'后,对此函数的所有后续调用(以NULL指针作为第一个参数)将返回 null 指针。

  • 找到最后一个delimiters的点由要在下一次调用中使用的函数在内部保存(不需要特定的库实现来避免数据争用)。

例:
/* strtok example */
#include <stdio.h>
#include <string.h>int main ()
{char str[] ="- This, a sample string.";char * pch;printf ("Splitting string \"%s\" into tokens:\n",str);pch = strtok (str," ,.-");while (pch != NULL){printf ("%s\n",pch);pch = strtok (NULL, " ,.-");}return 0;
}
输出:
Splitting string "- This, a sample string." into tokens:
This
a
sample
string

strerror
char* strerror ( int errnum );
  • 解释 errnum 的值,生成一个字符串,其中包含一条描述错误条件的消息,就像由库的函数设置为 errno 一样。

  • 返回的指针指向静态分配的字符串,程序不得修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)。

  • strerror 生成的错误字符串可能特定于每个系统和库实现。

例:
/* strerror example : error list */
#include <stdio.h>
#include <string.h>
#include <errno.h>int main ()
{FILE * pFile;pFile = fopen ("unexist.ent","r");if (pFile == NULL)printf ("Error opening file unexist.ent: %s\n",strerror(errno));return 0;
}
输出:
Error opening file unexist.ent: No such file or directory

perror(与字符串函数strerror效果相似的打印函数,属于<stdio.h>(标准输入输出库))
void perror ( const char* str );
  • 将 errno 的值解释为错误消息,并将其打印到 stderr(标准错误输出流,通常是控制台),可以选择在其前面加上 str 中指定的自定义消息。

  • errno 是一个整数变量,其值描述调用库函数生成的错误条件或诊断信息(C 标准库的任何函数都可以为 errno 设置值,即使此引用中未明确指定,即使没有发生错误),有关详细信息,请参阅 errno。

  • perror 生成的错误消息与平台相关。

  • 如果参数 str 不是 null 指针,则打印 str,后跟冒号 : 和空格。然后,无论 str 是否为 null 指针,都会打印生成的错误说明,后跟换行符 '\n'

  • perror 应该在产生错误后立即调用,否则可能会被调用其他函数覆盖。

例:
/* perror example */
#include <stdio.h>int main ()
{FILE * pFile;pFile=fopen ("unexist.ent","rb");if (pFile==NULL)perror ("The following error occurred");elsefclose (pFile);return 0;
}
输出:
The following error occurred: No such file or directory

三. 内存函数

memcpy

void* memcpy ( void* destination, const void* source, size_t num );
  • 将 num 字节的值从source指向的位置直接复制到destination指向的内存块。

  • source指针和destination指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本。

  • 该函数不检查source中的任何'\0'——它始终准确复制 num 个字节。

  • 为避免溢出,destination参数和source参数指向的数组的大小应至少为 num 个字节,并且不应重叠(对于重叠的内存块,memmove 是一种更安全的方法)

例:
/* memcpy example */
#include <stdio.h>
#include <string.h>struct {char name[40];int age;
} person, person_copy;int main ()
{char myname[] = "Pierre de Fermat";/* using memcpy to copy string: */memcpy ( person.name, myname, strlen(myname)+1 );person.age = 46;/* using memcpy to copy structure: */memcpy ( &person_copy, &person, sizeof(person) );printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );return 0;
}
输出:
person_copy: Pierre de Fermat, 46

memmove

void* memmove ( void* destination, const void* source, size_t num );
  • 将 num 字节的值从source指向的位置复制到destination指向的内存块。复制就像使用中间缓冲区一样进行,允许destinationsource重叠。

  • source指针和destination指针所指向的对象的基础类型与此函数无关;结果是数据的二进制副本。

  • 该函数不检查source中的任何'\0'——它始终准确复制 num 个字节。

  • 为避免溢出,destination参数和source参数所指向的数组的大小应至少为 num 个字节。

例:
/* memmove example */
#include <stdio.h>
#include <string.h>int main ()
{char str[] = "memmove can be very useful......";memmove (str+20,str+15,11);puts (str);return 0;
}
输出:
memmove can be very very useful.

memcmp

int memcmp ( const void* ptr1, const void* ptr2, size_t num );
  • 将 ptr1 指向的内存块的第一个字节与 ptr2 指向的第一个 num 字节进行比较,如果它们都匹配,则返回零,或者返回一个不同于零的值,如果它们不匹配,则表示哪个值更大。 请注意,与 strcmp 不同,该函数在找到 null 字符后不会停止比较。
例:
/* memcmp example */
#include <stdio.h>
#include <string.h>int main ()
{char buffer1[] = "DWgaOtP12df0";char buffer2[] = "DWGAOTP12DF0";int n;n=memcmp ( buffer1, buffer2, sizeof(buffer1) );if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);return 0;
}
输出:
'DWgaOtP12df0' is greater than 'DWGAOTP12DF0'.

函数模拟实现

字符串函数

my_strlen

#include <stdio.h>
#include <assert.h>
size_t my_strlen(const char* str)
{assert(str);int i = 0;while (str[i])//计数器,到'\0'时退出循环,停止计数i++;return i;
}
int main()
{char str[100] = { 0 };scanf("%s", str);printf("lens: %zd", my_strlen(str));return 0;
}

my_strcpy

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{assert(dest && src);int i = 0;while (dest[i] = src[i++])//复制到'\0'时,条件判断为0,跳出while循环,复制动作停止;return dest;
}
int main()
{char str1[100] = { 0 }, str2[100] = { 0 };scanf("%s%s", str1, str2);printf("cpyed: %s", my_strcpy(str1, str2));return 0;
}

my_strcmp

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2)
{assert(str1 && str2);int i = 0;while (str1[i] || str2[i])//c1=c2且不是均为'\0'时进入循环{if (str1[i] - str2[i])//如果对应字符不相同的话,则返回它们的差值//(可保证c1>c2时返回>0;c1<c2时返回<0)return str1[i] - str2[i];i++;}return 0;//c1=c2且均为'\0'则终止循环,两字符串相同返回0
}
int main()
{char str1[100] = { 0 }, str2[100] = { 0 };scanf("%s%s", str1, str2);printf("%d", my_strcmp(str1, str2));return 0;
}

my_strcat

#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{assert(dest && src);char* cat = dest + strlen(dest), i = 0;//定义及赋值衔接处的地址变量while (cat[i] = src[i++])//如果没到'\0'就会继续赋值;return dest;//返回赋值后的字符串地址
}
int main()
{char str[20] = { 0 };strcpy(str, "Hello ");my_strcat(str, "bit!");puts(str);return 0;
}

my_strstr

#include <stdio.h>
#include <assert.h>
const char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);if (str2[0] == '\0')return str1;const char* cp = str1;//记录原字符串中的子字符串比较位置const char* s1;//str1单位字符比较指针const char* s2;//str2单位字符比较指针while (*cp){s1 = cp;s2 = str2;while (*s1&&*s2&&*s1 == *s2){s1++;s2++;}if (*s2 == '\0')return cp;cp++;}return NULL;
}
int main()
{char str1[] = "abbbcdef", str2[] = "bcd";if (my_strstr(str1, str2) == NULL)printf("NULL");elseprintf("%s", my_strstr(str1, str2));return 0;
}

my_strncpy

#include <stdio.h>
#include <string.h>
#include <assert.h>
char* strncpy(char* dest, const char* src, size_t num)
{assert(dest && src);int lens = strlen(src);for (int i = 0; i < num; i++){if (i < lens)dest[i] = src[i];else//num大于lens时,在dest中填充0dest[i] = 0;}return dest;
}
int main()
{char str1[] = "abcdefghijk", str2[] = "Wang";printf("%s", strncpy(str1, str2, 7));return 0;
}

my_strncat

#include <stdio.h>
#include <assert.h>
char* my_strncat(char* dest, const char* src, size_t num)
{assert(dest && src);int lens = strlen(dest);char* pc = dest + lens;int i = 0;for (i = 0; i < num; i++){if (i == lens)//检测到赋值到'\0'时, 立马停止赋值break;pc[i] = src[i];}pc[i] = '\0';//衔接完之后的字符串追加一个'\0'作为字符串的结尾return dest;
}
int main()
{char str1[10] = "abc", str2[] = "zzzzz";printf("%s", my_strncat(str1, str2, 4));return 0;
}

内存函数

my_memmove

#include <stdio.h>
#include <assert.h>
void* memmove(void* dest, const void* src, size_t num)
{if (dest < src)//前->后赋值{for (int i = 0; i < num; i++)((char*)dest)[i] = ((const char*)src)[i];}else//后->前赋值{for (int i = num - 1; i >= 0; i--)((char*)dest)[i] = ((const char*)src)[i];}return dest;
}
int main()
{char str[] = "abcdef";printf("%s", memmove(str, str + 3, 3));return 0;
}

my_memcpy

#include <stdio.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);char* cp = dest;for (int i = 0; i < num; i++)*(cp + i) = *(((const char*)src)+i);//通过强转为char类型来进行以字节为单位的循环复制内存结构return dest;
}
struct
{char name[15];int age;
}person, person_copy;
int main()
{char myname[] = "Petter";person.age = 19;my_memcpy(person.name, myname, sizeof(myname));my_memcpy(&person_copy, &person, sizeof(person));printf("person_copy: %s, %d\n", person_copy.name, person_copy.age);return 0;
}

结语

以上就是我对字符、字符串与内存函数的介绍以及对其中一些的函数模拟,希望你能够对这些函数有更加深刻的理解。设计逻辑上有所不足的欢迎评论区积极进行指正,让我们共同成长,一起进步!


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单屏蔽WPforms垃圾留言和无效询盘的方法

简单屏蔽WPforms垃圾留言和无效询盘的方法 发表评论 因为WPforms的可视化操作非常简单&#xff0c;不少外贸网站都使用WPforms来制作询盘表单&#xff0c;而只要网站可以提交留言&#xff0c;就非常容易被垃圾留言骚扰。本文奶爸将给大家介绍两种屏蔽WPforms表单垃圾留言的方…

单片机中MCU跑RTOS相比裸机的优势

经常有读者问关于RTOS的问题&#xff0c;比如&#xff1a;我现在要不要学习RTOS&#xff1f; 学习RTOS有什么好处&#xff1f; 我的项目要不要跑RTOS&#xff1f; 问这些问题&#xff0c;其实归根结底还是对RTOS理解的不够&#xff0c;项目开发的经验还不足等。针对这部分朋友…

实战项目(一)内容管理系统

一、实现技术 前端技术&#xff1a;html、javascript(jquery、ajax、json)、css 后端技术&#xff1a;java、mysql、servlet 开发工具&#xff1a;eclipse、vscode 二、项目描述 首页仿写某大学网页&#xff0c;上面有各种栏目及栏目内容&#xff0c;管理员能登录进去对首…

FPGA之分布式RAM(2)

1) 128 X1 Single Port Distributed RAM 下图中可以看出来,通过2个LUT的组合使用可以串联实现更大深度的分布式RAM.下图中出现了F7BMUX的加入, F7BMUX可以用于LUT输出的选通. 原语调用&#xff1a; RAM128XIS#(INIT(128h00000000000000000000000000000000) // Initial conten…

2.服务拆分和远程调用

2.服务拆分和远程调用 任何分布式架构都离不开服务的拆分&#xff0c;微服务也是一样。 2.1.服务拆分原则 这里我总结了微服务拆分时的几个原则&#xff1a; 不同微服务&#xff0c;不要重复开发相同业务微服务数据独立&#xff0c;不要访问其它微服务的数据库微服务可以将…

接口测试详解,看完就会。。。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、什么是接口测试&#xff1f; 所谓接口&#xff0c;是指同一个系统中模块与模块间的数据传递…

力扣移掉k位数字402

Problem: 402. 移掉 K 位数字 给你一个以字符串表示的非负整数 num 和一个整数 k &#xff0c;移除这个数中的 k 位数字&#xff0c;使得剩下的数字最小。请你以字符串形式返回这个最小的数字。 示例 1 &#xff1a; 给你一个以字符串表示的非负整数 num 和一个整数 k &…

Aria2 WebUI控制台 任意文件读取漏洞复现(CVE-2023-39141)

0x01 产品简介 Aria2 WebUI控制台是用于下载文件的实用程序。它支持 HTTP(S)/FTP/SFTP/BitTorrent 和 Metalink 协议。aria2可以从多个来源/协议下载文件,并尝试利用您的最大下载带宽。它支持同时从HTTP(S)/FTP/SFTP和BitTorrent下载文件,而从HTTP(S)/FTP/SFTP下载的数据上…

怎么抹掉 Macbook系统 并将它还原为出厂设置

抹掉 Mac 并将它还原为出厂设置 借助“抹掉所有内容和设置”这项功能&#xff0c;你可以快速安全地抹掉所有设置、数据和 App&#xff0c;同时保留当前安装的操作系统。 使用“抹掉所有内容和设置” 这项功能要求装有 macOS Monterey 或更高版本&#xff0c;且使用搭载 Apple 芯…

关联系统-智能座舱控制器ICC

智能座舱构成 如上图所示&#xff0c;智能座舱主要是由仪表、中控、HUD、语音、DMS/OMS等多种交互通道组成&#xff0c;其宗旨是提升人的交互体验&#xff0c;使车辆更加智能化&#xff0c;情感化。 智能座舱内部功能 仪表功能 SR场景重构 如上图所示&#xff0c;仪表区域可实…

Redis相关面试题大全

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于java面试题系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基…

为啥现在4位单片机依然没有被淘汰?

为啥现在4位单片机依然没有被淘汰&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xf…

网络安全概述

目录 网络安全背景 网络安全常识及术语 网络的脆弱性和常见安全攻击 网络环境的开放性 协议栈(TCP/IP)自身的脆弱性 物理层 -- 物理攻击 链路层 网络层 -- ICMP攻击 传输层 -- TCP SYN Flood攻击 应用层 -- DNS欺骗攻击 ​编辑 操作系统的脆弱性及常见安全攻…

DevEco Studio4.0/3.1预览器报错综合整理

题外话&#xff1a;额&#xff0c;这篇文章的由来&#xff0c;是在这篇文章DevEco Studio3.1报错...发布后&#xff0c;仍有人没解决预览不了的问题&#xff0c;然后就有小伙伴让我看看到底哪个地方出错了&#xff0c;为什么按照文章上的去做了&#xff0c;还是无法使用&#x…

HCIP----MGRE实验

实验要求&#xff1a; 第一步&#xff0c;基本的IP地址配置 R1&#xff1a; [R1]int g0/0/1 [R1-GigabitEthernet0/0/1]ip add 192.168.1.1 24 #配置PC的网关 [R1]int Serial 4/0/0 [R1-Serial4/0/0]link-protocol hdlc #R1和R2之间采用hdlc封装 [R1-S…

爬虫入门到精通_基础篇1(爬虫基本原理讲解, Urllib库基本使用)

01 爬虫基本原理讲解 1.什么是爬虫:请求网站并提取数据的自动化程序 2.爬虫基本流程&#xff1a; 发起请求&#xff1a;通过HTTP库向目标站点发起请求&#xff0c;即发送一个Request,请求可以包含额外的headers等信息&#xff0c;等待服务器响应。获取响应内容&#xff1a;如…

从0开始学鸿蒙应用开发——安装与配置DevEco Studio

安装与配置DevEco Studio 一.电脑配置要求 64位win10及以上&#xff0c;内存8GB&#xff0c;硬盘100GB 二.下载 1.进入openharmony官网&#xff1a;OpenAtom OpenHarmonyhttps://www.openharmony.cn/mainPlay 2.点击下载。 3.依次选择 开发者->应用开发者->应用开发文…

从零学Java - Stream API

Java - Stream API 文章目录 Java - Stream API什么是流(Stream)?Stream 的特点Stream使用步骤1 创建 Stream流2 中间操作3 终止操作 什么是流(Stream)? 流&#xff08;Stream&#xff09;与集合类似&#xff0c;但集合中保存的是数据&#xff0c;而Stream中保存对集合或数组…

揭开Spring MVC的真面目

官方对于Spring MVC的描述为&#xff1a; Spring Web MVC是基于Servlet API框架构建的原始Web框架&#xff0c;从一开始就包含在Spring框架中。它的正式名称“Spring Web MVC”来自其源模块的名称&#xff08;Spring-webmvc&#xff09;&#xff0c;但它通常被称为“Spring-MVC…

数组和链表部分例题(力扣)

1.数组 1.1 合并一个数组的两个有序区间 public class MargTwo {public static void main(String[] args) {int[] arr1{1,5,6,2,4,10,11};int[] arr2new int[arr1.length];marg2(arr1,0,2,3,6,arr2);}private static void marg2(int[]arr1,int iStar,int iEnd,int jStar,int j…