1c语言基础

news2024/11/27 5:24:59

1.关键字

一、数据类型关键字

A基本数据类型(5个)

  • void:声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果
  • char:字符型类型数据,属于整型数据的一种
  • int:整型数据,通常为编译器指定的机器字长
  • float:单精度浮点型数据,属于浮点数据的一种
  • double:双精度浮点型数据,属于浮点数据的一种

B类型修饰关键字(4个)

  • short:修饰int,短整型数据,可省略被修饰的int。
  • long:修饰int,长整形数据,可省略被修饰的int。
  • signed:修饰整型数据,有符号数据类型
  • unsigned:修饰整型数据,无符号数据类型

C复杂类型关键字(5个)

  • struct:结构体声明
  • union:共用体声明
  • enum:枚举声明
  • typedef:声明类型别名
  • sizeof:得到特定类型或特定类型变量的大小

D存储级别关键字(6个)

  • auto:指定为自动变量,由编译器自动分配及释放。通常在栈上分配
  • static:指定为静态变量,分配在静态变量区,修饰函数时,指定函数作用域为文件内部
  • register:指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数形参,建议编译器通过寄存器而不是堆栈传递参数
  • extern:指定对应变量为外部变量,即在另外的目标文件中定义,可以认为是约定由另外文件声明的对象的一个“引用“
  • const:与volatile合称“cv特性”,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)
  • volatile:与const合称“cv特性”,指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值

二、流程控制关键字

A跳转结构(4个)

  • return:用在函数体中,返回特定值(或者是void值,即不返回值)
  • continue:结束当前循环,开始下一轮循环
  • break:跳出当前循环或switch结构
  • goto:无条件跳转语句

B分支结构(5个)

  • if:条件语句
  • else:条件语句否定分支(与if连用)
  • switch:开关语句(多重分支语句)
  • case:开关语句中的分支标记
  • default:开关语句中的“其他”分治,可选。

C循环结构(3个)

  • for:for循环结构,for(1;2;3)4;的执行顺序为1->2->4->3->2…循环,其中2为循环条件
  • do:do循环结构,do 1 while(2);的执行顺序是1->2->1…循环,2为循环条件
  • while:while循环结构,while(1) 2;的执行顺序是1->2->1…循环,1为循环条件

以上循环语句,当循环条件表达式为真则继续循环,为假则跳出循环。

关键字 typedef

typedef 顾名思义是类型定义,这里应该理解为类型重命名。比如:

//将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
typedef unsigned int uint_32;
int main()
{
    //观察num1和num2,这两个变量的类型是一样的
    unsigned int num1 = 0;
    uint_32 num2 = 0;
    return 0; }

关键字static

在C语言中:
static是用来修饰变量和函数的

  1. 修饰局部变量-称为静态局部变量
  2. 修饰全局变量-称为静态全局变量
  3. 修饰函数-称为静态函数
1 修饰局部变量

对比代码1和代码2的效果理解static修饰局部变量的意义。

//代码1
#include <stdio.h>
void test()
{
    int i = 0;
    i++;
    printf("%d ", i);  //每次函数执行结束,i值都会被释放掉
}
int main()
{
 int i = 0;
    for(i=0; i<10; i++)
   {
        test(); //每次有打印1
   }
    return 0; }
12345678910111213141516
//代码2
#include <stdio.h>
void test()
{
    //static修饰局部变量
    static int i = 0;  //test()执行结束后,保留i值
    i++;
    printf("%d ", i);
}
int main()
{
 int i = 0;
    for(i=0; i<10; i++)
   {
        test(); //每次有打印1到10
   }
    return 0; }
1234567891011121314151617

结论:static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。

2 修饰全局变量

代码1正常,代码2在编译的时候会出现连接性错误。

//代码1
//add.c
int g_val = 2018;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0; }

//代码2
//add.c   static 全局变量
static int g_val = 2018;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0; }
1234567891011121314151617

结论:一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。

3 修饰函数

代码1正常,代码2在编译的时候会出现连接性错误,和修饰全局变量一样。

//代码1
//add.c
int Add(int x, int y) {
    return x+y; }
//test.c
int main()
{
    printf("%d\n", Add(2, 3));
    return 0; }

//代码2
//add.c   static 修饰函数
static int Add(int x, int y) {
    return c+y; }
//test.c
int main()
{
    printf("%d\n", Add(2, 3));
    return 0; }
12345678910111213141516171819

结论:一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。

2.基础数据类型 和 尺寸

char //字符数据类型

short //短整型

int //整形

long //长整型

long //更长的整形

float //单精度浮点数

double //双精度浮点数

//C语言有没有字符串类型? 答案是没有。c语言中没有string类型,string是用char型数组来构造的。

每种数据类型占据的字节大小:

#include <stdio.h>  
int main()
{
		//以下是在win10的vs2017显示的结果
    printf("%d\n", sizeof(char));  // 1
    printf("%d\n", sizeof(short));  // 2
    printf("%d\n", sizeof(int));  // 4
    printf("%d\n", sizeof(long));  // 4
    printf("%d\n", sizeof(long long));  //8
    printf("%d\n", sizeof(float));  //4
    printf("%d\n", sizeof(double));  // 8
    printf("%d\n", sizeof(long double));  //8
    return 0; }
12345678910111213

存在这么多的类型,其实是为了更加丰富的表达生活中的各种值。
类型的使用:

char ch = 'w';  //字符型
int weight = 120;  //整型
float salary = 20000.0f;  //单精度浮点型

3. 变量、常量

