本文主要介绍一维数组和二维数组及其简单访问。
1. 数组基本概述
数组的来源
一次性可以定义n个相同数据类型的变量,所占的空间是连续的空间。
数组的访问
数组名 + 下标 如 arr[x]
注:下标从0开始
2. 一维数组
1. 一维数组定义
//⼀维数组定义的语法
type arrayName[arraySize];
arraySize 必须是⼀个⼤于零的整数常量,type 可以是任意有效的C数据类型
例如
char ar[10]; //定义⼀个字符数组,有10个元素
int br[10]; //定义⼀个整形数组,有10个元素
double cr[10]; //定义⼀个浮点数组,有10个元素
2. 一维数组初始化
下面是直接给数组初始化的操作,非scanf的方式
#include<stdio.h>
int main()
{
//未初始化,值为随机值
int ar[10];
//完全初始化,值⼀⼀对应
int br[10] = {1,2,3,4,5,6,7,8,9,10};
//未完全初始化,剩余空间⽤0填充
int cr[10] = {1,2,3,4,5};
//错误,初始化的元素个数不能超过空间个数
int dr[10] = {1,2,3,4,5,6,7,8,9,10,11};
return 0;
}
3. 计算数组元素个数
元素个数 = 数组所占空间大小 / 首元素的大小
数组所占空间大小:sizeof(ar)
首元素的大小:sizeof(ar[0])
#include<stdio.h>
int main()
{
int ar[] = {1,2,3,4,5,6,7,8,9,10};
int n = sizeof(ar) / sizeof(ar[0]);
printf("size = %d\n", n);
return 0;
}
4. 一维数组的访问 / 遍历
#include<stdio.h>
int main()
{
int ar[] = {1,2,3,4,5,6,7,8,9,10}; // 由数组里的个数决定n
int n = sizeof(ar) / sizeof(ar[0]);
for(int i=0; i<n; i++) // for循环实现访问遍历,下标从0开始
{
printf("%d ",ar[i]);
}
printf("\n");
return 0;
}
3. 二维数组
1. 二维数组定义
//⼆维数组定义的语法
type arrayName[rowSize][colSize]; // 先行后列
rowSize和colSize必须是⼀个⼤于零的整数常量,type 可以是任意有效的C数据类型
举例
#include<stdio.h>
int main()
{
char ar[3][3]; // 定义⼀个3⾏3列的字符⼆维数组
int br[3][3]; // 定义⼀个3⾏3列的整型⼆维数组
double cr[3][3]; // 定义⼀个3⾏3列的浮点⼆维数组
return 0;
}
2. 二维数组初始化
#include<stdio.h>
int main()
{
//未初始化,值为随机值
int ar[3][3];
//完全初始化,值⼀⼀按⾏优先对应,一行满3个元素后自动开下一行填充元素
int br[3][3] = {1,2,3,4,5,6,7,8,9};
//完全初始化,⾏列对应,一个{}代表一行
int cr[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
//未完全初始化,剩余空间使⽤0填充
int dr[3][3] = {1,2,3,4,5};
//未完全初始化,1,2,3分别各占⼀⾏,其余空间使⽤0填充
int er[3][3] = {{1}, {2}, {3}};
//⼆维数组可以省略⾏标,但不能省略列标,根据列标⾃动换⾏
int fr[][3] = {1,2,3,4,5,6,7,8,9};
return 0;
}
注意最后:
二维数组可以省略行标,但不能省略列标,根据列标自动换行。
3. 二维数组的访问 / 遍历
通过双层循环进行访问,i 控制行,j 控制列
外层循环是行,内层循环是列
原理是 先填满一行元素(外)一行中有多个列(内)内层所有循环结束后算做外层一次循环结束
#include<stdio.h>
int main()
{
int ar[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
for(int i=0; i<3; ++i)
{
for(int j=0; j<3; ++j)
{
printf("%d ", ar[i][j]);
}
printf("\n"); // 内层循环结束一行元素已经填满,则使用换行
}
return 0;
}
4. 练习
1. 记数问题(牛客BC116)
描述:试计算在区间1 到n 的所有整数中,数字x(0 ≤ x ≤ 9)共出现了多少次?
例如,在1到11 中,即在1、2、3、4、5、6、7、8、9、10、11 中,数字1 出现了4 次。
输入描述:输入共1行,包含2个整数n、x,之间用一个空格隔开。
输出描述:输出共1行,包含一个整数,表示x出现的次数。
输入:11 1
输出:4
#include<stdio.h>
int main()
{
int n, x;
scanf("%d %d",&n, &x);
int count = 0; // 记数
for(int i=1; i<=n; i++)
{
int val = i; // 获取当前循环到的值
while(val) // 做为循环次数,0时退出循环
{
if(val % 10 ==x) // 只判断个位数是否为目标数字
count++;
val = val / 10; // 判断完一位向前进一位继续判断,同时赋给while循环次数
}
}
printf("%d\n",count);
return 0;
}
2. 井字棋(BC141)
描述:KiKi和BoBo玩 “井”字棋。也就是在九宫格中,只要任意行、列,或者任意对角线上面出现三个连续相同的棋子,就能获胜。请根据棋盘状态,判断当前输赢。
输入描述:三行三列的字符元素,代表棋盘状态,字符元素用空格分开,代表当前棋盘,其中元素为K代表KiKi玩家的棋子,为O表示没有棋子,为B代表BoBo玩家的棋子。
输出描述:如果KiKi获胜,输出“KiKi wins!”;如果BoBo获胜,输出“BoBo wins!”;如果没有获胜,输出“No winner!”。
输入:K O B
O K B
B O K
输出:KiKi wins!
#include <stdio.h>
#define N 3
char isWin(char ar[N][N]) {
for (int i = 0; i < N; ++i) {
if ((ar[i][0] == ar[i][1]) && (ar[i][1] == ar[i][2]))
return ar[i][0];
}
for (int j = 0; j < N; ++j) {
if ((ar[0][j] == ar[1][j]) && (ar[1][j] == ar[2][j]))
return ar[1][j];
}
if((ar[0][0]==ar[1][1]&&ar[0][0]==ar[2][2]) || (ar[0][2]==ar[1][1]&&ar[2][0]==ar[1][1])){
return ar[1][1];
}
return 'N';
}
int main() {
char ar[N][N];
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
scanf("%c", &ar[i][j]);
if (j <= N) //注意处理输⼊字符的空格,这是此题的关键
getchar(); // 吃掉空格和换行符
}
}
char ans = isWin(ar);
if (ans == 'K')
printf("KiKi wins!");
else if (ans == 'B')
printf("BoBo wins!");
else
printf("No winner!");
return 0;
}
getchar() 在这里吃掉空格和换行符
防止系统在判断时将空格相等也判断进去。
因此此类题目(自动输入的有空格的且影响判断的),加上此行代码
本文介绍数组知识点。