C_knowledge_addition

1.辗转相除法

    辗转相除法,也称为欧几里得算法,是一种古老且有效的方法,用于计算两个非负整数的最大公约数
​
比如现在要求这两个数 32,26的最大公约数,解法如下:
​
32/26=1...6  (此行除数26作下一行的被除数,余数作为除数)
​
26/6=4...2  (此行同理)
​
6/2=3...0  (此处余数为零,意味着最大公约数就是2)
​
反复把一个式子中的除数当作被除数去除余数,直到最后余数等于0。
​
最大公约数就是最后那个式子的除数,本例就是2。
    最大公因数:也称最大公约数、最大公因子,指两个或多个整数工哦呦约数中最大的一个

2.查看编程语言排名的网站:TIOBE Index - TIOBE

3.

(1)IDE

集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。

(2)IDLE

python自带的集成开发环境

4.标识符,识-→zhi

1.声明和定义的区别

(1)声明是告诉编译器某个标识符(例如变量、函数或类型)的存在和它的类型,但不为它分配内存空间。声明的主要目的是让编译器知道在后续的代码中将使用这个标识符,并且了解如何正确地处理它。
    int x; // 声明一个整型变量x
(2)定义是为一个标识符分配内存空间,并且(对于变量)可能还会给它一个初始值。对于函数,定义是提供函数体的地方,即函数实际执行的代码。
    int y = 10; // 定义一个整型变量y并初始化为10

2.在编程中,运算符可以根据其操作数的数量进行分类,主要分为单目运算符(Unary Operator)和双目运算符(Binary Operator),还有三目运算符(例如C语言中的条件运算符 ? :),但最常见的是单目和双目运算符。

  • ### 单目运算符(Unary Operator)
    ​
    单目运算符只需要一个操作数。以下是一些常见的单目运算符:
    ​
    - 递增(`++`):将操作数的值加1。例如,`x++` 或 `++x`。
    - 递减(`--`):将操作数的值减1。例如,`x--` 或 `--x`。
    - 取反(`!`):用于布尔值,如果操作数为真(true),则结果为假(false),反之亦然。
    - 正负号(`+` 和 `-`):用于数值,`+x` 返回 `x` 本身,`-x` 返回 `x` 的相反数。
    - 取地址(`&`):返回操作数的内存地址。
    - 解引用(`*`):用于指针,返回指针指向的值。
    - 位非(`~`):对操作数的每一位执行非操作。
    - `sizeof`:返回操作数或类型所占用的字节数。
    ​
    ### 双目运算符(Binary Operator)
    ​
    双目运算符需要两个操作数。以下是一些常见的双目运算符:
    ​
    - 加法(`+`):计算两个操作数的和。
    - 减法(`-`):从第一个操作数中减去第二个操作数。
    - 乘法(`*`):计算两个操作数的乘积。
    - 除法(`/`):将第一个操作数除以第二个操作数。
    - 取模(`%`):返回第一个操作数除以第二个操作数的余数。
    - 赋值(`=`):将右侧操作数的值赋给左侧操作数。
    - 比较运算符(`<`, `<=`, `>`, `>=`, `==`, `!=`):比较两个操作数的大小或是否相等。
    - 位运算符(`&`, `|`, `^`):对两个操作数的二进制表示进行位运算。
    - 逻辑运算符(`&&`, `||`):根据两个操作数的布尔值进行逻辑运算。
    - 移位运算符(`<<`, `>>`):将二进制表示向左或向右移动指定的位数。

1.%e

    %e 是用于 printf 函数中的一个格式说明符,它用于以科学记数法(exponential notation)输出浮点数。科学记数法通常以 "x.yyyyye±zz" 的形式表示一个数,其中 "x" 是单个非零数字,"yyyyy" 是小数部分,"zz" 是指数部分。
    当你使用 %e 格式说明符时,printf 会将一个浮点数打印为这种格式,其中小数点后面默认有六位数字(这取决于具体的实现,但六位是一个常见的默认值)
    小数点后保留了六位数字(由于四舍五入,最后一位可能与原始数字略有不同)

2.格式化输出

用法:
#include 
printf("字符串");//字符串多个字符的序列,printf就会输出 字符串
 
由于使用printf可能会输出各种数据的值,而直接写入printf的输出 "字符串" 就会当作字符 原样输出,
所以在printf的 "字符串" 中 可以包含一种叫做格式化字符,表示其中要输出的类型值,之后再添加具体的值
格式化字符:
%d: int类型
%hd:short类型
%ld:long类型
%u:unsigned int类型
%hu:unsigned short类型
%lu:unsigned long类型
%nd:n代表宽度。以n的宽度输出。不足补空格,大于n按实际长度输出。且右对齐
        %3d     以宽度为3的十进制格式输出,如果数据长度<3,在左边补空格,否则按实际长度输出。
