嵌入式学习day5
一、二维数组
定义:有两个下标表示的数组,称为二维数组
1.1 二维数组的定义格式
格式:存储类型 数据类型 数组名[常量表达式1][常量表达式2];
存储类型:
auto: 自动类型,一般默认不写的就是自动类型
static: 静态类型,存储在静态区,延长生命周期
const:修饰词,表示变量的值不可修改
register: 寄存器, 访问速度快
extern: 外部变量
volatile:防止内存优化
数据类型:
基本类型(int float char double),构造类型
数组名:
满足命名规范
常量表达式1:
行
常量表达式2:
列
1.2 二维数组初始化
1.按行初始化
int arr[2][3]={ {1,2,3},{2,3,4}}//全部初始化
int arr[2][3]={{1},{2,3}};//部分初始化,其它部分默认以0填充
int arr[][3]={{1},{2,3}}; //省略第一维,默认长度是实际的行数
2.按列初始化
int arr[2][3]={1,2,3, 4,5,6};//全部初始化
int arr[2][3]={1,2};//部分初始化,默认以0填充
int arr[][2]={1,2,3,0};
错误格式
int arr[2][]={1,2,3,4,5};
int arr[2][3];
arr[2][3]={1,2,3,4,5,6};
1.3 二维数组引用
- 当二维数组m行n列,行下标取值:[0,m-1] 列下标:[0,n-1]
- 二维数组的行列下标从0开始
- 二维数组输入输出
int arr[][3] = {1, 2, 4, 67};
int line = sizeof(arr) / sizeof(arr[0]); // 计算行
int row = sizeof(arr[0]) / sizeof(arr[0][0]); // 计算列
for (int i = 0; i < line; i++)
{
for (int j = 0; j < row; j++)
{
printf("arr[%d][%d]=", i, j);
scanf("%d", &arr[i][j]);
}
}
for (int i = 0; i < line; i++)
{
for (int j = 0; j < row; j++)
{
printf("%5d", arr[i][j]);
}
printf("\n");
}
}
- 二维数组引用使用一维的方式
for(int i=0;i<line*row;i++)
{
printf("%d\t",arr[0][i]);//二维数组可以当作在一行中存储
}
- 越界访问:
int arr[2][3];
越界案例:
arr[0][6] //列越界
arr[1][3] //列越界
- 当越界访问的空间,没有被占有,可以访问,输出随机值
- 当越界访问的空间,被占用,但存储数据不重要,可以正常访问
- 当越界访问的空间,被占用,但存储数据重要,不可以正常访问,会出现段错误
段错误:访问了不该访问的内存空间
1.4 二维数组练习
练习1:循环输入m行n列的二维数组,计算最大、小值
int m, n;
printf(“请输入行数、列数:”);
scanf(“%d %d”, &m, &n); // 3,4
int arr[m][n];
int max, min, maxi, maxj, mini, minj;
int count = 0;
// 循环输入
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
scanf(“%d”, &arr[i][j]);
if (i == 0 && j == 0) // 将arr[0][0]赋值为最大值和最小值
{
max = min = arr[i][j];
maxi = mini = i;
maxj = minj = j;
}
// 最大值
if (max < arr[i][j])
{
max = arr[i][j]; // 得到最大值
maxi = i; // 最大值的行下表
maxj = j; // 最大值的列下表
}
// 最小值
if (min > arr[i][j])
{
min = arr[i][j]; // 得到最小值
mini = i; // 得到最小值的行下表
minj = j; // 得到最小值的列下表
}
}
}
// 最大值,最小值
printf("最大值:%d 在%d行%d列\n最小值:%d 在%d行%d列\n", max, maxi + 1, maxj + 1, min, mini + 1, minj + 1);
练习2.杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
int m;
printf("请输入行数:");
scanf("%d", &m);
int arr[m][m]; // 当[]里面是变量是,不允许初始化,报错
for (int i = 0; i < m; i++)
{
for (int j = 0; j <= i; j++)
{
if (j == 0 || i == j)
{
arr[i][j] = 1;
}
else
{
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
printf("%d\t", arr[i][j]);
}
printf("\n");
}
二、一维字符数组
- 字符数组:若干个字符组成的线性结构
- 字符串:是由0个或多个单字符组成的串(以双引号括起来, 有\0,所有汉字都是字符串)
- 字符数组是用来存储字符串,字符数组是容器,字符串是数据
- 单字符: ‘a’ ‘0’
- 字符串: “a” “” " " “你好” “0” “±” “!@#$%^&*([]{}}])”
2.1 字符数组的定义
格式:存储类型 char 数组名[常量表达式];
存储类型:
auto: 自动类型,一般默认不写的就是自动类型
static: 静态类型,存储在静态区,延长生命周期
const:修饰词,表示变量的值不可修改
register: 寄存器, 访问速度快
extern: 外部变量
volatile:防止内存优化
- 数据类型:char
- 数组名:命名规范
- 常量表达式:表示数组的个数【不为0,定义不为空,不为小数,初始化时不为变量】
正确示范如:
char str[5]={1,2,3,4,5};
char str[100]={};
错误示范 如:
int arr[0]
int arr[];
int arr[2.5];
int n=5;
int arr[n]={1,2,3,4,5};错误
2.2 字符数组初始化
- 单字符初始化
char str[5]={ 'a','b','c','d','e'}; 全部初始化
char str[5]={'a','b'}; 部分初始化,默认以'\0'或者0填充 ==>char str[5]={'a','b','\0','\0','\0'};
char str[]={'a','b','c','\0'}; 省略数组长度,默认是实际字符的个数
- 字符串赋值
char str[5]={"abcd"}等价char str[5]="abcd"; //计算会默认为字符串填充\0
char str[5]="a" //部分初始化,默认以'\0'或者0填充
char str[]="abc"; 等价 char str[4]="abc" 省略数组长度,默认是实际字符的个数
- 错误
char str[10];
str=“abc”; 错误
2.3 一维字符数组的引用
-
循环逐个引用
-
整体引用
注:输入字符串不需要加&
char str[50];
printf("输入一个字符串:");
scanf("%s",str); //输入字符串不需要加&
printf("str=%s\n",str);
2.4 gets 和 puts
项目 | gets() | puts() |
---|---|---|
格式 | char *gets(char *s) | int puts(const char *s) |
返回值 | 返回的是一个字符串 | 返回输出字符串数组个数 |
参数 | 一个参数,可以是常量,也可以是变量 | 一个参数,可以是常量,也可以是变量 |
头文件 | #include <stdio.h> | #include <stdio.h> |
2.5 scanf和gets的区别
1.scanf不识别空格,认为空格是一个数据的结束,gets识别空格
2.scanf可以输入多个字符串,gets只可以输入一个字符串
3.scanf返回值输入参数的个数,gets返回字符串
4.scanf一般以空格、tab、回车结束,gets以回车结束
2.6 printf和puts
1.printf没有\n(不自带换行),puts自带换行功能
2.printf可以输出多个变量,puts只可以输出一个
3.printf可以输出任意一种类型,puts只可以输出字符串
4.printf返回输出格式串的字符个数,puts返回字符串的数组长度
2.7 字符数组长度和字符串长度
字符串长度:不计算\0
字符数组长度:计算\0
char a[5]={‘a’ ,‘b’ ,’ c’ ,’ d’ ,‘\0’}; \这个是字符串
char a[3]={‘a’ ,‘b’ ,’ c’ }; \这个是字符数组
char a[10]=“abc”\这个是字符串
char a[]=“abcd”
char a[]=“ab\0cdef”
char a[]=“ab\01cd”
字符串和字符数组
字符串:结尾带 \0的 以及 ""表示的 都是字符串
字符数组: 结尾不带 \0 的 和 char a[3]={‘a’ ,‘b’ ,’ c’ }
作业
作业1:输出如下图案
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
程序要求:杨辉三角形
*/
int main(int argc, const char *argv[])
{
int a;
printf("请输入行列数:");
scanf("%d", &a);
int arr[a][a];
for (int i = 0; i < a; i++)
{
arr[i][0] = 1; // 每行首字母都是1
for (int b = 0; b < a - i; b++)
{
printf(" "); // 输出空格
}
for (int j = 0; j <= i; j++)
{
if (i > 1 && j >= 1)
{
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j]; // 21=10+11
}
if (i == j)
{
arr[i][j] = 1;
}
printf(" %d", arr[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
作业2:
循环输入n个值,
冒泡升序排序,输出,简单选择降序排序,输出
冒泡排序:
// C语言专用模板
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
程序要求:循环输入n个值,冒泡升序排序,输出,简单选择降序排序,输出
*/
int main()
{
int n;
printf("请输入总共数值:\t");
scanf("%d", &n);
printf("请输入数值:\n");
int arr[n], num;
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
for (int i = 0; i < n - 1; i++) // 外层循环次数
{
for (int j = 0; j < n - i - 1; j++) // 内层循环,反复比较大小,将最大的运到最后面
{
if (arr[j] > arr[j + 1])
{
num = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = num;
}
}
}
printf("升序排序后的数值为: ");
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
system("pause");
return 0;
}
简单选择排序
// C语言专用模板
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
程序要求:简单选择降序排序,输出
*/
int main()
{
int n;
printf("请输入总共数值:\t");
scanf("%d", &n);
printf("请输入数值:\n");
int arr[n], num;
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
int max, temp;
for (int i = 0; i < n; i++) // 外层循环次数
{
max = i; // 默认第一个值为最大值
for (int j = i + 1; j < n; j++) // 访问未排序的元素
{
if (arr[j] < arr[max]) // 找到目前最小值
{
max = j; // 记录最大值
}
}
if (max != i)
{
temp = arr[max]; // 交换两个变量
arr[max] = arr[i];
arr[i] = temp;
}
}
printf("降序排序后的数值为: ");
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
system("pause");
}