生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)
有些值是可变的(比如:年龄,体重,薪资)。
不变的值,C语言中用常量的概念来表示,变得值C语言中用变量来表示。

3.1 定义变量的方法

语法:变量类型 变量名称 = 初始值;

int age = 150;
float weight = 45.5f;
char ch = 'w';
123

3.2 变量的分类

1)局部变量
2)全局变量
#include <stdio.h>
int global = 2019;//全局变量
int main()
{
    int local = 2018;//局部变量
    //下面定义的global会不会有问题?没有问题
    int global = 2020;//局部变量,当局部变量和全局变量同名时,优先使用局部变量,这个人感觉和搜索路径相关!
    printf("global = %d\n", global);
    return 0; }

3.3 变量的使用(使用 scanf如何 接收数据)

#include <stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);  //int -- %d  float -- %f  double -- %lf  char -- %c
    sum = num1 + num2;
    printf("sum = %d\n", sum);
    return 0; }

在C语言中,scanf函数可以用来输入longlong longshort类型的数据。下面是一些示例:

#include <stdio.h>

int main() {
    long a;
    long long b;
    short c;

    printf("请输入一个long类型的数:");
    scanf("%ld", &a);

    printf("请输入一个long long类型的数:");
    scanf("%lld", &b);

    printf("请输入一个short类型的数:");
    scanf("%hd", &c);

    printf("你输入的long类型的数是:%ld\n", a);
    printf("你输入的long long类型的数是:%lld\n", b);
    printf("你输入的short类型的数是:%hd\n", c);

    return 0;
}

在这个代码中,%ld%lld%hd分别用于输入longlong longshort类型的数据。&符号是取地址运算符,它的作用是获取变量的内存地址。scanf函数需要这个地址来改变变量的值。注意,scanf函数的使用需要谨慎,因为它可能会导致缓冲区溢出等问题。在实际编程中,建议使用更安全的输入函数,如fgetssscanf


3.4 变量的作用域和生命周期

1)作用域:作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用
的。而限定这个名字的可用性的代码范围就是这个名字的作用域。
(1)局部变量的作用域是变量所在的局部范围。比如:{int a = 10;},{}内就是局部变量a的作用域。
(2)全局变量的作用域是整个工程。比如:int b =100;int main(){};,在main()函数{}之外也不在其他范围内的变量。

2)生命周期:变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
(1)局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。比如函数的形参。
(2)全局变量的生命周期是:整个程序的生命周期。程序结束,全局变量生命周期才结束。

3.5 常量

C语言中的常量和变量的定义的形式有所差异。

C语言中的常量分为以下以下几种:

1)字面常量

2)const 修饰的常变量 语法: const 变量类型

3)#define 定义的标识符常量 语法:#define 常量标识符 常量值

4)枚举常量 语法:enum 枚举常量名 {常量1, 常量2,…}; //这里记得加上分号!常量面前没有常量类型

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//举例
enum Sex
{
	MALE,
	//MALE=2,  //可指定默认值,后面的值在2的基础上,递增+1
	FEMALE,
	SECRET
};  //这里要加上分号;
//括号中的MALE,FEMALE,SECRET是枚举常量


int main()
{
	//字面常量演示
	3.14;//字面常量
	1000;//字面常量

	//const 修饰的常变量
	const float pai = 3.14f; //这里的pai是const修饰的 常变量
	//pai = 5.14;//是不能直接修改的!vs2017会提示表达式必须是可修改的左值

	//#define的标识符常量 演示
	#define MAX 100  //这里没有分号”;“
	printf("max = %d\n", MAX);  // 100

	//枚举常量演示
	printf("%d\n", MALE);  // 0
	printf("%d\n", FEMALE);  // 1
	printf("%d\n", SECRET);  // 2
	//注:枚举常量的默认是从0开始,依次向下递增1的
	return 0;
}

注(常变量):
上面例子上的 pai 被称为 const 修饰的常变量, const 修饰的常变量在C语言中只是在语法层面限制了变量 pai 不能直接被改变,但是 pai 本质上还是一个变量的,所以叫常变量。

4. 字符串+转义字符

4.1 字符串

"hello bit.\n"

这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。
注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。

#include <stdio.h>
//下面代码,打印结果是什么?为什么?(突出'\0'的重要性)
int main()
{
	char arr1[] = "bit";  
	char arr2[] = { 'b', 'i', 't' };
	char arr3[] = { 'b', 'i', 't', '\0' };  
	printf("%s\n", arr1);  //bit  默认包含了'\0'
	printf("%d\n", sizeof(arr1)/sizeof(char)); //4, 但是在计算长度的时候是包括的!!!
	printf("%s\n", arr2);  //bit烫烫烫烫蘠it 随机值
	//printf("%d\n", sizeof(arr2) / sizeof(char));
	printf("%s\n", arr3);  //bit 显示写出'\0'
	printf("%d\n", sizeof(arr3) / sizeof(char));  // 4  

	return 0;
}
 

4.2 转义字符

加入我们要在屏幕上打印一个目录: c:\code\test.c
我们该如何写代码?

#include <stdio.h>
int main()
{
 printf("c:\code\test.c\n");
    return 0; }
12345

