您的位置:首页 > 编程语言 > C语言/C++

网易云课堂程序设计入门—C语言第六周 数组学习笔记

2016-11-23 10:14 507 查看

第六周 数组

标签(空格分隔):程序设计入门—C语言

6.1数组

写一个程序,计算用户输入的平均数,并输出所有大于平均数的数



定义数组

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


int greads[100];

double weight[20];

元素数量必须为整数

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

数组

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

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

一旦创建,不能改变大小

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

int a [10];

一个int数组

10个单元:a[0],a[1],a[2]……a[9]

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

可以出现在赋值的左边和右边,a[1]=a[2]+6; *在赋值的左边叫做左值

数组的单元

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

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

有效的下标范围

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

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

segmentation fault 可能是下标越界

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

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

数组例子:统计个数

#include<stdio.h>
//输入[1,9]输入-1结束,统计输入各个数字的个数
main(void){
const int number =10;  //数组的大小 C99
int x;
int count[number];  //定义数组
int i;

for(i=0;i<number;i++){  //初始化数组
count[i]=0;         //
}                       //
scanf("%d",&x);
while(x!=-1){
if(x>=0 && x<10){
count[x]+=1;   //数组参与运算
}
scanf("%d",&x);
}
for(i=0;i<number;i++){                      //遍历数组输出
printf("%d输入了%d次\n",i,count[i]);     //
}                                           //
return 0;
}


6.2数组运算

搜索

#include<stdio.h>
/*
找出key在数组中的位置,
@param key 要寻找的数字
@param a[] 要寻找的数组
@param length 数组a的长度
@return如果找到返回其在a中的位置,如果找不到则返回-1
*/
int search(int key,int a[],int length);

int main (void){
int a[]={2,4,6,7,1,3,5,9,11,13,23,14,32};
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不存在",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,13,15,};

int a[4]={1} –>{1,0,0,0,}给一个单元值,后面的没给值

int a[5]={0} –>{0,0,0,0,0,}代替遍历初始化

集成初始化时的定位 (C99)

int a[10] = {[0]=2,[2]=2,6,7} –>{2,2,6,7,0,0,0,0,0,0}

数组的大小

sizeof给出整个数组所占据的内容的大小,单位是字节

sizeof(a)/sizeof(a[0])

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

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

数组的赋值

int a[] = {1,3,5,7,}

int b[] = a; (错)

数组变量本身不能被赋值

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

遍历数组

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

程序员写for一般从0到小于某个数,而不是从1到小于等于某个数

常见错误

*循环的条件是<=数组的长度或;

*离开循环后,继续用i的值做数组元素的下标,因为离开时,i正好等于length是无效下标

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

不能在[ ]中给出数组的大小,不能再利用sizeof来计算数组的元素个数

/n 回车

/t 下一个制表符

素数

#include<stdio.h>
#include<math.h>
//int isPrime (int x){
//  int ret =1;
//  int i;
//  if (x==1||(x%2==0&&x!=2)){ //如果x是偶数,就不是素数
//      ret =0;
//  }
//  for (i=2;i<sqrt(x);i++){  //值需要循环sqrt(x)遍
//      if(x%i==0){
//          ret =0;
//          break;
//      }
//  }
//  return ret;
//}

//判断是否能被已知的且<X的素数整除
int isPrime (int x,int knowPrimes[],int numberOfKnowPrime) {
int ret =1;
int i;
for (i=0;i<numberOfKnowPrime;i++){
if(x % knowPrimes[i]==0){
ret =0;
break;
}
}
return ret;
}

int main (void){
const int number =7;//100;
int prime[number]={2};  //
int count =1;
int i =3;
{//调试输出  输出表头
int i;
printf("\t\t");
for( i=0;i<number;i++) {
printf("%d\t",i);
}
printf("\n");
}
while (count<=number){
if (isPrime(i,prime,count)){
prime[count++]=i;  //常见套路
}
{//调试输出
//加大括号是为了在里面定义自己的变量,而不会影响到外面的变量
printf ("i=%d \tcnt=%d\t",i,count) ;
{
int i;
for( i=0;i<number;i++){
printf("%d\t",prime[i]);
}
printf("\n");
}
}
i++;
}
for (i=0;i<number;i++){
printf("%d",prime[i]);
if ( (i+1)%5 ) printf ("\t");
else printf("\n");
}
return 0;
}


/*
构造素数表  算法不一定和人的思考方式相同
欲构造N以内(不含)的素数表
1 令x为2
2 将2X 3X 4X直至aX<n的数标记为非素数
3 令x为下一个没有被标记为非素数的数,重复2;直到所有的数都尝试完毕
-->
1 开辟prime
,初始化其所有元素为1,prime[x]为1表示是素数
2 令 x=2
3 如果x是素数,则对于(i=2;x*i<n;i++)令prime[i*x]=0
4 令x++,如果x<n,重复3,否则结束
*/

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


二维数组

int a[3][5]; 通常理解为a是一个三行五列的矩阵

二维数组的遍历

for(i=0; i<3; i++){
for(j=0; j<5; j++){
a[i][j]=i*j;  //a[i][j]是一个int,表示第i行第j列上的单元
}
}


二维数组的初始化

列数是必须给出的,行数可以用编译器来数

每行一个{},逗号分离

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

如果省略,表示补零

也可以用定位(*C99 Only)

int a[][5]={
{0,1,2,3,4},
{2,3,4,5,6},
};


tic-tac-toe

#include<stdio.h>
int main(void){
const int size =3;
int board[size][size];
int i,j;
int numOfO;
int numOfX;
int result =-1;//-1没人赢; 0:O赢; 1:X赢
//读入矩阵
for(i=0;i<size;i++){
for (j=0;j<size;j++){
scanf("%d",&board[i][j]);
}
}
//检查行
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==3){
result = 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==3){
result = 1;
}
}
}
//检查对角线
if(result==-1){
numOfO=numOfX=0;
for(i=0;i<size;i++){
if(board[i][i]==1){
numOfX++;
}else{
numOfO++;
}
}
numOfO=numOfX=0;
for(i=0;i<size;i++){
if(board[i][size-i-1]==1){
numOfX++;
}else{
numOfO++;
}
}
if(numOfO==size){
result = 0;
}else if(numOfX==3){
result = 1;
}
}
//结果
if(result==1){
printf("X赢了!\n");
} else if(result ==0){
printf("0赢了!\n");
} else{
printf("平局\n");
}