%c:char类型
%f:float类型
%lf:double类型
%.mf        保留m位小数,遵循四舍五入
%n.mf       数据宽度为n,右对齐,且保留m位小数,遵循四舍五入
%o:以八进制格式
%x:以十六进行格式
%s:字符串格式
%e:浮点数的指数表示
 
printf("字符串+格式化字符",格式化字符的值1,格式化字符的值2,格式化字符的值3,格式化字符的值4,.....)
 
注意:格式化字符和值要对应起来

1.使用c语言将某个整数拆解得到每一位上的值,并将每个值赋值给一个变量,并且这个整数的位数不确定

    可以用数组来存储每个位置上的数字,再用数组的索引来得到该位置上对应的数据
#include 
​
int main() {
    int num, remainder, i = 0;
    int digits[100]; // 假设整数的位数不会超过 100
​
    printf("请输入一个整数: ");
    scanf("%d", &num);
​
    while (num!= 0) {
        remainder = num % 10;
        digits[i++] = remainder;
        num /= 10;
    }
​
    // 输出每一位数字
    for (int j = i - 1; j >= 0; j--) {
        printf("第%d位数字: %d\n", j + 1, digits[j]);
    }
​
    return 0;
}

2.整数的拆分

1.先逆序再逆序
	do{
		int d=x%10;
		t=t*10+d;
		x/=10;
	}while(x>0);
	do{
		int d=x%10;
		printf("%d",d);
		if(x>9){
			printf(" ");
		}
		x/=10;
	}while(x>0);
	但是只能适用于数字末尾没有零的数字
	2.使用求余和整除的方法
#include
int main(){
	int mask=10000;
	int x;
	scanf("%d",&x);
	do{
		int d=x/mask;
		printf("%d",d);
		if(mask>9){
			printf(" ");
		}
		x %=mask;
		mask/=10;
		printf("x=%d,mask=%d,d=%d\n",x,mask,d);
	}while(mask>0);
	return 0;
}
解决末尾为0的数字:更改判断的条件
	3.改进的代码
	int x;
	scanf("%d",&x);
	x=7;
	int mask=1;
	int t=x;
	while(t>9){
		t/=10;
		mask*=10;
	}
	printf("x=%d,mask=%d\n",x,mask);
	do{
		int d=x/mask;
		printf("%d",d);
		if (mask>9){
			printf(" ");
		}
		x%=mask;
		mask/=10;
	}while(mask>0);
	printf("\n");
重点:1.逆序代码
	do{
		int d=x%10;
		t=t%10+d;
		x/=10;
	}while(x>0);
	2.从右边开始得到数据
	while (num > 0) {
        digit = num % 10;
        printf("%d ", digit);
        num /= 10;
    }

1.获取某个数据的位数

一.使用具体的数字来比大小
二.使用循环将位数逐个递进
int first =1;
int i=0;
while(first<=n){
	first*=10;
	i++;
}

2.PHP

一.
	PHP(Hypertext Preprocessor)是一种广泛使用的开源服务器端脚本语言,主要用于Web开发,能够生成动态网页内容。它具有语法简单、易于学习和使用的特点,并且可以与多种数据库(如MySQL、Oracle等)进行交互。
二.
	PHP可以实现诸如用户注册、登录、文章发布、购物车管理等各种功能。许多知名的网站和应用程序都是使用PHP开发的。

3.RAM

一.
	RAM(Random Access Memory),即随机存取存储器,也叫主存,是与CPU直接交换数据的内部存储器。它可以随时读写,而且速度很快,通常作为操作系统或其他正在运行中的程序的临时数据存储媒介

1.字面量

	字面量是指在源代码中直接表示一个固定值的表示法
	比如,数字5、字符串'Hello',布尔值True或False都是字面量。他们是直接写在代码里的值,不是通过计算或者变量引用得到的

2.%p

