Files
Linux-C-Notes/Chapter05/C5-数组.md

404 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 目录
- [目录](#目录)
- [数组](#数组)
- [一维数组](#一维数组)
- [练习部分](#练习部分)
- [斐波那契数列前10项](#斐波那契数列前10项)
- [数据排序](#数据排序)
- [冒泡](#冒泡)
- [选择法](#选择法)
- [进制转换](#进制转换)
- [删除法求质数](#删除法求质数)
- [二维数组](#二维数组)
- [练习部分](#练习部分-1)
- [行列互换](#行列互换)
- [求最大值及其所在位置](#求最大值及其所在位置)
- [求各行与各列的和](#求各行与各列的和)
- [矩阵乘积](#矩阵乘积)
- [字符数组](#字符数组)
- [常用函数](#常用函数)
- [练习部分](#练习部分-2)
- [单词计数](#单词计数)
- [多维数组](#多维数组)
# 数组
构造类型之一,连续存放。
> [!warning]
>
> 时间关系,大量的练习题,没有做笔记,只记录了题目。自己思考加看课程足矣。
## 一维数组
1. 定义
【存储类型】 数据类型 标识符 【下标】
2. 初始化
- 不初始化
- 全部初始化
- 部分初始化
- `static`
3. 元素引用
数组名【下标】
4. 数组名
数组名是表示地址的**常量**,也是数组的起始位置。
5. 数组越界
### 练习部分
#### 斐波那契数列前10项
```c
static void fibonacci(void)
{
int fib[10] = {1, 1};
for (int i = 2; i < sizeof(fib) / sizeof(fib[0]); i++)
{
fib[i] = fib[i - 2] + fib[i - 1];
}
for (int i = 0; i < sizeof(fib) / sizeof(fib[0]); i++)
{
printf("fib[%d] = %d\n", i, fib[i]);
}
printf("\n");
int i = 0;
int j = sizeof(fib) / sizeof(fib[0]) - 1;
int tmp;
while (i < j)
{
tmp = fib[i];
fib[i] = fib[j];
fib[j] = tmp;
i++;
j--;
}
for (int i = 0; i < sizeof(fib) / sizeof(fib[0]); i++)
{
printf("fib[%d] = %d\n", i, fib[i]);
}
}
```
#### 数据排序
##### 冒泡
```c
#define N 10
static void sort1(void)
{
int a[N] = {12, 8, 45, 30, 98, 67, 2, 7, 68, 11};
int tmp;
for (int i = 0; i < N; i++)
{
printf("%d ", a[i]);
}
printf("\n");
for (int i = 0; i < (N - 1); i++)
{
for (int j = 0; j < N - 1 - i; j++)
{
if (a[j] > a[j + 1])
{
tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
}
}
}
for (int i = 0; i < N; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
```
##### 选择法
```c
static void sort2(void)
{
int a[N] = {23, 45, 90, 76, 13, 55, 76, 45, 3, 8};
int i, j, k, tmp;
for (int i = 0; i < N; i++)
{
printf("%d ", a[i]);
}
printf("\n");
for (i = 0; i < N - 1; i++)
{
k = i;
for (j = i + 1; j < N; j++)
{
if (a[j] < a[k])
k = j;
}
if (i != k)
{
tmp = a[i];
a[i] = a[k];
a[k] = tmp;
}
}
for (int i = 0; i < N; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
```
#### 进制转换
```c
static void base_convert(void)
{
int num, base;
int n[128];
int i = 0;
printf("Please enter the converted num:\n");
scanf("%d", &num);
printf("Please enter the base:\n");
scanf("%d", &base);
do
{
n[i] = num % base;
num = num / base;
i++;
} while (num != 0);
for (i--; i >= 0; i--)
{
if (n[i] >= 10)
printf("%c", n[i] - 10 + 'A');
else
printf("%d", n[i]);
}
printf("\n");
}
```
#### 删除法求质数
```c
static void primer(void)
{
char primer[1001] = {0};
int i, j;
for (i = 2; i < 1001; i++)
{
for (j = i * 2; j < 1001; j += i)
primer[j] = -1;
}
for (i = 2; i < 1001; i++)
{
if (primer[i] == 0)
printf("%d is a primer.\n", i);
}
}
```
## 二维数组
1. 定义,初始化
【存储类型】 数据类型 标识符 【行下标】 【列下标】
> [!note]
>
> 初始化时,行号可省,列号不可省
2. 元素引用
数组名 【行标】【列标】
3. 存储形式
顺序存储,按行存储
4. 对于二维数组的深入理解
```c
int a[M][N] = {1, 2, 3, 4, 5};
int i, j;
printf("a = %p\n", a);
printf("a+1 = %p\n", a + 1);
for (i = 0; i < M; i++)
{
for (j = 0; j < N; j++)
{
printf("%p --> %d\n", &a[i][j], a[i][j]);
}
printf("\n");
}
```
输出:
```c
a = 0x7ffcc2376f80
a+1 = 0x7ffcc2376f8c
0x7ffcc2376f80 --> 1
0x7ffcc2376f84 --> 2
0x7ffcc2376f88 --> 3
0x7ffcc2376f8c --> 4
0x7ffcc2376f90 --> 5
0x7ffcc2376f94 --> 0
```
`a+1`跨越了行而不是单个元素。
### 练习部分
#### 行列互换
#### 求最大值及其所在位置
#### 求各行与各列的和
#### 矩阵乘积
## 字符数组
1. 定义,初始化,存储特点
【存储类型】 数据类型 标识符 【下标】...
- 单个字符初始化
- 用字符串常量初始化
2. 输入输出
3. 常用函数
### 常用函数
1. `strlen`和`sizeof`
```c
size_t strlen(const char *s);
// strlen函数可以获取字符串的长度不包括尾'\0'
// 以'\0'作为结束,所以对于"hello\0abc"abc就不计入
// sizeof是完整的识别。
char str[] = "hello\0abc";
printf("%d\n", strlen(str));
// out: 5
printf("%d\n", sizeof(str));
// out: 6
```
2. `strcpy`与`strncpy`
```c
char *strcpy(char *dest, const char *src);
// 把src内容拷贝到dest以'\0'结束返回dest的地址
// 当src大于dest造成越界
char *strncpy(char *dest, const char *src, size_t n);
// 把src内容拷贝n个字节到dest
strcpy(str, "abcde");
puts(str);
// out: abcde
strncpy(str, "abcde", STR_SIZE);
puts(str);
// out: abcde
```
3. `strcat`与`strncat`
```c
char *strcat(char *dest, const char *src);
// 把src补到dest后面
// 需要保证dest空间足够
char *strncat(char *dest, const char *src, size_t n);
// 把src拿最多n个字符到dest
strcat(str1, " ");
strcat(str1, "world");
// out:hello world
strncat(str, " ", STR_SIZE);
strncat(str, "world", STR_SIZE);
// out:hello world
```
4. `strcmp`与`strncmp`
```c
int strcmp(const char *s1, const char *s2);
// 返回两个字符串ascii码的差值
int strncmp(const char (s1, const char *s2, size_t n);
// 指定比较前5个字符
```
### 练习部分
#### 单词计数
## 多维数组
```c
int a[2][3][4];
```