重生之我学习C语言遇到数组

一、

数组

int number[100];
scanf("%d, &number[i]);
  • 求平均数,打印出大于平均数的数

int x;
double sum = 0;
int cnt = 0;
int number[100];  // 定义数组
scanf("%d", &x);
while (x!=-1){
    number[cnt] = x;  // 对数组中的元素赋值
    sum +=x;
    cnt++;
    scanf("%d", &x);
}
if (cnt >0){
    int i;
    double average =sum/cnt;
    for (i=0;i<cnt;i++){
        if(number[i]>average){
            printf("%d", number[i]);  // 使用数组中的元素
        }
    }   //  遍历数组
}

定义数组

  • <类型>变量名称[元素数量];

    • int grades[100];

    • double weight[20];

  • 元素数量必须是整数

  • C99之前:元素数量必须是编译时刻确定的字面量

数组

  • 是一种容器(放东西的东西),特点是:

    • 其中所有的元素具有相同的数据类型;

    • 一旦创建,不能改变大小

    • (数组中的元素在内存中是连续依次排列的)

int 1[10]

  • 10个单元: a[0],a[1,a],...,a[9]

  • 每个单元就是一个int类型的变量

  • 可以出现在赋值的左边或右边:

    • a[2] = a[1] + 6;

  • 在赋值左边的叫做左值

数组的单元

  • 数组的每个单元就是数组类型的一个变量

  • 使用数组时放在[]中的数字叫做下标或索引,下标从0开始计数:

    • grades[0]

    • grades[99]

    • average[5] (最大下标是数组个数减一,而不是数组的个数)

有效的下标范围

  • 编译器和运行环境都不会检查数组的下标是否越界,无论是对数组单元做读还是写

  • 一旦程序运行,越界的数组访问可能造成问题,导致程序崩溃

  • segmentation fault

  • 但也可能运气好,没造成严重的后果

  • 所以这是程序员的责任来保证程序只使用有效的下标值:[0,数组的大小减一]

长度微0的数组?

  • int a[0];

  • 可以存在,但是无用

例子:输入数量不确定的[0,9]范围内的整数,统计每一种数字出现的次数,输入-1表示结束

const number = 10;
int x;
int cnt[number];
int i;
​
for(i=0; i<number;i++){
    cnt[i]=o;
}
scanf("%d", &x);
while(x!=-1){
    if(x>=0 && x<=9){
        cnt[x]++;
    }
    scanf("%d", &x);
}
for(i=0;i<number;i++){
    printf("%d:%d", i,cnt[i]);
}
​
  1. 确定数组的大小

  2. 定义数组

  3. 初始化数组

  4. 数组参与运算

  5. 遍历数组输出

数组的集成初始化

int a[] = {2,3,4,5,6,7,8,9,};

  • 直接用大括号给出数组的所有元素的初始值

  • 不需要给出数组的大小,编译器替你数数

集成初始化时的定位

int a[10] = {
    [0]=2, [2]=3, 6,
};
  • 用[n]在初始化数据中给出定位

  • 没用定位的数据接在前面位置的后面

  • 其他位置的值补0

  • 也可以不给数组大小,让编译器算

  • 特别适合初始数据稀疏的数组 (C99 only)

数组的大小

  • sizeof给出整个数组所占据的内容的大小,单位是字节 sizeof(a)/sizeof(a[0])

  • sizeof(a[0])给出数组中单个元素的大小,于是相除就得到了数组的单元个数

  • 这样的代码,一但修改数组中初始的数据,不需要修改遍历的代码

数组的赋值

int a[] = {1,2,4,7,9,453,214,123};
int b[] = a;   // 错误
  • 数组本身不能被赋值

  • 要把一个数组的所有元素交给另一个数组,必须采用遍历

    for ( i=0; i<length; i++){
      b[i] = a[i];
    }

遍历数组

  • 通常使用for循环,让循环变量i从0到<数组的长度,这样循环体内最大的i正好是数组最大的有效下标

  • 常见的错误:

    • 循环结束条件是<=数组长度,或;

    • 离开循环后,继续用i的值来做元素的下标!

  • 数组作为函数参数时,往往必须再用另一个参数来传入数组的大小


  • 数组作为函数参数时:

    • 不能在[]中给出数组的大小

    • 不能再利用sizeof;来计算数组的元素个数!

构造素数表

  • 欲构造n以内(不含)的素数表

  1. 开辟prime[n],初始化其所有的元素为1,prime[x]为1表示x是素数

  2. 令x=2

  3. 如果x是素数,则对于(i=2;xi<n;n++)令prime[ix]=0

  4. 令x++,如果x<n,重复3,否则结束

# include <stdio.h>
​
int main()
{
    const int maxNumber = 25;
    int isPrime[maxNumber];
    int i;
    int x;
    for ( i=0; i<maxNumber; i++){
        isPrime[i]= 1;
    }
    for (x=2; x<maxNumber; x++){
        if( isPrime[x] ){
            for( i=2; i*x<maxNumber; i++){
                isPrime[i*x] = 0;
            }
        }
    }
    for (x=2; x<maxNumber; x++){
        if(isPrime[i]){
            printf("%d/t", i);
        }
    }
    printf("/n");
​
    return 0;
}

二维数组

  • int a3;

  • 通常理解为a是一个3行5列的矩阵

二维数组的遍历

  • 读入矩阵

for ( i=0; i<3; i++){
    for ( j=0; j<5; j++){
        a[i][j] = i*j;
    }
}
  • ai是一个int

  • 表示第i行第j列上的一个单元

    • a[i,j]是什么? // 错误

二维数组的初始化

int a[][5] = {
    {0,1,2,3,4},
    {2,3,4,5,6},
};
  • 列数是必须给出的,行数可以由编译器来数

  • 每一行{},逗号分隔

  • 最后的逗号可以存在,有古老的传统

  • 如果省略,表示补0

  • 也可以永定位(*C99 ONLY)

井字棋游戏

  1. 读入矩阵

const int size =3;
int board[size][size];
int i,j;
int numOfX;
int numOfO;
int result = -1;  // -1:没人赢;1:X赢;0:O赢
​
// 读入矩阵
for ( i=0; i<size; i++){
    for ( j=0; j<size; j++){
        scanf("%d", &board[i][j]);
    }
}
  1. 检查行

// 检查行
for ( i=0; i<size && result ==-1; i++){
    numOfO = numOfX =0;
    for ( j=0; j<size; j++){
        if( board[i][j] == 1){
            numOfX ++;
        } else {
            numOfO ++;
        }
    }
    if (numOfO == size){
        result = 0;
    } else if ( numOfX ==size ){
        result =1;
    }
}
  1. 检查列

if( result == -1){
    for ( j=0; j<size && result == -1; j++){
        numOfO = numOfX = 0;
        for ( i=0; i<size; i++ ){
            if(board[i][j] == 1 ){
                numOfX ++;
            } else {
                numOfO ++;
            }
        }
        if ( numOfO == size ){
            result = 0;
        } else if ( numOfX == size ){
            result = 1;
        }
    }
}
  1. 检查对角线

// 正对角线
numOfO = numOfX = 0;
for ( i=0; i<size; i++){
    if( board[i][i] == 1 ){
        numOfX ++;
    } else {
        numOfO ++;
    }
}
if ( numOfO == size ){
    result = 0;
} else if (numOfX == size){
    result = 1;
}
// 反对角线
numOfO = numOfX = 0;
for ( i=0; i<size; i++){
    if ( board[i][size-i-1] == 1 ){
        numOfX ++;
    } else {
        numOfO ++;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘志达@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值