C&C++快速入门
11、数组与字符串
1、课程目标
- 掌握一维和多维数组的定义和使用
- 理解字符串的存储方式
- 掌握字符数组与字符指针的区别
- 了解宽字符和Unicode字符串
2、名词解释
| 术语 | 说明 |
|---|---|
| 数组 | 相同类型元素的连续存储集合 |
| 索引 | 访问数组元素的下标,从0开始 |
| 字符串 | 以\0结尾的字符数组 |
| 空终止符 | \0,标识字符串结束 |
| ANSI | 单字节字符编码 |
| Unicode | 宽字符编码,Windows使用UTF-16 |
| wchar_t | 宽字符类型,Windows上2字节 |
| TCHAR | 根据编译选项自动选择char或wchar_t |
3、代码实现
1. 一维数组
#include <stdio.h>
int main() {
printf("=== 一维数组 ===\n\n");
// 数组定义与初始化
int arr1[5]; // 未初始化
int arr2[5] = {1, 2, 3, 4, 5}; // 完全初始化
int arr3[5] = {1, 2}; // 部分初始化,其余为0
int arr4[] = {1, 2, 3}; // 自动计算大小
int arr5[5] = {0}; // 全部初始化为0
// 数组大小
printf("【数组大小】\n");
printf("arr2大小: %d字节\n", (int)sizeof(arr2));
printf("元素个数: %d\n", (int)(sizeof(arr2)/sizeof(arr2[0])));
// 数组访问
printf("\n【数组访问】\n");
for (int i = 0; i < 5; i++) {
printf("arr2[%d] = %d\n", i, arr2[i]);
}
// 数组与指针
printf("\n【数组与指针】\n");
int* p = arr2; // 数组名是首元素地址
printf("arr2 = %p\n", (void*)arr2);
printf("&arr2[0] = %p\n", (void*)&arr2[0]);
printf("p = %p\n", (void*)p);
printf("*p = %d, *(p+1) = %d\n", *p, *(p+1));
return 0;
}
2. 多维数组
#include <stdio.h>
int main() {
printf("=== 多维数组 ===\n\n");
// 二维数组
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
printf("【二维数组遍历】\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
// 内存布局
printf("\n【内存布局】\n");
printf("matrix地址: %p\n", (void*)matrix);
printf("matrix[0]地址: %p\n", (void*)matrix[0]);
printf("matrix[1]地址: %p\n", (void*)matrix[1]);
printf("行间隔: %d字节\n",
(int)((char*)matrix[1] - (char*)matrix[0]));
return 0;
}
3. 字符串基础
#include <stdio.h>
#include <string.h>
int main() {
printf("=== 字符串基础 ===\n\n");
// 字符数组 vs 字符串
char arr1[] = {'H', 'e', 'l', 'l', 'o'}; // 字符数组,非字符串
char arr2[] = {'H', 'e', 'l', 'l', 'o', '\0'}; // 字符串
char arr3[] = "Hello"; // 字符串(自动加\0)
char* str = "Hello"; // 字符串指针
printf("【大小对比】\n");
printf("arr1: %d字节 (无\\0)\n", (int)sizeof(arr1)); // 5
printf("arr2: %d字节 (有\\0)\n", (int)sizeof(arr2)); // 6
printf("arr3: %d字节 (有\\0)\n", (int)sizeof(arr3)); // 6
printf("str: %d字节 (指针大小)\n", (int)sizeof(str)); // 4或8
printf("\n【字符串长度】\n");
printf("strlen(arr3): %d\n", (int)strlen(arr3)); // 5
printf("strlen(str): %d\n", (int)strlen(str)); // 5
// 字符串修改
printf("\n【字符串修改】\n");
arr3[0] = 'h'; // OK: 字符数组可修改
printf("arr3: %s\n", arr3);
// str[0] = 'h'; // 错误! 字符串常量不可修改
return 0;
}
4. 宽字符串
#include <stdio.h>
#include <windows.h>
#include <wchar.h>
int main() {
printf("=== 宽字符串 ===\n\n");
// 宽字符定义
wchar_t wstr[] = L"Hello世界"; // L前缀表示宽字符
printf("【宽字符大小】\n");
printf("wchar_t大小: %d字节\n", (int)sizeof(wchar_t));
printf("wstr数组大小: %d字节\n", (int)sizeof(wstr));
printf("wstr长度: %d字符\n", (int)wcslen(wstr));
// 打印宽字符串
wprintf(L"\nwstr: %ls\n", wstr);
// Windows API中的字符串类型
printf("\n【Windows字符串类型】\n");
LPSTR ansiStr = "ANSI String"; // char*
LPWSTR wideStr = L"Wide String"; // wchar_t*
LPCSTR constAnsi = "Const ANSI"; // const char*
LPCWSTR constWide = L"Const Wide"; // const wchar_t*
printf("LPSTR: %s\n", ansiStr);
wprintf(L"LPWSTR: %ls\n", wideStr);
return 0;
}
5、课后作业
5.1、作业1:数组操作
实现一个函数,将数组元素反转。
5.2、作业2:字符串复制
手动实现strcpy函数,注意处理\0。
5.3、作业3:ANSI转Unicode
使用MultiByteToWideChar实现ANSI到Unicode转换。