欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 3.数组基础

3.数组基础

2025/2/24 16:45:12 来源:https://blog.csdn.net/weixin_51147313/article/details/140319712  浏览:    关键词:3.数组基础

文章目录

    • 4.1 冒泡排序
      • 冒泡排序算法
    • 4.2 `memset`
      • 参数说明
      • 返回值
      • 基本用法
      • 注意事项
    • 4.3 字符数组
      • 4.3.1`scanf` 中的 `%c` 格式说明符
      • 4.3.2 `scanf` 中的 `%s` 格式说明符
      • 结合使用
      • 处理输入中的空白字符
      • 组合示例
      • 4.3.3 `gets` 输入,`puts` 输出
      • 对比
      • 详细说明
      • 示例代码
        • `gets`(不推荐使用)
        • `fgets`(推荐使用)
        • `getchar`
        • `scanf`
      • 4.3.4 字符数组存放方式
      • 结束符 `\0`
      • 示例
      • 注意事项
      • 手动添加 `\0`
      • 注意
      • 示例代码:使用 `getchar` 输入字符串
      • 详细步骤
      • 关键点
      • 示例代码:处理空格的字符串输入
      • 示例输出
    • 通过正确处理输入字符和手动添加字符串结束符,可以确保使用 `getchar` 进行字符串输入时的正确性和安全性。
    • 4.4 `string.h` 头文件
      • 4.4.1 `strlen()`
      • 参数说明
      • 返回值
      • 示例代码
      • 注意事项
      • 4.4.2 sscanf与sprintf

4.1 冒泡排序

冒泡排序是一种简单的排序算法,其基本思想是重复遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就交换它们的位置。遍历数列的工作重复进行直到没有再需要交换。

冒泡排序算法

步骤:

  1. 比较相邻的元素。如果第一个比第二个大,就交换它们。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。完成后,最后的元素就是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

示例代码:

#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 

4.2 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 数组的内存区域设置为 0memset(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

注意事项

  1. 值转换:参数 c 被转换为无符号字符,因此它的实际效果是将每个字节设置为 c 的最低 8 位。这意味着,如果 c 超过了 0-255 的范围,高位部分将被忽略。
  2. 性能考虑memset 通常是非常高效的,因为它是一个库函数,通常会针对特定硬件进行优化。
  3. 安全性:确保 n 不超过目标内存区域的大小,否则会导致缓冲区溢出,可能引发严重的错误。

4.3 字符数组

在C语言中,scanf函数用于从标准输入读取数据,并根据指定的格式存储到变量中。不同的格式说明符(如 %c%s)在处理输入时有不同的行为。

4.3.1scanf 中的 %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;
}

4.3.2 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 函数,而不是 scanffgets 可以读取整行输入,包括空格和换行符。

#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[strcspn(str, "\n")] = '\0';  // 去掉换行符printf("You entered: '%s'\n", str);return 0;
}

4.3.3 gets 输入,puts 输出

  • gets 用来输入一行字符串,以换行符作为输入结束。
  • puts 输出结束后自动跟上一个换行符。

对比

下面是一个表格详细描述了 getsgetcharscanf 的结束方式:

函数描述结束条件是否包含空白字符
gets从标准输入读取一行读取到换行符('\n'
getchar从标准输入读取一个字符读取到一个字符
scanf从标准输入读取指定格式的数据取决于格式说明符和输入取决于格式说明符

详细说明

  1. gets

    • 描述:从标准输入读取一行字符串,直到遇到换行符。gets 会将换行符替换为字符串终止符('\0')。
    • 结束条件:遇到换行符('\n')。
    • 是否包含空白字符:包含。gets 会读取空白字符(如空格、制表符)作为字符串的一部分。
    • 注意gets 函数由于无法控制输入长度,容易引发缓冲区溢出问题,已在C11标准中被弃用。推荐使用 fgets 代替。
  2. getchar

    • 描述:从标准输入读取一个字符并返回。
    • 结束条件:读取到一个字符。
    • 是否包含空白字符:包含。getchar 会读取任何字符,包括空白字符(如空格、换行符、制表符)。
  3. 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;
}

4.3.4 字符数组存放方式

在C语言中,字符数组(即字符串)的存储方式有几种重要的特性需要注意,其中最重要的是以空字符(\0)作为字符串的结束标志。

结束符 \0

在C语言中,字符串实际上是以空字符 \0 结尾的字符数组。这种结尾字符用于标识字符串的结束,这对于字符串操作函数(如 strlenstrcpystrcat 等)非常重要,因为这些函数依赖 \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)

注意事项

  1. 分配空间:定义字符数组时,必须为 \0 预留空间。例如,要存储 “Hello” 字符串,需要一个长度为 6 的字符数组,因为它需要一个额外的空间来存储 \0

  2. 初始化:初始化字符数组时,如果使用字符串常量初始化,编译器会自动添加 \0。例如,char str[] = "Hello"; 自动会在字符串的末尾添加 \0

  3. 操作字符串:使用字符串处理函数时,必须确保字符串以 \0 结束,否则会导致未定义行为,因为这些函数会一直读取,直到找到 \0

手动添加 \0

有时候需要手动操作字符数组,在这种情况下,必须确保在适当的位置添加 \0 以保证字符串正确结束。

示例:

#include <stdio.h>int main() {char str[6];  // 为 "Hello" 字符串分配空间,包含 \0str[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;
}

详细步骤

  1. 定义字符数组char str[100]; 定义一个大小为 100 的字符数组,用于存储输入的字符串。
  2. 逐字符读取输入:使用 getchar() 逐字符读取输入,直到遇到换行符或文件结束符(EOF)。
  3. 添加字符串结束符:在字符数组的最后一个有效字符位置后添加 \0 结束符,确保字符串正确结束。
  4. 输出字符串:使用 printfputs 输出字符串。

关键点

  • 数组大小检查:在读取输入时,检查数组的大小,确保不会超出数组边界,避免缓冲区溢出。
  • 手动添加 \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 进行字符串输入时的正确性和安全性。

4.4 string.h 头文件

4.4.1 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 的字符串不是以空字符结尾的,将会引发未定义行为。

4.4.2 sscanf与sprintf

sscanf == string + scanf
sprintf == string + printf

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词