printf(" ————————————\n");
for(i=0;i<size;i++){
for(j=0;j<size;j++){
printf("|   %d   ",board[i][j]);
}
printf("|\n  ———————————\n");
}
return 0;
}


以下程序片段的输出结果是:(A)

int m[][3] = {1,4,7,2,5,8,3,6,9,};
int i,j,k=2;
for ( i=0; i<3; i++ ) {
printf("%d", m[k][i]);
}


A.369

B.不能通过编译

C.789

D.能编译,但是运行时数组下标越界了

第六周编程题

1 多项式加法(5分)

题目内容:一个多项式可以表达为x的各次幂与系数乘积的和,比如:


现在,你的程序要读入两个多项式,然后输出这两个多项式的和,也就是把对应的幂上的系数相加然后输出。程序要处理的幂最大为100。

输入格式:

总共要输入两个多项式,每个多项式的输入格式如下:

每行输入两个数字,第一个表示幂次,第二个表示该幂次的系数,所有的系数都是整数。第一行一定是最高幂,最后一行一定是0次幂。

注意第一行和最后一行之间不一定按照幂次降低顺序排列;如果某个幂次的系数为0,就不出现在输入数据中了;0次幂的系数为0时还是会出现在输入数据中。

输出格式:从最高幂开始依次降到0幂,如:2x6+3x5+12x3-6x+20

注意其中的x是小写字母x,而且所有的符号之间都没有空格,如果某个幂的系数为0则不需要有那项。

输入样例:

6 2

5 3

3 12

1 6

0 20

6 2

5 3

2 12

1 6

0 20

输出样例:

4x6+6x5+12x3+12x2+12x+40

#include<stdio.h>
int main(void){
const int a =101;
int num[a]={0}; //初始化数组
//  int num[a];
//  for(i=0;i<a;i++){
//      num[i]=0;
//  }

int m=0; //计数
int mi,xi;
while(m!=2){
do{
scanf("%d %d", &mi, &xi);
num[mi]+=xi;
}while(mi!=0);
m++;
}

int zui;//最高次幂
int i;
for(i=100;i>1;i--){
if(num[i]!=0){
zui=i;
printf("%dx%d",num[i],i);
break;
}
}

for(i=zui-1;i>1;i--){
if(num[i]!=0){
printf("+%dx%d",num[i],i);
}
}

if(num[1]!=0){
printf("+%dx",num[1]);
}
if(num[0]!=0){
printf("+%d",num[0]);
}
return 0;
}


2 鞍点(5分)

题目内容:给定一个n*n矩阵A。矩阵A的鞍点是一个位置(i,j),在该位置上的元素是第i行上的最大数,第j列上的最小数。一个矩阵A也可能没有鞍点。你的任务是找出A的鞍点。

输入格式:输入的第1行是一个正整数n,(1<=n<=100),然后有n行,每一行有n个整数,同一行上两个整数之间有一个或多个空格。

输出格式:对输入的矩阵,如果找到鞍点,就输出其下标。下标为两个数字,第一个数字是行号,第二个数字是列号,均从0开始计数。

如果找不到,就输出

NO

题目所给的数据保证了不会出现多个鞍点。

输入样例:

4

1 7 4 1

4 8 3 6

1 6 1 2

0 7 8 9

输出样例:

2 1

#include<stdio.h>
int main (void){
int x;
scanf("%d",&x);
if(x>0 && x<=100){
int n[x][x];
int i,j;
for (i=0;i<x;i++){
for (j=0;j<x;j++){
scanf("%d",&n[i][j]);
}
}
int find =0;
int zhao =1;
for (i=0;i<x;i++){
for (j=0;j<x;j++){
zhao=1;
for(int a=0;a<x;a++){
if(n[i][j]<n[i][a]){
zhao=0;
break;
}
if(n[i][j]>n[a][j]){
zhao=0;
break;
}
}
if(zhao==1){
printf("%d %d\n",i,j);
find =1;
}
}
}
if(find==0){
printf("NO");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 网易