实际上程序运行的结果是这样的:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
这里就不得不提一下转义字符了。转义字符顾名思义就是转变意思。
下面看一些转义字符。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
int main()
{
	//问题1:在屏幕上打印一个单引号',怎么做?
	//问题2:在屏幕上打印一个字符串,字符串的内容是一个双引号“,怎么做?
	printf("%c\n", '\'');  //注意:单引号''括起来的对应%c,双引号括起来的对应%s
	printf("%s\n", "\'"); 
	printf("%s\n", "\"");
	printf("%c\n", '\"');
	return 0;
}
12345678910111213
//程序输出什么?
#include <stdio.h>
int main()
{
	//strlen()求字符串长度
	printf("%d\n", strlen("abcdef"));  // 6
	// \62被解析成一个转义字符
	printf("%d\n", strlen("c:\test\628\test.c"));  //14 = 11 + 3个转义字符
	
	printf("%c\n", '\62');  //2  ???

	return 0;
}

    
    

4.3字符指针和字符数组 和字符串的区别

在C语言中,字符指针、字符数组和字符串是三个不同的概念,虽然它们在许多情况下可以互换使用,但它们之间还是存在一些关键的区别123456。

字符指针是一个指针,它存储的是地址,而不是将字符串放到字符指针变量中123456。例如:

char *p = "Hello World!";

在这个例子中,p是一个字符指针,它指向的是字符串"Hello World!"的首地址123456。

字符数组是一个存储字符的数组,其长度是固定的,其中任何一个数组元素都可以为 null 字符。因此,字符数组不一定是字符串123456。例如:

char cArr[] = {'H', 'e', 'l', 'l', 'o'};

在这个例子中,cArr是一个字符数组,它包含5个字符,但并没有以null字符(‘\0’)结束,所以它不是一个字符串123456。

字符串,它必须以 null 字符结束,其后的字符不属于该字符串123456。字符串一定是字符数组,它是最后一个字符为 null 字符的字符数组123456。例如:

char sArr[] = "Hello";

在这个例子中,sArr是一个字符串,它包含5个字符和一个结束的null字符(‘\0’),所以它是一个字符串123456。

需要注意的是,字符串是一个只读型字符型数组,不能够通过指针更改字符串内部数据2。而字符数组可以修改其内部的数据123456。

总的来说,所有的字符串都是字符数组,但并非所有的字符数组都是字符串123456。这是因为字符串有一个额外的约束,即必须以null字符结束123456。这个约束使得字符串可以被一些特定的函数(如printfstrlen)用于特定的目的123456。

进阶

1 字符函数和字符串函数

**1.1 **strlen (重要)

函数用于获取字符串的长度:

size_t strlen ( const char * str );
1

字符串已 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(*不包含 ‘\0’* )。
参数指向的字符串必须要以 ‘\0’ 结束。
没有’\0’,的出来的结果就是随机值
注意函数的返回值为size_t,是无符号的( 易错 )
学会strlen函数的模拟实现

#include <stdio.h>

int main()
{
	const char*str1 = "abcdef";
	const char*str2 = "bbb";
	if(strlen(str2)-strlen(str1)>0)  // 返回无符号的,就一直是>0
	{
		printf("str2>str1\n");
	} 
	else
	{
		printf("srt1>str2\n");
	}
	
	return 0; 
}
 

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这段代码中的问题在于 strlen 函数返回的是 size_t 类型,这是一个无符号整数类型。当你从一个较大的无符号数中减去一个较小的无符号数时,结果仍然是一个无符号数。在你的例子中,strlen(str2) 是3,strlen(str1) 是6,所以 strlen(str2) - strlen(str1) 的结果是一个非常大的无符号数,而不是一个负数。这就是为什么 if(strlen(str2)-strlen(str1)>0) 总是为真的原因。

为了避免这个问题,你可以先将 strlen 的结果存储在 int 类型的变量中,然后再进行比较,就像你在第二段代码中所做的那样。这样,b - a 的结果就会是一个有符号的整数,可以正确地表示负数。这就是为什么第二段代码能够正确地比较两个字符串的长度。希望这个解释对你有所帮助!


#include <stdio.h>