%p`是 C 语言中的一个格式控制符,用于输出指针类型变量在内存中的地址值。指针变量的值实际上就是一个地址值,`%p`可以用来输出这个地址值。在使用`%p`时,需要将要输出的指针变量作为参数传递给`printf`函数,并使用`%p`格式控制符进行格式化输出。

3.malloc函数

malloc函数用于动态分配内存
void *malloc(size_t size);
malloc函数接受一个参数size,表示要分配的内存字节数。函数会在堆上分配指定大小的内存空间,并返回一个指向该内存空间的指针。如果分配失败,malloc函数会返回NULL。

使用malloc函数分配的内存需要通过free函数进行释放,以避免内存泄漏。

#include 
#include 

int main() {
    int *ptr;
    int n = 5;

    // 分配 n 个整数大小的内存空间
    ptr = (int *)malloc(n * sizeof(int));

    if (ptr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 使用分配的内存
    for (int i = 0; i < n; i++) {
        ptr[i] = i + 1;
    }

    // 输出分配的内存中的值
    for (int i = 0; i < n; i++) {
        printf("%d ", ptr[i]);
    }
    printf("\n");

    // 释放内存
    free(ptr);

    return 0;
}
在这个示例中,我们使用malloc函数分配了n个整数大小的内存空间,并将其赋值后进行输出,最后使用free函数释放了分配的内存。

1.argc和argv

一.
	在 C 语言中,argc和argv是main函数的两个参数,用于接收命令行参数。argc表示命令行参数的个数,argv是一个指针数组,其中每个元素都是一个指向命令行参数的指针。
#include 

int main(int argc, char *argv[]) {
    // 输出命令行参数的个数
    printf("argc = %d\n", argc);

    // 遍历命令行参数并输出
    for (int i = 0; i < argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }

    return 0;
}
	在上面的代码中,argc表示命令行参数的个数,包括程序名本身。argv是一个指针数组,其中每个元素都是一个指向命令行参数的指针。通过遍历argv数组,可以访问每个命令行参数。

2.restrict

	restrict是一个关键字,用于修饰指针。它告诉编译器,在该指针的生命周期内,其指向的对象不会被其他指针所引用

3.宏

	宏(Macro)是一种预处理指令,允许程序员定义在编译前进行替换的文本模式。宏定义使用#define预处理指令,并且它们可以在程序中的任何地方使用,以简化代码、提高可读性或者执行一些编译时的计算

4.给结构体的数据初始化

一.按顺序,不用写成员名称
struct Student {
    char name[50];
    int age;
    float score;
};

// 初始化结构体变量
struct Student student1 = {"Alice", 20, 85.5};
二.对成员逐个进行赋值
truct Student {
    char name[50];
    int age;
    float score;
};

// 声明结构体变量
struct Student student2;

// 对结构体成员进行赋值
strcpy(student2.name, "Bob");
student2.age = 21;
student2.score = 90.0;
三.指定成员进行初始化
struct Student {
    char name[50];
    int age;
    float score;
};

// 使用指定初始化器初始化结构体变量
struct Student student3 = {.age = 22, .name = "Charlie", .score = 88.0};

5.putchar和getchar

	putchar 和 getchar 是 C 语言标准库中的两个函数,分别用于向标准输出流(通常是终端或屏幕)输出一个字符和从标准输入流(通常是键盘)读取一个字符。这两个函数都定义在  头文件中。
	putchar
		putchar 函数的原型是:
		int putchar(int char);
		它接受一个整数参数,该整数通常表示一个字符的 ASCII 码值,然后把这个字符输出到标准输出流。虽然参数是 int 类型,但通常我们传递一个 char 类型的值,它会自动转换为 int。函数返回成功写入的字符,如果发生错误则返回 EOF
	getchar
		getchar 函数的原型是:
		int getchar(void);
		它不接受任何参数,并从标准输入流读取下一个字符,直到遇到换行符或 EOF。读取的字符作为 int 类型返回,以便能够表示所有可能的字符值以及特殊的 EOF 值。通常,我们可以将返回的 int 值赋值给一个 char 类型的变量,但需要注意处理可能的 EOF 值。

6.feof

feof()函数是一个标准库函数,用于检测文件结束标志(EOF)是否已设置在与给定文件流相关联的文件上。该函数定义在头文件中。

函数原型
int feof(FILE *stream);
参数
stream:指向FILE对象的指针,该对象标识要检查的文件流。
返回值
如果文件结束标志(EOF)已设置,则feof()函数返回非零值(真)。
如果文件结束标志(EOF)未设置,则返回零(假)。
使用场景
feof()函数通常用于在读取文件时检测是否已到达文件末尾。当使用如fscanf(), fgetc(), fgets()等函数从文件读取数据时,如果到达文件末尾,这些函数通常会设置EOF标志。通过检查feof()函数的返回值,程序可以确定是否继续读取操作或执行其他任务。

示例
下面是一个简单的示例,展示了如何使用feof()函数来逐字符读取文件内容,直到到达文件末尾:

#include 
#include 

int main() {
    FILE *file = fopen("example.txt", "r"); // 打开文件以读取
    if (file == NULL) {
        perror("无法打开文件");
        return EXIT_FAILURE;
    }

    int ch;
    while (!feof(file)) { // 循环直到到达文件末尾
        ch = fgetc(file); // 从文件读取一个字符
        if (ch != EOF) { // 检查是否读取到EOF
            putchar(ch); // 输出读取到的字符
        }
    }

    fclose(file); // 关闭文件
    return EXIT_SUCCESS;
}
注意:虽然上面的示例代码在大多数情况下都能正常工作,但使用feof()来预检测EOF在某些情况下可能会导致逻辑错误。特别是,当fgetc()返回EOF时,它通常意味着已经尝试读取文件末尾之后的位置。因此,更健壮的做法是检查fgetc()的返回值是否为EOF,而不是依赖feof()来预测EOF。

1.标准偏差

	准偏差,也称为标准差或Std Dev(Standard Deviation),是统计学中的一个重要概念。它用于度量数据分布的分散程度,具体来说是衡量数据值偏离算术平均值的程度。标准偏差越小,表示数据值越接近平均值,即数据的离散程度较低;反之,标准偏差越大,表示数据值越分散,即数据的离散程度较高。

	计算方法
	标准偏差的计算公式为:(S = \sqrt{\frac{\sum_{i=1}^{n}(x_i - \bar{x})^2}{n-1}}),其中 (x_i) 是每个数据点,(\bar{x}) 是数据的算术平均值,(n) 是数据点的数量。这个公式计算了每个数据点与平均值之间差的平方的平均值,然后取其平方根,从而得到标准偏差。

2.数组

#include 
 
int main()
{
   int data[5], i;
   printf("输入元素: ");
 
   for(i = 0; i < 5; ++i)
     scanf("%d", data + i);
 
   printf("你输入的是: \n");
   for(i = 0; i < 5; ++i)
      printf("%d\n", *(data + i));
 
   return 0;
}
中的data+i为什么能这样写?
	data + i 的含义:
	假设 data 是一个数组(比如 int data[5]; 定义了一个能存放 5 个整数的数组),在 C 语言中,数组名本身可以看作是指向数组首元素的指针。data + i 这个表达式利用了指针运算的特性,当 i 为 0 时,data + 0 就等价于 &data[0](即数组第一个元素的地址);当 i 为 1 时,data + 1 等价于 &data[1](第二个元素的地址),以此类推。这样在每一次循环中,scanf 函数就能通过 data + i 准确地获取到当前要存储输入数据的数组元素的地址,然后将从键盘输入读取到的整数依次存储到数组 data 的各个元素中,实现了逐个元素读入数据的功能。

3.calloc

	calloc是 C 语言标准库中的一个函数,其函数原型为void* calloc(size_t num, size_t size);。它的主要功能是在内存的堆区中分配一块连续的内存空间,并且会将这块内存空间中的每个字节初始化为 0。
其中,num表示要分配的元素个数,size表示每个元素的大小(单位是字节)。例如,calloc(5, sizeof(int))会分配一块足够存储 5 个int类型数据的内存空间,并且将这块空间里的每个字节都初始化为 0。

4.动态分配内存和静态分配内存

	动态内存分配的必要性(以数组为例)
	静态分配的局限性:
在程序设计中,有时候我们无法预先确定变量(如数组)的大小。如果使用静态分配,例如int arr[10];,数组的大小在编译时就确定为 10 个元素。但如果程序运行时需要根据用户输入或者其他动态因素来确定数组大小,这种静态分配方式就无法满足需求。
	例如,一个程序需要读取用户输入的一组数字并存储起来,用户输入的数字数量可能每次都不同。如果采用静态分配数组,要么数组太大浪费内存(当用户输入的数字很少时),要么数组太小无法存储全部数据(当用户输入的数字很多时)。
	动态分配的优势:
	通过动态内存分配函数(如malloc、calloc等),可以在程序运行时根据实际需要来分配内存。例如,使用int* arr = (int*)malloc(n * sizeof(int));(其中n是根据实际情况确定的变量),就可以在程序运行过程中,根据n的值动态地分配足够存储n个整数的内存空间,使得程序能够更加灵活地处理各种情况。

5.stdin

	stdin 是 C 语言中的一个宏定义,代表“标准输入流”(Standard Input Stream)。在 Unix 和类 Unix 系统中,这通常指的是从键盘接收输入的流。在程序中,你可以使用 stdin 来从控制台读取用户输入。

	例如,在 C 语言中,你可以使用 scanf、fgets 等函数来从 stdin 读取数据。这些函数内部会使用 stdin 作为默认的输入流,除非你明确指定了其他的输入流。

6.后缀运算符

	函数调用运算符 ():用于调用函数,例如 printf("Hello, World!"); 中的 () 表示调用 printf 函数。
	数组下标运算符 []:用于访问数组中的元素,例如 int arr[10]; arr[5] = 100; 中的 [] 表示访问数组 arr 的第6个元素(下标从0开始)。
	结构体或联合体成员访问运算符 . 或 ->:用于访问结构体或联合体的成员,例如 struct Person { int age; }; struct Person p; p.age = 30; 中的 . 表示访问结构体 p 的 age 成员。如果结构体指针被使用,则使用 -> 运算符,如 struct Person *ptr = &p; ptr->age = 35;。
	后缀自增运算符 ++:用于将变量的值增加1,例如 int x = 5; x++; 中的 ++ 表示将 x 的值从5增加到6。这是后缀形式,意味着先返回变量的原始值,然后再执行增加操作。
	后缀自减运算符 --:用于将变量的值减少1,与后缀自增运算符类似,但执行的是减少操作。
  1. scanf("%\n", line);

	在C语言中,%[^\n] 是一个用于 scanf 函数中的格式说明符,它有着特殊的含义和用途。这个格式说明符用于读取一个字符串,直到遇到换行符 \n 为止。换句话说,它会连续读取输入中的字符,并将其存储到指定的字符数组中,直到遇到换行符为止。

	这里是对 %[^\n] 的详细解释:

	%:表示这是一个格式说明符的开始。
	[:表示开始指定一个字符集。
	^:表示取字符集的补集,即读取不在指定字符集中的字符。
	\n:表示换行符。
	]:表示字符集的结束。
	因此,%[^\n] 表示读取除换行符之外的所有字符。

	在使用 %[^\n] 时,通常需要为 scanf 函数提供一个字符数组来存储读取的字符串,并且还需要指定一个最大宽度来防止缓冲区溢出。例如:

	char buffer[100];
	scanf("%99[^\n]", buffer); // 读取最多99个字符,直到遇到换行符
	在这个例子中,buffer 是一个大小为100的字符数组,用于存储读取的字符串。%99[^\n] 指定了最大宽度为99,这意味着 scanf 将读取最多99个字符(留下一个位置给字符串的终止符 \0),直到遇到换行符为止。

	需要注意的是,如果在使用 %[^\n] 之前已经有其他输入操作,并且输入缓冲区中还存在未处理的换行符,那么 %[^\n] 可能会立即失败,因为它会立即遇到换行符。在这种情况下,可能需要先使用其他方法来清除或跳过换行符。
	总之就是可以用于用户输入空格时不会当成两个字符串,而是当成一个字符串(平常的话空格和换行都是会让程序识别成进入下一个过程)

8.memset

	memset是C语言中的一个库函数,用于将指定的内存块设置为特定的值。它的原型为void *memset(void *ptr, int value, size_t num),其中ptr是指向要设置的内存块的指针,value是要设置的值,num是要设置的字节数。
	memset是C语言中的一个库函数,用于将指定的内存块设置为特定的值。它的原型为void *memset(void *ptr, int value, size_t num),其中ptr是指向要设置的内存块的指针,value是要设置的值,num是要设置的字节数。

以下是关于memset函数的详细解释和用法:

一、功能

	memset函数主要用于初始化内存块,通常用于以下几种情况:

	初始化数组:可以使用memset函数将数组的所有元素设置为特定的值,如0或-1。这对于需要重置数组或分配新内存时非常有用。

	清空字符串或缓冲区:memset函数也可以用于清空字符串或缓冲区,将其内容设置为特定的字符,通常是空字符(\0)以表示字符串结束,或者用于清除敏感数据。

	设置特定值:除了初始化和清空操作外,memset函数还可以用于将内存块设置为特定的值。然而,需要注意的是,由于memset函数按字节设置值,因此当设置非字符类型的数组时,需要确保设置的值与数组类型兼容。

二、用法

	使用memset函数时,需要包含头文件。以下是memset函数的一些常见用法示例:

	初始化数组为0:

int arr[10];
memset(arr, 0, sizeof(arr)); // 将数组arr的所有元素设置为0
	清空字符串:

char str[100];
memset(str, '\0', sizeof(str)); // 将字符串str清空
	设置特定值(需要注意类型兼容性):

char buffer[100];
memset(buffer, 'A', sizeof(buffer)); // 将缓冲区buffer的所有字节设置为字符'A'
三、注意事项

	在使用memset函数时,需要注意以下几点:

	确保指针ptr指向有效的内存块,并且该内存块的大小至少为num字节,以避免访问非法内存区域或导致缓冲区溢出。

	当设置非字符类型的数组时,要特别注意值的兼容性。由于memset函数按字节设置值,因此可能会导致意想不到的结果。例如,将整型数组设置为非零值时,每个元素可能会被设置为不同的值,具体取决于系统和编译器的实现。

	对于复杂的数据结构(如结构体包含指针成员),使用memset函数进行初始化或清空操作时需要格外小心,以避免内存泄漏或错误的结果。在这种情况下,最好使用其他方法进行初始化和清空操作。

9.exit()函数

	exit 函数是 C 语言标准库中的一个函数,用于立即终止程序的执行,并返回一个状态码到操作系统。这个函数的原型通常定义在  头文件中。

	函数的原型如下:

	void exit(int status);
	其中,status 参数是一个整数,表示程序退出时的状态码。这个状态码可以被操作系统或其他调用程序捕获,以判断程序是正常结束还是遇到了错误。

	如果 status 为 0 或 EXIT_SUCCESS(在  中定义的一个宏,通常值为 0),则表示程序正常退出。
	如果 status 为非 0 值或 EXIT_FAILURE(同样在  中定义的一个宏,通常为一个非 0 值,如 1),则表示程序因为某种错误或异常情况而退出。
	使用 exit 函数时,程序会立即停止执行,不会返回到调用者。在程序退出前,C 运行时库会执行一些清理工作,如关闭所有打开的文件、释放由库分配的内存资源等。然而,它不会自动释放由程序员分配的资源(如使用 malloc 分配的内存),因此在调用 exit 之前,程序员应该确保手动释放这些资源。

1.static

	静态全局变量和函数: 在文件作用域(全局作用域)中,static用于限制全局变量或函数的链接属性为内部链接。这意味着这些变量或函数只能在定义它们的源文件中被访问,而不能被其他源文件访问。这有助于封装和隐藏实现细节。

2.字符串字面量

	字符串字面量是指在源代码中直接使用双引号括起来的一系列字符。这些字符在编译时会被分配内存空间,并存储为字符串类型的数据。字符串字面量是程序中表示文本数据的常用方式之一
	内存分配:
	当编译器遇到字符串字面量时,它会在内存中为该字符串分配空间。
这个空间通常比字符串的实际字符数多1,用于存储字符串的结束符'\0'(空字符)。

3.逆序处理

一.printf
	求余后直接输出,不换行
二.转换成字符串处理
	在C语言中,要逆序一个末尾可能为零的整数,并且希望保留这些末尾零,最好的方法是先将整数转换为字符串,逆序字符串,然后再根据需要处理结果。由于整数类型不会存储前导零(在逆序后就变成了末尾零),所以必须以字符串的形式来处理。

以下是一个简单的C语言函数,用于逆序一个整数,同时保留末尾的零:

#include 
#include 
#include 

// 函数:逆序整数,并保留末尾零(以字符串形式返回)
char* reverseIntegerWithTrailingZeros(int num) {
    char str[50]; // 假设整数转换后的字符串不会超过49个字符
    sprintf(str, "%d", num); // 将整数转换为字符串
    
    int len = strlen(str);
    char *reversed = (char*)malloc((len + 1) * sizeof(char)); // 为逆序字符串分配内存
    if (!reversed) {
        return NULL; // 内存分配失败,返回NULL
    }
    
    int j = 0;
    // 逆序字符串,同时跳过前导零(逆序后的末尾零)
    for (int i = len - 1; i >= 0; --i) {
        if (j == 0 && str[i] == '0') {
            continue; // 跳过前导零
        }
        reversed[j++] = str[i];
    }
    reversed[j] = '\0'; // 添加字符串结束符

    // 如果逆序后的字符串为空(原数字为0),则直接返回"0"
    if (j == 0) {
        strcpy(reversed, "0");
    }
    
    return reversed;
}

int main() {
    int num = 123000; // 示例整数,末尾有多个零
    char* reversedStr = reverseIntegerWithTrailingZeros(num);
    if (reversedStr) {
        printf("Reversed number (with trailing zeros): %s\n", reversedStr);
        free(reversedStr); // 释放动态分配的内存
    } else {
        printf("Memory allocation failed.\n");
    }
    return 0;
}
在这个例子中,reverseIntegerWithTrailingZeros 函数接受一个整数,将其转换为字符串,然后逆序这个字符串,同时跳过逆序后字符串的末尾零(即原数字的前导零)。函数返回一个新的动态分配的字符串,其中包含逆序后的数字(带末尾零)。调用者需要负责在使用完毕后释放这块内存。

请注意,由于这个函数返回的是字符串,因此它保留了末尾的零。如果你需要以整数形式处理逆序后的数字,并且希望保留末尾的零,那么这是不可能的,因为整数类型不会存储末尾的零。在这种情况下,你必须以字符串的形式来处理这个数字。

1.单一出口

	单一出口原则在编程领域指的是一个函数或模块应该只有一个出口点,即所有的执行路径最终都应该通过同一个语句返回。这一原则的目的在于增强代码的可读性和可维护性,使得函数或模块的逻辑更加清晰。当需要调整函数的行为时,程序员只需要关注这一个出口点,而不是在多个可能的返回语句中追踪逻辑。

2.qsort

qsort函数是C语言标准库中的一个函数,用于对数组进行快速排序。以下是qsort函数的详细用法:

一、函数原型

c复制
void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *));
二、参数解释

void *base:指向要排序的数组的首元素的指针。
size_t num:数组中元素的个数,即数组的大小。
size_t size:每个元素的大小,单位是字节。通常使用sizeof()函数来计算元素的大小。
int (*compar)(const void *, const void *):一个函数指针,指向比较函数。比较函数用于确定两个元素的排序顺序。它接受两个const void *类型的指针作为参数(分别指向要比较的两个元素),并返回一个整数值来表示这两个元素的相对顺序。
三、比较函数的返回值

如果第一个元素小于第二个元素,比较函数应返回一个负值。
如果第一个元素等于第二个元素,比较函数应返回0。
如果第一个元素大于第二个元素,比较函数应返回一个正值。
四、使用步骤

包含头文件:#include 
定义比较函数,根据需要比较的元素类型来编写。例如,对于整型数组,比较函数可以如下所示:
c复制
int compare(const void *a, const void *b) {
    int int_a = *((int*) a);
    int int_b = *((int*) b);
    return (int_a - int_b);
}
调用qsort函数进行排序:qsort(array, num_elements, element_size, compare); 其中array是要排序的数组,num_elements是数组中的元素个数,element_size是每个元素的大小(使用sizeof()计算),compare是比较函数的指针。
五、示例

以下是一个使用qsort函数对整型数组进行排序的示例:

示例1
#include 
#include 

int compare(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int numbers[] = {44, 78, 34, 12, 40, 85, 36};
    int n = sizeof(numbers) / sizeof(numbers[0]);
    qsort(numbers, n, sizeof(int), compare);
    for (int i = 0; i < n; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}

示例2
#include 
#include 

// 比较函数,用于整型比较
int compare_ints(const void *a, const void *b) {
    const int *ia = (const int *)a;
    const int *ib = (const int *)b;
    return (*ia - *ib);
}

int main() {
    int arr[] = {5, 3, 8, 1, 2};
    int n = sizeof(arr) / sizeof(arr[0]);

    qsort(arr, n, sizeof(int), compare_ints);

    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}
六、注意事项

qsort函数可以排序任意类型的数组元素,只需相应地编写比较函数即可。
比较函数中的指针强制类型转换和解引用操作是必要的,因为比较函数接收的是void *类型的指针,需要转换为具体的元素类型才能进行比较。

七.比较函数的作用原理
	比较函数接受两个指向待比较元素的指针作为参数,通过比较这两个元素的大小关系,返回一个整数值来表示它们的顺序。
	1.如果比较函数返回值小于 0,表示第一个元素小于第二个元素,qsort函数会将第一个元素排在第二个元素之前。
	2.如果返回值等于 0,表示两个元素相等,qsort函数不会交换这两个元素的位置。
	3.如果返回值大于 0,表示第一个元素大于第二个元素,qsort函数会将第一个元素排在第二个元素之后。

3.string.h

一.strcat
	1.函数原型 strcat函数的原型通常为 char *strcat(char *dest, const char *src);。这个函数接受两个参数:dest是目标字符串,即需要追加内容的字符串;src是源字符串,即要追加到目标字符串后面的内容。

	2.功能 strcat函数会将src的内容追加到dest的末尾,并返回dest的指针。需要注意的是,dest必须有足够的空间来容纳连接后的新字符串,否则可能会导致缓冲区溢出。

二.strchr
strchr是C语言中的一个标准库函数,用于在字符串中查找第一次出现指定字符的位置。下面是对strchr函数的详细解释:

	1.函数原型 strchr函数的原型是char *strchr(const char *str, int c);。其中,str是要搜索的字符串,c是要查找的字符(以整数形式表示,即字符的ASCII值)。

	2.功能 strchr函数会在字符串str中从头开始搜索,直到找到第一个与字符c匹配的字符。如果找到了匹配的字符,函数会返回一个指向该字符在str中首次出现位置的指针。如果没有找到匹配的字符,函数会返回NULL。

	3.使用注意事项

strchr函数对大小写敏感,因此它会区分大写和小写字母。
如果要查找的字符在字符串中出现了多次,strchr函数只返回第一次出现的位置。
在使用strchr函数时,需要确保传入的字符串str不是NULL,以避免空指针解引用的错误。
	4,示例代码 下面是一个简单的示例代码,展示了如何使用strchr函数在字符串中查找指定字符的位置:

#include 
#include 

int main() {
    const char *str = "Hello, World!";
    char c = 'o';
    char *result = strchr(str, c);
    if (result != NULL) {
        printf("字符 '%c' 在字符串中第一次出现的位置是: %ld\n", c, result - str + 1);
    } else {
        printf("字符 '%c' 在字符串中未找到\n", c);
    }
    return 0;
}
三.strstr
`strstr`是C语言中的一个标准库函数,用于在一个字符串(称为“主字符串”)中查找另一个字符串(称为“子字符串”)的首次出现。以下是关于`strstr`函数的详细解释:

	1.函数原型
`strstr`函数的原型定义在``头文件中,其基本语法为:`char *strstr(const char *haystack, const char *needle);`。其中,`haystack`是指向要搜索的主字符串的指针,而`needle`是指向要查找的子字符串的指针。

	2.功能
`strstr`函数会返回指向`haystack`中第一次出现`needle`的位置的指针。如果未找到子字符串,则返回`NULL`。

	3.使用注意事项

	(1)strstr`函数是区分大小写的,这意味着它会将大写和小写字母视为不同的字符。
	(2)在使用`strstr`函数时,应确保传入的指针(特别是`haystack`)不是`NULL`,以避免潜在的运行时错误。
	(3)返回的指针指向的是主字符串中的子字符串,因此,对返回指针的任何修改都可能影响原始主字符串。在使用返回指针时应谨慎,以避免越界访问或内存损坏。

	4.示例代码
