Appearance
数组与字符串
数组和字符串是 C 语言中最常用的数据结构。
一维数组
数组声明与初始化
c
#include <stdio.h>
int main() {
// 声明数组
int arr1[5]; // 声明但不初始化(值不确定)
// 完全初始化
int arr2[5] = {1, 2, 3, 4, 5};
// 部分初始化(其余为0)
int arr3[5] = {1, 2}; // {1, 2, 0, 0, 0}
// 自动推断大小
int arr4[] = {1, 2, 3, 4, 5}; // 大小为5
// 全部初始化为0
int arr5[5] = {0}; // {0, 0, 0, 0, 0}
// 指定初始化器 (C99)
int arr6[10] = {[0] = 1, [5] = 2, [9] = 3};
// 访问元素
printf("arr2[0] = %d\n", arr2[0]);
printf("arr2[4] = %d\n", arr2[4]);
// 修改元素
arr2[0] = 10;
// 数组大小
printf("数组大小: %zu bytes\n", sizeof(arr2));
printf("元素个数: %zu\n", sizeof(arr2) / sizeof(arr2[0]));
return 0;
}数组遍历
c
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int size = sizeof(arr) / sizeof(arr[0]);
// 使用索引遍历
printf("索引遍历:\n");
for (int i = 0; i < size; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
// 使用指针遍历
printf("\n指针遍历:\n");
int *p = arr;
for (int i = 0; i < size; i++) {
printf("*(p + %d) = %d\n", i, *(p + i));
}
// 指针递增遍历
printf("\n指针递增遍历:\n");
int *end = arr + size;
for (int *p = arr; p < end; p++) {
printf("%d ", *p);
}
printf("\n");
return 0;
}数组作为函数参数
c
#include <stdio.h>
// 数组作为参数(退化为指针)
void print_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// 等价写法
void print_array2(int *arr, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// 计算数组元素和
int sum_array(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
// 修改数组元素
void double_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2;
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
int size = sizeof(arr) / sizeof(arr[0]);
printf("原数组: ");
print_array(arr, size);
printf("和: %d\n", sum_array(arr, size));
double_array(arr, size);
printf("翻倍后: ");
print_array(arr, size);
return 0;
}多维数组
二维数组
c
#include <stdio.h>
int main() {
// 声明与初始化
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 部分初始化
int m2[3][4] = {
{1, 2},
{5},
{9, 10, 11}
};
// 省略内层大括号
int m3[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// 访问元素
printf("matrix[0][0] = %d\n", matrix[0][0]);
printf("matrix[1][2] = %d\n", matrix[1][2]);
// 遍历二维数组
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
// 行数和列数
int rows = sizeof(matrix) / sizeof(matrix[0]);
int cols = sizeof(matrix[0]) / sizeof(matrix[0][0]);
printf("行数: %d, 列数: %d\n", rows, cols);
return 0;
}二维数组作为参数
c
#include <stdio.h>
// 必须指定列数
void print_matrix(int rows, int cols, int matrix[][cols]) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
}
// 使用指针
void print_matrix_ptr(int rows, int cols, int *matrix) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%2d ", *(matrix + i * cols + j));
}
printf("\n");
}
}
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
print_matrix(3, 4, matrix);
printf("\n");
print_matrix_ptr(3, 4, (int*)matrix);
return 0;
}三维数组
c
#include <stdio.h>
int main() {
// 三维数组
int cube[2][3][4] = {
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}
}
};
// 遍历
for (int i = 0; i < 2; i++) {
printf("第 %d 层:\n", i);
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 4; k++) {
printf("%2d ", cube[i][j][k]);
}
printf("\n");
}
printf("\n");
}
return 0;
}字符串
字符串基础
c
#include <stdio.h>
int main() {
// 字符数组(可修改)
char str1[] = "Hello";
str1[0] = 'h'; // 可以修改
printf("str1: %s\n", str1);
// 字符串常量指针(不可修改)
char *str2 = "World";
// str2[0] = 'w'; // 未定义行为
printf("str2: %s\n", str2);
// 字符数组初始化
char str3[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str4[6] = "Hello";
// 字符串长度
printf("str1 长度: %zu\n", sizeof(str1)); // 6(包含 '\0')
printf("str1 字符数: %zu\n", strlen(str1)); // 5
// 遍历字符串
char *p = str1;
while (*p != '\0') {
printf("%c ", *p);
p++;
}
printf("\n");
return 0;
}字符串输入输出
c
#include <stdio.h>
int main() {
char name[50];
// scanf 读取(遇到空格停止)
printf("请输入名字(不含空格): ");
scanf("%s", name);
printf("名字: %s\n", name);
// 清除输入缓冲区
while (getchar() != '\n');
// fgets 读取一行(推荐)
printf("请输入完整名字: ");
fgets(name, sizeof(name), stdin);
// 去除末尾换行符
name[strcspn(name, "\n")] = '\0';
printf("名字: %s\n", name);
// puts 输出字符串
puts("使用 puts 输出");
// fputs 输出到文件或 stdout
fputs("使用 fputs 输出\n", stdout);
return 0;
}字符串函数
c
#include <stdio.h>
#include <string.h>
int main() {
char str1[50] = "Hello";
char str2[50] = "World";
char str3[50];
// 字符串长度
printf("strlen(str1) = %zu\n", strlen(str1));
// 字符串复制
strcpy(str3, str1);
printf("strcpy: %s\n", str3);
// 字符串连接
strcat(str1, " ");
strcat(str1, str2);
printf("strcat: %s\n", str1);
// 字符串比较
char s1[] = "apple";
char s2[] = "banana";
printf("strcmp(s1, s2) = %d\n", strcmp(s1, s2)); // -1
printf("strcmp(s2, s1) = %d\n", strcmp(s2, s1)); // 1
printf("strcmp(s1, s1) = %d\n", strcmp(s1, s1)); // 0
// 字符串查找
char str[] = "Hello, World!";
char *pos = strchr(str, 'W');
if (pos != NULL) {
printf("找到 'W' 在位置: %ld\n", pos - str);
}
pos = strstr(str, "World");
if (pos != NULL) {
printf("找到 \"World\" 在位置: %ld\n", pos - str);
}
// 安全版本(推荐)
char dest[10];
strncpy(dest, "Hello World", sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';
printf("strncpy: %s\n", dest);
return 0;
}自定义字符串函数
c
#include <stdio.h>
// 字符串长度
size_t my_strlen(const char *str) {
const char *p = str;
while (*p) p++;
return p - str;
}
// 字符串复制
char* my_strcpy(char *dest, const char *src) {
char *p = dest;
while ((*p++ = *src++));
return dest;
}
// 字符串连接
char* my_strcat(char *dest, const char *src) {
char *p = dest;
while (*p) p++;
while ((*p++ = *src++));
return dest;
}
// 字符串比较
int my_strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return *(unsigned char*)s1 - *(unsigned char*)s2;
}
// 字符串查找
char* my_strchr(const char *str, int c) {
while (*str && *str != c) {
str++;
}
return (*str == c) ? (char*)str : NULL;
}
int main() {
char s1[50] = "Hello";
char s2[50] = "World";
printf("长度: %zu\n", my_strlen(s1));
char s3[50];
my_strcpy(s3, s1);
printf("复制: %s\n", s3);
my_strcat(s3, " ");
my_strcat(s3, s2);
printf("连接: %s\n", s3);
printf("比较: %d\n", my_strcmp("apple", "banana"));
char *pos = my_strchr("Hello", 'l');
printf("查找: %s\n", pos ? pos : "未找到");
return 0;
}字符串数组
c
#include <stdio.h>
#include <string.h>
int main() {
// 二维字符数组
char fruits[][20] = {
"Apple",
"Banana",
"Cherry",
"Date"
};
printf("水果列表:\n");
for (int i = 0; i < 4; i++) {
printf("%s\n", fruits[i]);
}
// 指针数组
char *colors[] = {
"Red",
"Green",
"Blue",
"Yellow"
};
printf("\n颜色列表:\n");
for (int i = 0; i < 4; i++) {
printf("%s\n", colors[i]);
}
// 排序字符串
char *names[] = {"Charlie", "Alice", "David", "Bob"};
int n = 4;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (strcmp(names[j], names[j + 1]) > 0) {
char *temp = names[j];
names[j] = names[j + 1];
names[j + 1] = temp;
}
}
}
printf("\n排序后:\n");
for (int i = 0; i < n; i++) {
printf("%s\n", names[i]);
}
return 0;
}字符处理
字符分类函数
c
#include <stdio.h>
#include <ctype.h>
int main() {
char c;
printf("输入一个字符: ");
scanf("%c", &c);
// 字符分类
printf("isalpha: %d\n", isalpha(c)); // 是否字母
printf("isdigit: %d\n", isdigit(c)); // 是否数字
printf("isalnum: %d\n", isalnum(c)); // 是否字母或数字
printf("islower: %d\n", islower(c)); // 是否小写
printf("isupper: %d\n", isupper(c)); // 是否大写
printf("isspace: %d\n", isspace(c)); // 是否空白
printf("ispunct: %d\n", ispunct(c)); // 是否标点
printf("isxdigit: %d\n", isxdigit(c)); // 是否十六进制数字
// 字符转换
printf("tolower: %c\n", tolower(c)); // 转小写
printf("toupper: %c\n", toupper(c)); // 转大写
return 0;
}字符串转换
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main() {
// 字符串转数字
char num_str[] = "12345";
int num = atoi(num_str);
long lng = atol("1234567890");
double dbl = atof("3.14159");
printf("atoi: %d\n", num);
printf("atol: %ld\n", lng);
printf("atof: %f\n", dbl);
// 更安全的转换
char *end;
long val = strtol("12345abc", &end, 10);
printf("strtol: %ld, 剩余: %s\n", val, end);
double d = strtod("3.14abc", &end);
printf("strtod: %f, 剩余: %s\n", d, end);
// 数字转字符串
char buffer[50];
sprintf(buffer, "%d", 12345);
printf("sprintf: %s\n", buffer);
// 字符串大小写转换
char str[] = "Hello World";
printf("原字符串: %s\n", str);
// 转大写
for (int i = 0; str[i]; i++) {
str[i] = toupper(str[i]);
}
printf("大写: %s\n", str);
// 转小写
for (int i = 0; str[i]; i++) {
str[i] = tolower(str[i]);
}
printf("小写: %s\n", str);
return 0;
}实践示例
字符串分割
c
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "apple,banana,cherry,date";
char *token;
char *rest = str;
printf("分割字符串:\n");
while ((token = strtok_r(rest, ",", &rest))) {
printf("%s\n", token);
}
// 使用 strtok(会修改原字符串)
char str2[] = "one two three four";
token = strtok(str2, " ");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, " ");
}
return 0;
}字符串反转
c
#include <stdio.h>
#include <string.h>
void reverse_string(char *str) {
int len = strlen(str);
for (int i = 0; i < len / 2; i++) {
char temp = str[i];
str[i] = str[len - 1 - i];
str[len - 1 - i] = temp;
}
}
int main() {
char str[] = "Hello World";
printf("原字符串: %s\n", str);
reverse_string(str);
printf("反转后: %s\n", str);
return 0;
}单词统计
c
#include <stdio.h>
#include <ctype.h>
#include <string.h>
typedef struct {
int chars;
int words;
int lines;
} TextStats;
TextStats count_text(const char *text) {
TextStats stats = {0, 0, 0};
int in_word = 0;
for (int i = 0; text[i] != '\0'; i++) {
stats.chars++;
if (text[i] == '\n') {
stats.lines++;
}
if (isalpha(text[i])) {
if (!in_word) {
stats.words++;
in_word = 1;
}
} else {
in_word = 0;
}
}
if (stats.chars > 0 && text[stats.chars - 1] != '\n') {
stats.lines++;
}
return stats;
}
int main() {
char text[] = "Hello World\nThis is a test\nC programming";
TextStats stats = count_text(text);
printf("字符数: %d\n", stats.chars);
printf("单词数: %d\n", stats.words);
printf("行数: %d\n", stats.lines);
return 0;
}矩阵运算
c
#include <stdio.h>
#define ROWS 3
#define COLS 3
void print_matrix(int matrix[ROWS][COLS]) {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
}
void add_matrices(int a[ROWS][COLS], int b[ROWS][COLS], int result[ROWS][COLS]) {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
result[i][j] = a[i][j] + b[i][j];
}
}
}
void multiply_matrices(int a[ROWS][COLS], int b[ROWS][COLS], int result[ROWS][COLS]) {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
result[i][j] = 0;
for (int k = 0; k < COLS; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
}
void transpose_matrix(int matrix[ROWS][COLS], int result[COLS][ROWS]) {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
result[j][i] = matrix[i][j];
}
}
}
int main() {
int a[ROWS][COLS] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int b[ROWS][COLS] = {
{9, 8, 7},
{6, 5, 4},
{3, 2, 1}
};
int result[ROWS][COLS];
printf("矩阵 A:\n");
print_matrix(a);
printf("\n矩阵 B:\n");
print_matrix(b);
printf("\nA + B:\n");
add_matrices(a, b, result);
print_matrix(result);
printf("\nA * B:\n");
multiply_matrices(a, b, result);
print_matrix(result);
printf("\nA 的转置:\n");
transpose_matrix(a, result);
print_matrix(result);
return 0;
}