int main()
{
	const char*str1 = "abcdef";
	const char*str2 = "bbb";
	printf("%d\n", strlen(str1));  // 6
	printf("%d\n", strlen(str2));  // 3
	
	int a = strlen(str1);
	int b = strlen(str2);
	int c = b - a;
	if (c > 0)
	{
		printf("str2>str1\n");
	}
	else
	{
		printf("srt1>str2\n");
	}
	return 0;
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.2 strcpy

函数用于复制字符串:

char * strcpy ( char * destination, const char * source );
1

Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。

#include <stdio.h>
#include <string.h>

int main() {
    char src[40];
    char dest[12];
   
    memset(dest, '\0', sizeof(dest));
    strcpy(src, "This is tutorialspoint.com");
    strcpy(dest, src);

    printf("Final copied string : %s\n", dest);
   
    return(0);
}
Final copied string : This is tutorialspoint.com
1.3 strcat

strcat是C语言中的一个库函数,用于将一个字符串追加到另一个字符串的末尾12345。其函数原型为:

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

其中,dest是目标字符串,src是要追加的字符串4。

这个函数的工作原理是将src所指向的字符串追加到dest所指向的字符串的结尾13。因此,必须确保dest有足够的内存空间来容纳两个字符串,否则可能会导致溢出错误3。

以下是strcat函数的一个使用示例1:

#include <stdio.h>
#include <string.h>

int main () {
    char src[50], dest[50];

    strcpy(src, "This is source");
    strcpy(dest, "This is destination");

    strcat(dest, src);

    printf("Final destination string: |%s|", dest);

    return(0);
}

在这个示例中,src字符串被追加到dest字符串的末尾,然后打印出最终的dest字符串。这将产生以下结果:

Final destination string: |This is destinationThis is source|

需要注意的是,strcat函数不会覆盖目标字符串1。而且,srcdest字符串中都必须包含字符’\0’,并且src字符串必须以’\0’结尾,否则追加过程无法顺利实现2。此外,目标字符串空间必须足够大(足够容纳追加字符串src的内容),并且目标空间必须可修改(前面不能加const并且不能说常量字符串)2。

字符串自己给自己追加,如何?会报错

/* strcat example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[80];
  strcpy(str,"these ");
  strcat(str,"strings ");
  strcat(str,"are ");
  strcat(str,"concatenated.");
  puts (str);
  
  return 0;
}

these strings are concatenated.
1.4 strcmp

strcmp 函数可以用来比较两个 C 字符串。在 C 语言中,字符串通常表示为字符数组,并以空字符 ‘\0’ 结尾。所以,如果你有两个字符数组,并且它们都以 ‘\0’ 结尾,那么你可以使用 strcmp 来比较它们。

但是,需要注意的是,strcmp 函数并不会比较两个数组的所有元素,它只会比较到遇到第一个 ‘\0’ 字符为止。所以,如果你的数组中包含 ‘\0’ 字符,或者你想比较的是非字符类型的数组,那么 strcmp 可能就不适用了。

在这种情况下,你可能需要使用其他函数,如 memcmp,它可以比较任意类型的数组,只需要指定要比较的字节数。希望这个解释对你有所帮助!

比较字符数组

当然可以。以下是一个使用 strcmp 来比较两个字符数组的例子:

#include <stdio.h>
#include <string.h>

int main() {
    char str1[] = "Hello, world!";
    char str2[] = "Hello, world!";

    if (strcmp(str1, str2) == 0) {
        printf("The two strings are equal.\n");
    } else {
        printf("The two strings are not equal.\n");
    }

    return 0;
}

在这个例子中,我们定义了两个字符数组 str1str2,然后使用 strcmp 来比较这两个数组是否相等。如果 strcmp 返回 0,那么这两个字符串就是相等的。否则,它们就不相等。希望这个例子对你有所帮助!

The two strings are equal.
比较字符串

函数用于比较两个字符串:

int strcmp ( const char * str1, const char * str2 );
1

This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.

标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
那么如何判断两个字符串?

#include <stdio.h>
int main()
{
	const char*str1 = "abcdef";
	const char*str2 = "abcfed";
	printf("%d\n", strlen(str1));  // 6
	printf("%d\n", strlen(str2));  // 3
	int a = strcmp(str2, str1);
	printf("%d\n", a);
	
	return 0;
}

6
6
1
#include <stdio.h>
#include <string.h>

int main() {
    char str1[15];
    char str2[15];
    int ret;

    strcpy(str1, "abcdef");
    strcpy(str2, "ABCDEF");

    ret = strcmp(str1, str2);

    if(ret < 0) {
        printf("str1 is less than str2\n");
    } else if(ret > 0) {
        printf("str2 is less than str1\n");
    } else {
        printf("str1 is equal to str2\n");
    }
   
    return(0);
}
str2 is less than str1
1.5 strncpy

函数用于复制指定数量的字符:

strncpy 是 C 语言中的一个内置函数,用于将一个字符串的前 n 个字符复制到另一个字符串1。它的声明如下:

char *strncpy(char *dest, const char *src, size_t n);

这里的参数是:

  • dest:我们想要复制到的目标字符串1。
  • src:我们要复制的源字符串1。
  • n:要复制的字符的最大数量1。

strncpy 函数的返回值是指向结果字符串 dest 的指针1。

如果 src 的长度小于 n,那么 dest 的剩余部分将用空字符 ‘\0’ 填充1。

以下是一个 strncpy 函数的使用示例:

#include <stdio.h>
#include <string.h>

int main() {
    char src[40];
    char dest[12];

    memset(dest, '\0', sizeof(dest));
    strcpy(src, "This is tutorialspoint.com");
    strncpy(dest, src, 10);

    printf("Final copied string : %s\n", dest);

    return 0;
}

在这个例子中,我们将 src 字符串的前 10 个字符复制到 dest 字符串1。

Final copied string : This is tu
/* 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
1.6 strncat (连接)

strncat 是 C 语言中的一个内置函数,用于将一个字符串的前 n 个字符追加到另一个字符串的末尾1。它的声明如下:

char *strncat(char *dest, const char *src, size_t n);

这里的参数是:

  • dest:我们想要追加的字符串1。
  • src:我们要追加的 ‘n’ 个字符的字符串1。
  • n:要追加的字符的最大数量1。

strncat 函数的返回值是指向结果字符串 dest 的指针1。

以下是一个 strncat 函数的使用示例:

#include <stdio.h>
#include <string.h>

int main() {
    char src[50], dest[50];

    strcpy(src,  "This is source");
    strcpy(dest, "This is destination");

    strncat(dest, src, 15);
    printf("Final destination string : |%s|\n", dest);
   
    return 0;
}

在这个例子中,我们将 src 字符串的前 15 个字符追加到 dest 字符串的末尾1。希望这个解释对你有所帮助!

Final destination string : |This is destinationThis is source|
1.7 strncmp (比较)

strncmp 是 C 语言中的一个内置函数,用于比较两个字符串的前 n 个字符1。它的声明如下:

int strncmp(const char *str1, const char *str2, size_t n);

这里的参数是:

  • str1:要比较的第一个字符串1。
  • str2:要比较的第二个字符串1。
  • n:要比较的字符的最大数量1。

strncmp 函数的返回值取决于比较的结果1:

  • 如果 str1 小于 str2,则返回值小于 01。
  • 如果 str1 大于 str2,则返回值大于 01。
  • 如果 str1 等于 str2,则返回值等于 01。

这里的 “大于” 和 “小于” 是指在比较字符串时,按照字符的 ASCII 值进行比较1。

以下是一个 strncmp 函数的使用示例:

#include <stdio.h>
#include <string.h>

int main() {
    char str1[15];
    char str2[15];
    int ret;

    strcpy(str1, "abcdef");
    strcpy(str2, "ABCDEF");

    ret = strncmp(str1, str2, 4);

    if(ret < 0) {
        printf("str1 is less than str2\n");
    } else if(ret > 0) {
        printf("str2 is less than str1\n");
    } else {
        printf("str1 is equal to str2\n");
    }

    return 0;
}

在这个例子中,我们比较了 str1str2 的前 4 个字符。如果 str1 小于 str2,我们就打印 “str1 is less than str2”,如果 str1 大于 str2,我们就打印 “str2 is less than str1”,否则我们就打印 "str1 is equal to str2"1。

str2 is less than str1
1.8 strstr (查找)

函数用于在一个字符串中查找另一个字符串:

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

Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.

/* strstr example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="This is a simple string";
  char * pch;
  pch = strstr (str, "simple");
  strncpy (pch, "sample", 6);
  puts (str);
  return 0;
}
 
This is a sample string
#include <stdio.h>
#include <string.h>

int main() {
    const char haystack[20] = "TutorialsPoint";
    const char needle[10] = "Point";
    char *ret;

    ret = strstr(haystack, needle);

    printf("The substring is: %s\n", ret);
   
    return(0);
}
The substring is: Point
1.9 strtok (分割)

函数用于分割字符串

char * strtok ( char * str, const char * sep );
1

sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针。

/* 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

#include <stdio.h>
#include<cstring>
int main()
{
	const char *p = "zhangpengwei@bitedu.tech";
	const char* sep = ".@";
	char arr[30];
	char *str = NULL;
	strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容
	for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep))
	{
		printf("%s\n", str);
	}
}

zhangpengwei
bitedu
tech
#include <string.h>
#include <stdio.h>

int main() {
    char str[80] = "This is - www.tutorialspoint.com - website";
    const char s[2] = "-";
    char *token;
   
    /* 获取第一个子字符串 */
    token = strtok(str, s);
   
    /* 继续获取其他的子字符串 */
    while( token != NULL ) {
        printf( " %s\n", token );
    
        token = strtok(NULL, s);
    }
   
    return(0);
}
 This is
  www.tutorialspoint.com
  website