下面是一个简单的示例代码,展示了如何使用`strstr`函数:

#include 
#include 

int main() {
    const char *haystack = "Hello, World!";
    const char *needle = "World";
    char *result = strstr(haystack, needle);
    
    if (result != NULL) {
        printf("Found substring: %s\n", result);
    } else {
        printf("Substring not found.\n");
    }
    
    return 0;
}

4.我现阶段弄的叫做文件操作而不叫文本操作

1.八进制转义字符和十六进制转义字符(重新去了解一下)

表示方法
八进制转义字符:以反斜杠(\)开头,后面跟着 1 到 3 位的八进制数字,范围是\0到\377。
十六进制转义字符:以反斜杠(\)开头,后面跟着x或X,再跟上 1 到 2 位的十六进制数字,范围是\x00到\xFF。
作用
用于表示那些无法直接在源程序中输入的特殊字符,如换行符、制表符等控制字符。
通过指定字符的 ASCII 码值,来表示 ASCII 码表中的任意字符。
使用示例

c
#include 

int main() {
    // 八进制转义字符表示字符'A'
    char octalChar = '\101';
    // 十六进制转义字符表示字符'A'
    char hexChar = '\x41';

    // 输出字符
    printf("八进制转义字符表示的字符:%c\n", octalChar);
    printf("十六进制转义字符表示的字符:%c\n", hexChar);

    // 八进制转义字符表示换行符
    printf("Hello\012World\n");
    // 十六进制转义字符表示换行符
    printf("Hello\x0AWorld\n");

    return 0;
}

注意事项
八进制转义字符:最多只能有 3 位八进制数字,超出部分会被解析为多个字符;取值范围是\0到\377,超出此范围结果未定义。
十六进制转义字符:最多只能有 2 位十六进制数字,超出部分会被解析为多个字符;取值范围是\x00到\xFF,超出此范围结果未定义。
八进制转义字符和十六进制转义字符为程序员在处理字符数据时提供了更多的灵活性,方便表示各种特殊字符和通过 ASCII 码值来精确控制字符的使用。在实际应用中,可根据具体需求和个人习惯选择使用合适的转义字符形式。

你可能感兴趣的:(c语言,java,开发语言)