8.C语言数组

8.C语言数组

8.1.1 初识数组

  • 如何写一个程序计算用户输入的数字的平均数?

    • 不需要记录输入的每一个数
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    int main()
    {
    	int x;
    	double sum = 0;
    	int cnt = 0;
    	scanf("%d", &x);
    	while (x != -1)
    	{
    		sum += x;
    		cnt++;
    		scanf("%d",&x);
    	}
    	if (cnt > 0)
    	{
    		printf("%f\n", sum / cnt);
    	}
    	return 0;
    }
    
  • 如何写一个程序计算用户输入的数字的平均数,并输出所有大于平均数的数?

    • 如何记录很多数?

    • int num1,num2,…循环

  • 数组:

    • int number[100];

    • scanf(“%d”,&number[i]);

    • #define _CRT_SECURE_NO_WARNINGS
      #include<stdio.h>
      int main()
      {
      	int x;
      	double sum = 0;
      	int cnt = 0;
      	scanf("%d", &x);
      	int number[100];//不同
      	while (x != -1)
      	{
      	    number[cnt]=x;//不同number这个数组里面的cnt这个位置上的单元=x,随着x的不断的读入,只要x不等于-1,都会放到number这个数组中
      		sum += x;
      		cnt++;
      		scanf("%d",&x);
      	}
      	if (cnt > 0)
      	{
      		printf("%f\n", sum / cnt);
      		int i;//
      		for(i=0;i<cnt++;i++)
      		{
      		  if(number[i]>sum/cnt)
      		  {
      		   printf("%d\n",number[i])
      		  }
      		}
      	}
      	
      	return 0;
      }//这个程序是危险的,因为输入的数据可能超过100个
      解决方法:
      1.在读数过程中加上计数,加上cnt,一旦达到100,就不能读数
      2.利用c99的特性:在定义时数组采用的那个大小是动态的
      可以让用户先输入一个数字,改变题目:不能说输入-1表示结束,改为先让用户输入数字,这个数字用来表明下面要输入多少个数字来求平均数,得到这个cnt后 去创建number数组
      
      • int number[100];// 定义数组

      • number[cnt]=x;对数组中的元素赋值

        • number[i]>sum/cnt

        • printf(“%d\n”,number[i]使用数组中的元素

      • for(i=0;i<cnt++;i++)
        {
        if(number[i]>sum/cnt)
        {
        printf(“%d\n”,number[i])
        }
        if(number[i]>sum/cnt)
        {
        printf(“%d\n”,number[i])
        }
        }遍历数组

8.1.2 定义数组

  • <类型>变量名称[元素数量];
    • int grade[100];
    • double weight[20];
  • 元素数量必须是整数
  • C99之前:元素数量必须是编译时刻确定的字面量
  • 是一种容器(放东西是东西),特点是:
    • 其中所有的元素具有相同的数据类型;
    • 一旦创建,不能改变大小
    • *(数组中的元素在内存中是连续依次排列的)
  • eg:int a[10]
    • 一个int的数组
    • 10个单元:a[0],a[1],…a[9]
    • 每个单元就是一个int类型的变量
    • 可以出现在赋值的左边或右边
      • a[2]=a[1]+6;
    • *在赋值左边的叫做左值
  • 数组的单元:
    • 数组的每个单元就是数组类型的一个变量
    • 使用数组时放在[]中的数字叫做下标或索引,下标从0开始计数:
      • grade[0]
      • grade[99]
      • averge[5]
      • ps:根据情况选择读法, 数学中叫做下标
        • 最大下标的是数组的个数减1,而不是数组的个数
  • 有效的下标范围
    • 编译器和运行环境都不会检查数组下标是否越界,无论是对数组单元做读还是写
    • 一旦程序运行,越界的数组访问可能造成问题,导致程序崩溃
      • segmentation fault
    • 但有可能是运气好,没造成严重的后果
    • 所以这是程序员的责任来保护程序只使用有效的下标值:[0,数组的大小-1]
    • eg:
#include<stdio.h>
void f();
int main()
{
 f();
 return 0;
}
void f()
{
 int a[10];
 a[10] = 0;//范围超出
}
  • 长度为0的数组?
    • int a[0];
    • 可以存在,但是无用
    • 长度为0的数组意味它的有效的下标是不存在的,即使是0也是越界了

8.1.3 数组的例子

  • 写一个程序,输入数量不确定的[0,9]范围内的整数,统计每一种数字出现的次数,输入-1表示结束
#include<stdio.h>
int main(void)
{
	const int number = 10;//数组的大小
	int x;
	int count[10];//定义数组
	int i;
	for (i = 0; i < number; i++)
	{
		count[i] = 0;
	}//初始化数组
	scanf("%d", &x);
	while (x != -1)
	{
		if (x >= 0 && x <= 9)
		{
			count[x]++;//数组参与运算
		}
		scanf("%d", &x);
	}
	for (i = 0; i < number; i++)
	{
		printf("%d:%d\n", i, count[i]);
	}//遍历数组输出
	return 0;
}

for (i = 0; i < number; i++)
	{
		count[i] = 0;
	}//初始化数组看
	可写为int count[10]={0};
  • 一般来说都要有这些步骤:
 - 数组的大小
 - 定义数组
 - 初始化数组
 - 数组参与运算
 - 遍历数组输出

8.2.1 数组运算

  • 在一组给定的数据中,如何找出某个数据是否存在?
int search(int key, int a[], int length);

int main(void)
{
	int a[] = { 2,4,6,7,1,3,5,9,11,12,23,14,32 };
	/*{
		int i;
		for (i = 0; i < 13; i++)
		{
			printf("%d\t", a[i]);
		}
		printf("\n");
	}*/
	int x;
	int loc;
	printf("请输入一个数字:");
	scanf("%d", &x);
	loc = search(x, a, sizeof(a) / sizeof(a[0]));
	if (loc != -1)
	{
		printf("%d在第%d个位置上\n", x, loc);
	}
	else
	{
		printf("%d不存在\n", x);
	}
	return 0;
}
int search(int key, int a[], int length)
{
	int ret = -1;
	int i;
	for (i = 0; i < length; i++)
	{
		if (a[i] == key) {
			ret = i;
			break;
		}
	}return ret;
}
  • 数组的集成初始化:
    • int a[] = { 2,4,6,7,1,3,5,9,11,12,23,14,32 };
    • 直接用大括号给出数组的所有元素的初始值
    • 不需要给出数组的大小,编译器替你数数
  • 集成初始化的定位:
    • int a[10]={[0]=2,[2]=3,6,};
    • 用[n]在初始化数据中给出定位
    • 没有定位的数据接在前面的位置后面
    • 其他位置的值补零
    • 也可以不给出数组大小,让编译器算
    • 特别适合初始数据稀疏的数组
    • 只有c99使用
  • 数组的大小:
    • sizeof给出整个数组所占据的内存的大小,单位是字节

    • 在这里插入图片描述

      • sizeof(a)/sizeof(a[0])
        • sizeof/sizeof那个数组的第一个单元得到这个数组有多少个元素
    • sizeof(a[0])给出数组中单个元素的大小,于是相除就得到了数组的单元个数

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

  • 数组赋值:
    • int a[] = { 2,4,6,7,1,3,5,9,11,12,23,14,32 };
    • int b[]=a;
    • 数组变量本身不能被赋值
    • 要把一个数组的所有元素交给另一个数组,必须采用遍历,意味着需要写一个循环遍历那个数组,把它的每一个元素赋给另一个数组的每个元素
      • for(i=0;i<length;i++)
        {
        b[i]=a[i];
        }
  • 遍历数组:
    • 通常使用for循环,让循环变量i从0到<数组的长度,这样循环体内最大的i正好是数组最大的有效下标
    • 常见错误:
      • 循环结束条件是<=数组长度
      • 离开循环后,继续用i的值来做数组元素的下标
    • 数组作为函数参数时:
      • 往往必须再用另一个参数来传入数组的大小
      • 不能在[]中给出数组的大小
      • 不能再利用sizeof来计算数组的元素个数

    8.2.2 数组例子:素数

    • 欲构造n以内的素数表:
      • 令x为2
      • 将2x,3x,4* x直至ax<n的数标记为非素数
      • 令x为下一个没有被标记为非素数的数,重复2;直到所有的数都已经尝试完毕
      • 2.伪代码
      • 开辟Prime[n],初始化其所有元素为1,Prime[x]为1表示x是素数
      • 令x=2
      • 如果x是素数,则对于(i=2;xi<n;i++)令Prime[ix]=0
      • 令x++,如果x<n,重复3,否则结束

8.2.3 二维数组

  • eg: int a[3][5];
    • 理解为a是一个3行5列的矩阵
    • 在这里插入图片描述
  • 二维数组遍历:
for (i = 0; i < 3; i++)
{
	for (j = 0; j < 5; j++)
	{
		a[i][j] = i * j;
	}
}
    • a[i][j]是一个int
    • 表示第i行第j列上的单元
    • a[i,j]是什么?
      • i,j是一个表达式,计算结果是j,等于a[j],并不是正确的二维数组表达方式
  • 二维数组初始化:
    • eg: int a[][5]={{0,1,2,3,4,},{2,3,4,5,6},};
    • 列数是必须给出的,行数可以由编译器来数
    • 每行一个{},逗号分隔
    • 最后逗号可以存在,有古老的传统
    • 如果省略,表示补零
    • 也可以用定位(*C99 ONLY)
  • tic-tac-toe游戏
    • 读入一个3*3的矩阵,矩阵中的数字1表示该位置上有一个x,为0表示为O
    • 程序判断这个矩阵中是否有获胜的一方,输出表示获胜一方的字符X或O,或输出无人获胜
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值