1.10 strerror
char * strerror ( int errnum );
1

返回错误码,所对应的错误信息。

/* 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));
	//errno: Last error number
	return 0; 
}

Error opening file unexist.ent: No such file or directory
字符分类函数:

函数 如果他的参数符合下列条件就返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
isdigit 十进制数字 0~9
isxdigit 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母az或AZ
isalnum 字母或者数字,az,AZ,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符

字符转换:
int tolower ( int c );
int toupper ( int c );

/* isupper example */
#include <stdio.h>
#include <ctype.h>
int main ()
{
	int i=0;
	char str[]="Test String.\n";
	char c;
	while (str[i])
	{
		c=str[i];
		if (isupper(c)) 
		    c=tolower(c);
		putchar (c);
		i++;
	}
	
	return 0;
}
 
test string.

在C语言中,字符串是由字符组成的数组,以空字符(‘\0’)结束。while(str[i]) 这个循环会一直执行,直到遇到字符串 str 的结束标志 ‘\0’。在ASCII编码中,‘\0’ 对应的整数值是0,所以当 str[i] 是 ‘\0’ 时,while(str[i]) 的条件就不满足,循环就会结束。这就是 while(str[i]) 的含义。希望这个解释对你有所帮助!

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

函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 ‘\0’ 的时候并不会停下来。

