赞
踩
冒泡排序是一种简单的排序算法,其基本思想是重复遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就交换它们的位置。遍历数列的工作重复进行直到没有再需要交换。
步骤:
示例代码:
#include <stdio.h> void bubbleSort(int arr[], int n) { for (int i = 0; i < n-1; i++) { for (int j = 0; j < n-i-1; j++) { if (arr[j] > arr[j+1]) { // 交换 arr[j] 和 arr[j+1] int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } void printArray(int arr[], int size) { for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[] = {64, 34, 25, 12, 22, 11, 90}; int n = sizeof(arr)/sizeof(arr[0]); bubbleSort(arr, n); printf("Sorted array: \n"); printArray(arr, n); return 0; }
输出:
Sorted array:
11 12 22 25 34 64 90
memset
memset
是一个标准C库函数,用于设置一块内存区域中的所有字节为指定的值。它的原型在头文件 string.h
中声明:
void *memset(void *s, int c, size_t n);
s
:指向要填充的内存块的指针。c
:要设置的值。注意,该值会被转换为无符号字符,然后用于填充内存块。n
:要填充的字节数。memset
返回指向内存块 s
的指针。memset
通常用于初始化数组或结构体,或将一块内存区域清零。
示例1:初始化字符数组
#include <stdio.h> #include <string.h> int main() { char buffer[10]; // 将 buffer 的前 10 个字节设置为字符 'A' memset(buffer, 'A', sizeof(buffer)); // 打印 buffer 内容 for (int i = 0; i < sizeof(buffer); i++) { printf("%c ", buffer[i]); } printf("\n"); return 0; }
输出:
A A A A A A A A A A
示例2:清零整数数组
#include <stdio.h> #include <string.h> int main() { int numbers[10]; // 将 numbers 数组的内存区域设置为 0 memset(numbers, 0, sizeof(numbers)); // 打印 numbers 数组内容 for (int i = 0; i < 10; i++) { printf("%d ", numbers[i]); } printf("\n"); return 0; }
输出:
0 0 0 0 0 0 0 0 0 0
示例3:初始化结构体
#include <stdio.h> #include <string.h> struct Data { int id; char name[20]; float value; }; int main() { struct Data item; // 将结构体 item 的内存区域清零 memset(&item, 0, sizeof(item)); // 打印结构体成员的初始值 printf("id: %d, name: %s, value: %.2f\n", item.id, item.name, item.value); return 0; }
输出:
id: 0, name: , value: 0.00
c
被转换为无符号字符,因此它的实际效果是将每个字节设置为 c
的最低 8 位。这意味着,如果 c
超过了 0-255 的范围,高位部分将被忽略。memset
通常是非常高效的,因为它是一个库函数,通常会针对特定硬件进行优化。n
不超过目标内存区域的大小,否则会导致缓冲区溢出,可能引发严重的错误。在C语言中,scanf
函数用于从标准输入读取数据,并根据指定的格式存储到变量中。不同的格式说明符(如 %c
和 %s
)在处理输入时有不同的行为。
scanf
中的 %c
格式说明符%c
格式说明符用于读取单个字符。%c
将读取输入缓冲区中的下一个字符,不会跳过空白字符。示例1:读取单个字符
#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
scanf("%c", &ch);
printf("You entered: '%c'\n", ch);
return 0;
}
示例2:读取多个字符,包括空格和换行符
#include <stdio.h>
int main() {
char ch1, ch2;
printf("Enter two characters separated by a space: ");
scanf("%c%c", &ch1, &ch2);
printf("You entered: '%c' and '%c'\n", ch1, ch2);
return 0;
}
scanf
中的 %s
格式说明符%s
格式说明符用于读取字符串。%s
读取字符串时,以空格、换行符或制表符作为分隔符,并在遇到这些分隔符时结束读取。示例3:读取字符串
#include <stdio.h>
int main() {
char str[100];
printf("Enter a string: ");
scanf("%s", str);
printf("You entered: '%s'\n", str);
return 0;
}
有时我们需要结合使用 %c
和 %s
格式说明符来处理更复杂的输入场景。
示例4:读取包含空格的字符串
如果需要读取包含空格的字符串,可以使用 fgets
函数,而不是 scanf
。 fgets
可以读取整行输入,包括空格和换行符。
#include <stdio.h>
int main() {
char str[100];
printf("Enter a string: ");
fgets(str, sizeof(str), stdin);
// 去掉字符串末尾的换行符(如果有)
str[strcspn(str, "\n")] = '\0';
printf("You entered: '%s'\n", str);
return 0;
}
当使用 scanf
读取字符时,如果希望跳过空白字符,可以在格式说明符前添加一个空格。
示例5:跳过空白字符
#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
scanf(" %c", &ch); // 在%c前加一个空格,跳过空白字符
printf("You entered: '%c'\n", ch);
return 0;
}
以下示例展示了如何读取字符和字符串,并处理输入中的空白字符:
#include <stdio.h> int main() { char ch; char str[100]; printf("Enter a character: "); scanf(" %c", &ch); // 跳过前导空白字符,读取单个字符 printf("You entered: '%c'\n", ch); // 清空输入缓冲区,确保后续输入不受前一次输入影响 while (getchar() != '\n'); printf("Enter a string: "); fgets(str, sizeof(str), stdin); str[strc spn(str, "\n")] = '\0'; // 去掉换行符 printf("You entered: '%s'\n", str); return 0; }
gets
输入,puts
输出gets
用来输入一行字符串,以换行符作为输入结束。puts
输出结束后自动跟上一个换行符。下面是一个表格详细描述了 gets
、getchar
和 scanf
的结束方式:
函数 | 描述 | 结束条件 | 是否包含空白字符 |
---|---|---|---|
gets | 从标准输入读取一行 | 读取到换行符('\n' ) | 是 |
getchar | 从标准输入读取一个字符 | 读取到一个字符 | 是 |
scanf | 从标准输入读取指定格式的数据 | 取决于格式说明符和输入 | 取决于格式说明符 |
gets
gets
会将换行符替换为字符串终止符('\0'
)。'\n'
)。gets
会读取空白字符(如空格、制表符)作为字符串的一部分。gets
函数由于无法控制输入长度,容易引发缓冲区溢出问题,已在C11标准中被弃用。推荐使用 fgets
代替。getchar
getchar
会读取任何字符,包括空白字符(如空格、换行符、制表符)。scanf
scanf
根据格式说明符解析输入,并在遇到与格式不匹配的字符或空白字符时停止。%c
:读取单个字符,包括空白字符。%s
:读取字符串,遇到空白字符(如空格、换行符、制表符)时结束。%d
, %f
):根据输入格式,空白字符会被跳过。gets
(不推荐使用)#include <stdio.h>
int main() {
char str[100];
printf("Enter a string: ");
gets(str);
printf("You entered: '%s'\n", str);
return 0;
}
fgets
(推荐使用)#include <stdio.h>
int main() {
char str[100];
printf("Enter a string: ");
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0'; // 去掉换行符
printf("You entered: '%s'\n", str);
return 0;
}
getchar
#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
ch = getchar();
printf("You entered: '%c'\n", ch);
return 0;
}
scanf
读取单个字符
#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
scanf(" %c", &ch); // 跳过前导空白字符
printf("You entered: '%c'\n", ch);
return 0;
}
读取字符串
#include <stdio.h>
int main() {
char str[100];
printf("Enter a string: ");
scanf("%s", str); // 读取字符串,遇到空白字符结束
printf("You entered: '%s'\n", str);
return 0;
}
在C语言中,字符数组(即字符串)的存储方式有几种重要的特性需要注意,其中最重要的是以空字符(\0
)作为字符串的结束标志。
\0
在C语言中,字符串实际上是以空字符 \0
结尾的字符数组。这种结尾字符用于标识字符串的结束,这对于字符串操作函数(如 strlen
、strcpy
、strcat
等)非常重要,因为这些函数依赖 \0
来判断字符串的边界。
#include <stdio.h>
int main() {
// 定义一个字符数组并初始化为一个字符串
char str[] = "Hello, World!";
// 手动查看字符数组的每个元素
for (int i = 0; i < sizeof(str); i++) {
printf("str[%d] = '%c' (ASCII: %d)\n", i, str[i], str[i]);
}
return 0;
}
输出:
str[0] = 'H' (ASCII: 72)
str[1] = 'e' (ASCII: 101)
str[2] = 'l' (ASCII: 108)
str[3] = 'l' (ASCII: 108)
str[4] = 'o' (ASCII: 111)
str[5] = ',' (ASCII: 44)
str[6] = ' ' (ASCII: 32)
str[7] = 'W' (ASCII: 87)
str[8] = 'o' (ASCII: 111)
str[9] = 'r' (ASCII: 114)
str[10] = 'l' (ASCII: 108)
str[11] = 'd' (ASCII: 100)
str[12] = '!' (ASCII: 33)
str[13] = '\0' (ASCII: 0)
分配空间:定义字符数组时,必须为 \0
预留空间。例如,要存储 “Hello” 字符串,需要一个长度为 6 的字符数组,因为它需要一个额外的空间来存储 \0
。
初始化:初始化字符数组时,如果使用字符串常量初始化,编译器会自动添加 \0
。例如,char str[] = "Hello";
自动会在字符串的末尾添加 \0
。
操作字符串:使用字符串处理函数时,必须确保字符串以 \0
结束,否则会导致未定义行为,因为这些函数会一直读取,直到找到 \0
。
\0
有时候需要手动操作字符数组,在这种情况下,必须确保在适当的位置添加 \0
以保证字符串正确结束。
示例:
#include <stdio.h>
int main() {
char str[6]; // 为 "Hello" 字符串分配空间,包含 \0
str[0] = 'H';
str[1] = 'e';
str[2] = 'l';
str[3] = 'l';
str[4] = 'o';
str[5] = '\0'; // 手动添加 \0 结束符
printf("String is: %s\n", str);
return 0;
}
输出:
String is: Hello
如果不使用scanf%s或者gets函数输入字符串,如使用getchar输入,则一定要输入的每个字符串后面加‘/0’,否则printf和puts输出字符串会因为无法识别字符串末尾二输出一大堆乱码
getchar
输入字符串#include <stdio.h> int main() { char str[100]; int i = 0; char ch; printf("Enter a string: "); while (i < sizeof(str) - 1) { // 确保不超出字符数组的大小 ch = getchar(); if (ch == '\n' || ch == EOF) { break; // 遇到换行符或文件结束符时结束输入 } str[i++] = ch; } str[i] = '\0'; // 手动添加字符串结束符 printf("You entered: '%s'\n", str); puts(str); // 使用 puts 输出字符串 return 0; }
char str[100];
定义一个大小为 100 的字符数组,用于存储输入的字符串。getchar()
逐字符读取输入,直到遇到换行符或文件结束符(EOF)。\0
结束符,确保字符串正确结束。printf
或 puts
输出字符串。\0
结束符:在输入结束后,手动在数组最后添加字符串结束符 \0
,确保字符串正确结束。\n
)和文件结束符(EOF),确保输入正确结束。如果需要处理输入中包含空格的字符串,可以使用以下方法:
#include <stdio.h> int main() { char str[100]; int i = 0; char ch; printf("Enter a string (including spaces): "); while (i < sizeof(str) - 1) { ch = getchar(); if (ch == '\n' || ch == EOF) { break; } str[i++] = ch; } str[i] = '\0'; // 添加字符串结束符 printf("You entered: '%s'\n", str); puts(str); return 0; }
Enter a string (including spaces): Hello, World!
You entered: 'Hello, World!'
Hello, World!
getchar
进行字符串输入时的正确性和安全性。string.h
头文件strlen()
strlen
函数用于计算字符串的长度(不包括末尾的空字符)。它的原型在头文件 string.h
中声明:
size_t strlen(const char *str);
str
:指向以空字符 \0
结尾的字符串。#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
size_t len = strlen(str);
printf("Length of the string '%s' is: %zu\n", str, len);
return 0;
}
输出:
Length of the string 'Hello, World!' is: 13
strlen
不计算字符串末尾的空字符 \0
。strlen
的字符串不是以空字符结尾的,将会引发未定义行为。sscanf == string + scanf
sprintf == string + printf
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。