memcpy 拷贝字符串和数组
/* 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; 
}
 
注意事项
不适用于重叠复制

如果source和destination有任何的重叠,复制的结果都是未定义的

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, world!";
    
    // 尝试将 str 的前 5 个字符复制到 str 的第 3 个字符开始的位置
    memcpy(&str[2], str, 5);
    printf("%s\n", str);
    
    return 0;
}

在这个例子中,我们尝试将 str 的前 5 个字符(“Hello”)复制到 str 的第 3 个字符开始的位置。由于源地址和目标地址有重叠,所以复制的结果可能会出现错误。

当你运行这段代码时,可能会发现输出的字符串并不是你期望的 “HeHello, world!”,而是 “HeHeHo, world!”。这就是因为在复制过程中,源地址和目标地址的重叠部分被提前覆盖了。

为了避免这种情况,你可以使用 memmove 函数来代替 memcpymemmove 函数会正确处理源地址和目标地址的重叠,即使源地址和目标地址有重叠,它也能正确地复制数据。希望这个解释对你有所帮助!


为什么需要使用 memmove

“如果source和destination有任何的重叠,复制的结果都是未定义的”,这句话的意思是,如果你在使用 memcpy 函数时,源地址和目标地址有重叠的部分,那么复制的结果可能会出现错误。

这是因为 memcpy 在复制数据时,可能会先复制源地址的开始部分到目标地址,然后再复制源地址的结束部分。如果源地址和目标地址有重叠,那么在复制源地址的结束部分时,可能会覆盖已经复制到目标地址的数据,导致数据错误。

为了避免这种情况,你可以使用 memmove 函数来代替 memcpymemmove 函数会检查源地址和目标地址是否有重叠,如果有,它会从源地址的结束部分开始复制,这样就可以避免数据错误。希望这个解释对你有所帮助!


必须复制源字符串的 ‘\0’

需要注意的是,当使用 memcpy 复制字符串时,需要确保目标字符串有足够的空间来存储源字符串,并且在复制时要包括源字符串的结束符 ‘\0’。

在C语言中,字符串是由字符数组表示的,这个数组以特殊的字符 ‘\0’ 结束。‘\0’ 是一个空字符,用于标记字符串的结束。当我们使用字符串处理函数(如 printfstrcpy 等)时,这些函数会依赖 ‘\0’ 来确定字符串何时结束。

因此,当我们使用 memcpy 复制字符串时,我们需要包括源字符串的 ‘\0’ 结束符,以确保目标字符串也有一个正确的结束标记。如果不复制 ‘\0’,那么目标字符串可能就没有正确的结束标记,这可能会导致未定义的行为,比如打印字符串时打印出预期之外的字符,或者在处理字符串时访问到不应该访问的内存区域。

所以,为了确保字符串的正确处理,我们在复制字符串时通常会包括 ‘\0’ 结束符。希望这个解释对你有所帮助!

1.12 memmove

memmove是C语言中的一个库函数,用于在内存中移动数据1234。其函数原型为:

void *memmove (void *dest, const void *src, size_t n);

其中,dest是目标内存区域,src是源内存区域,n是要复制的字节数1234。

这个函数的工作原理是将src所指向的内存区域的n个字节复制到dest所指向的内存区域1234。如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中1234。复制后源区域的内容会被更改1。如果目标区域与源区域没有重叠,则和memcpy函数功能相同1。

以下是memmove函数的一个使用示例1:

#include <stdio.h>
#include <string.h>

int main () {
    const char src[] = "newstring";
    char dest[] = "oldstring";

    printf("Before memmove dest = %s, src = %s\n", dest, src);
    memmove(dest, src, 9);
    printf("After memmove dest = %s, src = %s\n", dest, src);

    return 0;
}

在这个示例中,src字符串被复制到dest字符串的位置,然后打印出最终的dest字符串。这将产生以下结果:

Before memmove dest = oldstring, src = newstring
After memmove dest = newstring, src = newstring

需要注意的是,memmove函数不会覆盖目标字符串1。此外,目标字符串空间必须足够大(足够容纳追加字符串src的内容),并且目标空间必须可修改(前面不能加const并且不能说常量字符串)2。

和memcpy的差别 : 就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。

1.13 memcmp
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
1

比较从ptr1和ptr2指针开始的num个字节
返回值如下:
<0 the first byte that does not match in both memory blocks has a lower value in ptr1 than in ptr2 (if evaluated as unsigned char values)

0 the contents of both memory blocks are equal

0 the first byte that does not match in both memory blocks has a greater value in ptr1 than in ptr2 (if evaluated as unsigned char values)

/* 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;
}
 
memcmp 比较数组
#include <stdio.h>
#include <string.h>

int main() {
    int arr1[] = {1, 2, 3, 4, 5};
    int arr2[] = {1, 2, 3, 4, 5};

    if (memcmp(arr1, arr2, sizeof(arr1)) == 0) {
        printf("The two arrays are equal.\n");
    } else {
        printf("The two arrays are not equal.\n");
    }

    return 0;
}
memcmp 比较结构体
#include <stdio.h>
#include <string.h>

typedef struct {
    int id;
    char name[50];
} Person;

int main() {
    Person p1 = {123, "Alice"};
    Person p2 = {123, "Alice"};

    if (memcmp(&p1, &p2, sizeof(Person)) == 0) {
        printf("The two persons are equal.\n");
    } else {
        printf("The two persons are not equal.\n");
    }

    return 0;
}
strcmp 和 memcmp 的区别

strcmpmemcmp 是两个用于比较数据的 C 语言函数,但它们的用途和行为有所不同1。

  • strcmp 是用于比较两个以空字符 ‘\0’ 结束的 C 字符串1。它会从两个字符串的开始处开始比较,直到遇到不同的字符或者遇到空字符 '\0’1。如果两个字符串在遇到空字符 ‘\0’ 之前都相同,那么 strcmp 就会返回 0,表示两个字符串相等1。
  • memcmp 则是用于比较两个指定长度的字节序列1。它并不关心数据是否以空字符 ‘\0’ 结束,只会简单地比较指定数量的字节1。因此,memcmp 可以用于比较任何类型的数据,包括字符串、结构体、数组等1。

总的来说,strcmpmemcmp 的主要区别在于,strcmp 是用于比较字符串的,而 memcmp 是用于比较任意类型的数据的1。希望这个解释对你有所帮助!

2. 库函数的模拟实现 (暂略)

2.1 模拟实现strlen

方式1:

//计数器方式
int my_strlen(const char * str) 
{
	int count = 0;
	while(*str)
	{
		count++;
		str++;
	}
	
	return count; 
}

方式2:

//不能创建临时变量计数器
int my_strlen(const char * str) 
{
	if(*str == '\0')
		return 0;
	else
		return 1+my_strlen(str+1);//递归
}

方式3:

//指针-指针的方式
int my_strlen(char *s) 
{
     char *p = s;
     while(*p != ‘\0)
            p++;
     return p-s; 
}

2.2 模拟实现strcpy

参考代码:

//1.参数顺序
//2.函数的功能,停止条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题目出自《高质量C/C++编程》书籍最后的试题部分

char *my_strcpy(char *dest, const char*src)
{ 
	 char *ret = dest;//这里传进来的是字符串的首地址,即指针
	 assert(dest != NULL);
	 assert(src != NULL);
 
	 while((*dest++ = *src++))
	 {
	 	;
	 }
	 return ret; 
}

2.3 模拟实现strcat

参考代码:

char *my_strcat(char *dest, const char*src) 
{
	char *ret = dest;//同上,记住 不能返回局部变量的地址
	assert(dest != NULL);
	assert(src != NULL);
	while(*dest)
	{
		dest++;
	}
	while((*dest++ = *src++))
	{
	 ;
	}
	return ret; 
}

2.4 模拟实现strstr
char *strstr (const char * str1, const char * str2) 
{
	char *cp = (char *) str1;
	char *s1, *s2;
	if ( !*str2 ){
		return((char *)str1);
		}
	while (*cp)
	{
		s1 = cp;
		s2 = (char *) str2;
		while ( *s1 && *s2 && !(*s1-*s2) ){
		       s1++, s2++;
		      }
		if (!*s2)
		       return(cp);
		cp++;
	}
	
	return(NULL);
}


/stackoverflow.com/questions/13095513/what-is-the-difference-between-memcmp-strcmp-and-strncmp-in-c)1。希望这个解释对你有所帮助!

2. 库函数的模拟实现 (暂略)

2.1 模拟实现strlen

方式1:

//计数器方式
int my_strlen(const char * str) 
{
	int count = 0;
	while(*str)
	{
		count++;
		str++;
	}
	
	return count; 
}

方式2:

//不能创建临时变量计数器
int my_strlen(const char * str) 
{
	if(*str == '\0')
		return 0;
	else
		return 1+my_strlen(str+1);//递归
}

方式3:

//指针-指针的方式
int my_strlen(char *s) 
{
     char *p = s;
     while(*p != ‘\0)
            p++;
     return p-s; 
}

2.2 模拟实现strcpy

参考代码:

//1.参数顺序
//2.函数的功能,停止条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题目出自《高质量C/C++编程》书籍最后的试题部分

char *my_strcpy(char *dest, const char*src)
{ 
	 char *ret = dest;//这里传进来的是字符串的首地址,即指针
	 assert(dest != NULL);
	 assert(src != NULL);
 
	 while((*dest++ = *src++))
	 {
	 	;
	 }
	 return ret; 
}

2.3 模拟实现strcat

参考代码:

char *my_strcat(char *dest, const char*src) 
{
	char *ret = dest;//同上,记住 不能返回局部变量的地址
	assert(dest != NULL);
	assert(src != NULL);
	while(*dest)
	{
		dest++;
	}
	while((*dest++ = *src++))
	{
	 ;
	}
	return ret; 
}

2.4 模拟实现strstr
char *strstr (const char * str1, const char * str2) 
{
	char *cp = (char *) str1;
	char *s1, *s2;
	if ( !*str2 ){
		return((char *)str1);
		}
	while (*cp)
	{
		s1 = cp;
		s2 = (char *) str2;
		while ( *s1 && *s2 && !(*s1-*s2) ){
		       s1++, s2++;
		      }
		if (!*s2)
		       return(cp);
		cp++;
	}
	
	return(NULL);
}


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

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

相关文章

Ollama 运行视觉语言模型LLaVA

Ollama的LLaVA&#xff08;大型语言和视觉助手&#xff09;模型集已更新至 1.6 版&#xff0c;支持&#xff1a; 更高的图像分辨率&#xff1a;支持高达 4 倍的像素&#xff0c;使模型能够掌握更多细节。改进的文本识别和推理能力&#xff1a;在附加文档、图表和图表数据集上进…

Github界面学习

之前并没有使用到其他功能大多数是看代码&#xff0c;然后看discussion&#xff1b; now,在做毕设的时候发现了一个gymnasium关于异步环境的bug&#xff0c;查看github发现已经被修复了&#xff1b; 因此希望学习一下修复者是在哪个module修复以及如何修复以及提交代码&#…

Spring Boot框架在大学生就业招聘中的应用

3系统分析 3.1可行性分析 通过对本大学生就业招聘系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本大学生就业招聘系统采用JAVA作为开发语言&#xff0c;S…

kaggle实战3RossmanStore商店销售额预测XgBoost解决回归问题案例1

kaggle实战2信用卡反欺诈逻辑回归模型案例1 数据集下载地址 https://download.csdn.net/download/AnalogElectronic/89844637 https://tianchi.aliyun.com/dataset/89785 加载数据 #预测销售额 回归问题 import numpy as np import pandas as pd import matplotlib.pyplot a…

无神论文解读之ControlNet:Adding Conditional Control to Text-to-Image Diffusion Models

一、什么是ControlNet ControlNet是一种能够控制模型生成内容的方法&#xff0c;能够对文生图等模型添加限制信息&#xff08;边缘、深度图、法向量图、姿势点图等&#xff09;&#xff0c;在当今生成比较火的时代很流行。 这种方法使得能够直接提供空间信息控制图片以更细粒…

招联2025校招内推倒计时

【投递方式】 直接扫下方二维码&#xff0c;或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus&#xff0c;使用内推码 igcefb 投递&#xff09; 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…

【课程学习】随机过程之泊松过程

随机过程之泊松过程 泊松分布泊松过程 泊松分布 二项分布是离散性的分布&#xff0c;泊松分布是把二项分布取n趋于无穷得到的连续分布。也就是在一段时间内不停的观察某件事情发生的次数。 如&#xff1a;一个小时内观察一段路上经过行人的数目&#xff0c;如果每个半个小时观…

nginx和gateway的关系和区别

在技术选型时&#xff0c;选择 Nginx 和 Spring Cloud Gateway&#xff08;或简称为 Gateway&#xff09;主要取决于具体应用场景和技术需求。下面是两者的一些关键差异和适用场景。 一、Nginx 概念 Nginx 是一个高性能的 Web 服务器和反向代理服务器&#xff0c;常被用作静…

智能手表(Smart Watch)项目

文章目录 前言一、智能手表&#xff08;Smart Watch&#xff09;简介二、系统组成三、软件框架四、IAP_F411 App4.1 MDK工程结构4.2 设计思路 五、Smart Watch App5.1 MDK工程结构5.2 片上外设5.3 板载驱动BSP5.4 硬件访问机制-HWDataAccess5.4.1 LVGL仿真和MDK工程的互相移植5…

CSRF | CSRF 漏洞介绍

关注这个漏洞的其他相关笔记&#xff1a;CSRF 漏洞 - 学习手册-CSDN博客 0x01&#xff1a;CSRF 漏洞简介 CSRF&#xff08;Cross-Site request forgery&#xff0c;跨站请求伪造&#xff09;也被称为 One Click Attack 或者 Session Riding&#xff0c;通常缩写为 CSRF 或者 X…

【Java】IntelliJ IDEA开发环境安装

一、下载 官方地址&#xff1a;https://www.jetbrains.com/idea/ 点击Download直接下载 二、安装 双击安装包&#xff0c;点击Next 选择安装路径&#xff0c;点击Next 勾选安装内容 安装完成。 三、创建项目 打开IDEA&#xff0c;填写项目名称&#xff0c;选择项目安装路径…

S7-200 SMART的数据类型说明

S7-200 SMART的数据主要分为&#xff1a; 与实际输入/输出信号相关的输入/输出映象区&#xff1a; I&#xff1a;数字量输入&#xff08;DI&#xff09;Q&#xff1a;数字量输出&#xff08;DO&#xff09;AI&#xff1a;模拟量输入AQ&#xff1a;模拟量输出 内部数据存储区…

STM32 Hal库SDIO在FATFS使用下的函数调用关系

STM32 Hal库SDIO在FATFS使用下的函数调用关系 本文并不将FATFS的相关接口操作&#xff0c;而是将HAL在使用FATFS通过SDIO外设管理SD卡时&#xff0c;内部函数的调用逻辑&#xff0c;有助于当我们使用CUBEMX生成FATFS读取SD卡的代码时无法运行时Debug。本文也会说明一些可能出现…

如何编写一个优雅的commit message

在Git中&#xff0c;git commit 命令扮演着至关重要的角色。它的主要作用是将暂存区&#xff08;staging area&#xff09;里的改动内容提交到本地仓库&#xff08;repository&#xff09;中&#xff0c;形成一个新的版本或提交&#xff08;commit&#xff09;。这个过程是 Git…

渗透测试入门学习——使用python脚本自动识别图片验证码,OCR技术初体验

写在前面 由于验证码在服务端生成后存储在服务器的session中&#xff0c;而标用于标识用户身份的sessionid存在于用户cookie中 所以本次识别验证码时需要用requests.session()创建会话对象&#xff0c;模拟真实的浏览器行为&#xff0c;保持与服务器的会话才能获取登录时服务…

wsl2 ubuntu 桥接以太网卡

注意&#xff1a;此方法需要至少 Windows 11 22H2。桥接模式就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。 在桥接的作用下&#xff0c;类似于把宿主机虚拟为一个交换机&#xff0c;所有桥接设置的虚拟机连接到这个交换机的一个接口上&#xff0c;宿主机也同样插在这…

通信工程学习:什么是RARP反向地址解析协议

RARP&#xff1a;反向地址解析协议 RARP&#xff08;Reverse Address Resolution Protocol&#xff0c;反向地址解析协议&#xff09;是一种网络协议&#xff0c;其主要作用是在设备只知道物理地址&#xff08;如MAC地址&#xff09;时&#xff0c;允许其从网关服务器的地址解析…

致亲爱的Android studio

你的未来发展趋势&#xff1a; 可不可以把兼容性&#xff0c;什么的搞得更好。起因是我想写期末大作业&#xff0c;然后简单的把功能写的差不多了之后&#xff0c;我就想到处看看有没有一套比较好的类似于组件库的东西&#xff0c;但是没找到&#xff0c;然后就把目标锁定到了G…

Vue入门-Node.js安装

进入Node.js中文网 ​​​​​​​点击进入Node.js中文网 或者手动输入网址&#xff1a; https://www.nodejs.com.cn/download.html 点击下载64位安装包&#xff1a; 下载好之后双击进行安装 可选择个性化安装或默认安装 直接点【Next】按钮&#xff0c;此处可根据个人需求…

深度解析 HTTP

我的主页&#xff1a;2的n次方_ 1. HTTP 的简单介绍 HTTP &#xff1a;超文本传输协议&#xff0c;不仅能传输文本&#xff0c;还能传输图片&#xff0c;音频文件&#xff0c;视频 目前基本上都用的是 1.1 版本 https 可以认为是 http 的升级版&#xff0c;区别就是引入了…