第六章 数组
前言
自己身为计算机小白,刚入大一才接触程序设计,我相信有很多和我一样想学好c语言却不知怎么努力的同学,所以我想在大一期末前系统的复习整个学年的c语言知识,并且分享给大家,共同学习和进步。以下内容有的是自己所见所学,也有从别处借鉴,有误之处还请广大网友指正。
这里分享我自学的网站:c.biancheng.net 这个网站真的是简单易懂,受益匪浅,很适合我这种菜鸟小白自学。
目录
一、基础知识点
6.1什么是数组
举了一个例子,是输出一个 4×4 的整数矩阵,代码如下:
- #include
- #include
- int main()
- {
- int a1=20, a2=345, a3=700, a4=22;
- int b1=56720, b2=9999, b3=20098, b4=2;
- int c1=233, c2=205, c3=1, c4=6666;
- int d1=34, d2=0, d3=23, d4=23006783;
- printf("%-9d %-9d %-9d %-9d\n", a1, a2, a3, a4);
- printf("%-9d %-9d %-9d %-9d\n", b1, b2, b3, b4);
- printf("%-9d %-9d %-9d %-9d\n", c1, c2, c3, c4);
- printf("%-9d %-9d %-9d %-9d\n", d1, d2, d3, d4);
- system("pause");
- return 0;
- }
运行结果:
20 345 700 22 56720 9999 20098 2 233 205 1 6666 34 0 23 23006783
为了减少变量的数量,让开发更有效率,使用数组(Array)为多个数据定义一个变量。
#include<stdio.h>
int main()
{
int i;
int a[4]={20,345,700,22},
b[4]={56720,9999,20098,2},
c[4]={233,205,1,6666},
d[4]={34,0,23,23006783};
for(i=0;i<4;i++)
{
printf(" %-9d",a[i]);
}
printf("\n");
for(i=0;i<4;i++)
{
printf(" %-9d",b[i]);
}
printf("\n");
for(i=0;i<4;i++)
{
printf(" %-9d",c[i]);
}
printf("\n");
for(i=0;i<4;i++)
{
printf(" %-9d",d[i]);
}
return 0;
}
我们借助数组来输出一个 4×4 的矩阵:
#include <stdio.h>
int main()
{
int a[4] = {20, 345, 700, 22};
int b[4] = {56720, 9999, 20098, 2};
int c[4] = {233, 205, 1, 6666};
int d[4] = {34, 0, 23, 23006783};
printf("%-9d %-9d %-9d %-9d\n", a[0], a[1], a[2], a[3]);
printf("%-9d %-9d %-9d %-9d\n", b[0], b[1], b[2], b[3]);
printf("%-9d %-9d %-9d %-9d\n", c[0], c[1], c[2], c[3]);
printf("%-9d %-9d %-9d %-9d\n", d[0], d[1], d[2], d[3]);
return 0;
}
数组的概念和定义
要想把数据放入内存,必须先要分配内存空间
放入4个整数,就得分配4个int
类型的内存空间:
在定义数组的同时赋值 int a[4]={1,2,3,4}; 注意定义时{ , , ,}
这样,就在内存中分配了4个int
类型的内存空间,共 4×4=16 个字节,并为它们起了一个名字,叫a
。
我们把这样的一组数据的集合称为数组(Array),它所包含的每一个数据叫做数组元素(Element),所包含的数据的个数称为数组长度(Length),例如int a[4];
就定义了一个长度为4的整型数组,名字是a
。
数组中的每个元素都有一个序号,这个序号从0开始,而不是从我们熟悉的1开始,称为下标(Index)。
arrayName 为数组名称,index 为下标。例如,a[0] 表示第0个元素,a[3] 表示第3个元素。
a[0]=20; a[1]=345; a[2]=700; a[3]=22;
我们来总结一下数组的定义方式:
- float m[12]; //定义一个长度为 12 的浮点型数组
- char ch[9]; //定义一个长度为 9 的字符型数组
- int a[4];//定义一个长度为4的整数型数组
对于数组的初始化需要注意以下几点:
1) 可以只给部分元素赋值。当{ }
中值的个数少于元素个数时,只给前面部分元素赋值。例如:
int a[10]={12, 19, 22 , 993, 344};
表示只给 a[0]~a[4] 5个元素赋值,而后面 5 个元素自动初始化为 0。
当赋值的元素少于数组总体元素的时候,剩余的元素自动初始化为 0:
- 对于short、int、long,就是整数 0;
- 对于char,就是字符 '\0';
- 对于float、double,就是小数 0.0。
我们可以通过下面的形式将数组的所有元素初始化为 0:
int nums[10] = {0}; char str[10] = {0}; float scores[10] = {0.0};
由于剩余的元素会自动初始化为 0,所以只需要给第 0 个元素赋值为 0 即可。
2) 只能给元素逐个赋值,不能给数组整体赋值。例如给 10 个元素全部赋值为 1,只能写作:
int a[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
而不能写作: int a[10] = 1;
3) 如给全部元素赋值,那么在定义数组时可以不给出数组长度。例如:
int a[ ] = {1, 2, 3, 4, 5};
等价于
int a[5] = {1, 2, 3, 4, 5};
数组内存是连续的
(连续的内存为指针操作(通过指针来访问数组元素)和内存处理(整块内存的复制、写入等)提供了便利,这使得数组可以作为缓存(临时存储数据的一块内存)使用。)
数组是一个整体,它的内存是连续的;也就是说,数组元素之间是相互挨着的,彼此之间没有一点点缝隙。下图演示了int a[4];
在内存中的存储情形:
这里的0、1、2、3就是数组下标,a[0]、a[1]、a[2]、a[3] 就是数组元素。
在学习过程中,我们经常会使用循环结构将数据放入数组中(也就是为数组元素逐个赋值),然后再使用循环结构输出(也就是依次读取数组元素的值)
#include <stdio.h>
int main()
{
int i,a[10];
//将1~10放入数组中
for(i=0; i<10; i++)
{
n[i] = (i+1);
}
//依次输出数组元素
for(i=0; i<10; i++)
{
printf("%d ", n[i]);
}
return 0;
}
运行结果:
1 2 3 4 5 6 7 8 9 10
更改上面的代码,让用户输入 10 个数字并放入数组中(从控制台读取用户输入):
#include <stdio.h>
int main()
{
int i,a[10];
//从控制台读取用户输入
for(i=0; i<10; i++) //数组 a 的最大下标是 9,也就是不能超过 10
{
scanf("%d", &a[i]); //注意取地址符 &,不要遗忘哦
}
//依次输出数组元素
for(i=0; i<10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
运行结果:
22 18 928 5 4 82 30 10 666 888↙
22 18 928 5 4 82 30 10 666 888
6.2C语言二维数组
我们可以将二维数组看做一个 Excel 表格,有行有列,length1 表示行数,length2 表示列数,要在二维数组中定位某个元素,必须同时指明行和列。例如:
int a[3][4];
定义了一个 3 行 4 列的二维数组,共有 3×4=12 个元素,数组名为 a,即:
a[0][0], a[0][1], a[0][2], a[0][3]
a[1][0], a[1][1], a[1][2], a[1][3] 如果想表示第 2 行第 1 列的元素,应该写作 a[2][1]。
a[2][0], a[2][1], a[2][2], a[2][3]
二维数组的各个元素也是相互挨着的,彼此之间没有缝隙。
- 一种是按行排列, 即放完一行之后再放入第二行;在C语言中,二维数组是按行排列的。
另一种是按列排列, 即放完一列之后再放入第二列。
a[0][0], a[0][1], a[0][2], a[0][3]------a[0]行
a[1][0], a[1][1], a[1][2], a[1][3]------a[1]行
a[2][0], a[2][1], a[2][2], a[2][3]------a[2]行先存放完a[0],a[1],a[2]行,再存放每一行中的4个元素。此数组占用(3✖4)✖4=48字节。
二维数组的初始化(赋值)
二维数组的初始化可以按行分段赋值,也可按行连续赋值。
对于二维数组的初始化还要注意以下几点:
1) 可以只对部分元素赋值,未赋值的元素自动取“零”值。例如:
int a[3][3] = {{1}, {2}, {3}}; int a[3][3] = {{0,1}, {0,0,2}, {3}};
是对每一行的第一列元素赋值,未赋值的元素的值为 0。赋值后各元素的值为:
1 0 0 0 1 0
2 0 0 0 0 2
3 0 0 3 0 0
2) 如果对全部元素赋值,那么第一维的长度可以不给出。例如:
int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int a[][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
3) 二维数组可以看作是由一维数组嵌套而成的;如果一个数组的每个元素又是一个数组,那么它就是二维数组。当然,前提是各个元素的类型必须相同。根据这样的分析,一个二维数组也可以分解为多个一维数组,C语言允许这种分解。
a[3][4]可以分解为a[0],a[1],a[2]三个均有4个元素的一维数组,
a[0][0], a[0][1], a[0][2], a[0][3]
a[1][0], a[1][1], a[1][2], a[1][3]
a[2][0], a[2][1], a[2][2], a[2][3]
6.3判断数组中是否包含某个元素
对无序数组的查询
所谓无序数组,就是数组元素的排列没有规律。无序数组元素查询的思路也很简单,就是用循环遍历数组中的每个元素,把要查询的值挨个比较一遍。请看下面的代码:
#include<stdio.h> int main() { int i,n,thisindex=-1; int a[10]={1,10,6,296,177,23,0,100,34,999}; scanf("%d",&n); for(i=0;i<10;i++) { if(a[i]==n) //if括号中要用==,且后面用大括号{} { thisindex=i; //把i赋值给thisindex break; //找到相等的数,打印下标,跳出循环 } } if(thisindex<0) { printf("%d isn't in the array.\n",n); } else { printf("%d is in the array, it's index is %d.\n",n,thisindex); } }
运行结果:
100↙
100 is in the array, it's index is 7.28↙
28 isn't in the array.
注意:数组下标的取值范围是非负数,当 thisindex >= 0 时,该数字在数组中,当 thisindex < 0 时,该数字不在数组中,所以在定义 thisindex 变量时,必须将其初始化为一个负数。
对有序数组的查询
查询无序数组需要遍历数组中的所有元素,而查询有序数组只需要遍历其中一部分元素。
例如有一个长度为 10 的整型数组,它所包含的元素按照从小到大的顺序(升序)排列,假设比较到第 4 个元素时发现它的值大于输入的数字,那么剩下的 5 个元素就没必要再比较了,肯定也大于输入的数字,这样就减少了循环的次数,提高了执行效率。
#include<stdio.h>
int main()
{
int i,n,thisindex=-1;
int a[10]={1,10,6,296,177,23,0,100,34,999};
scanf("%d",&n);
for(i=0;i<10;i++)
{
if(a[i]==n) //if括号中要用==,且后面用大括号{}
{
thisindex=i; //把i赋值给thisindex
break; //找到相等的数,打印下标,跳出循环
}
else if(a[i]>n) break;
}
if(thisindex<0)
{
printf("%d isn't in the array.\n",n);
}
else
{
printf("%d is in the array, it's index is %d.\n",n,thisindex);
}
}
6.4C语言字符数组和字符串
用来存放字符的数组称为字符数组,例如:
- char a[10]; //一维字符数组
- char b[5][10]; //二维字符数组
- char c[20]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'}; // 给部分数组元素赋值
- char d[ ]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' }; //对全体元素赋值时可以省去长度
字符数组实际上是一系列字符的集合,也就是字符串(String)。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。
C语言规定,可以将字符串直接赋值给字符数组,例如:
char str[30] = {"wlacm.com"};
为了方便,也可以不指定数组长度,从而写作:
char str[] = {"wlacm.com"};
字符数组只有在定义时才能将整个字符串一次性地赋值给它,一旦定义完了,就只能一个字符一个字符地赋值了。
数组第 0 个元素为'w',第 1 个元素为
'l'
,第6 个元素为'.'
,后面的元素以此类推。
字符串结束标志(划重点)
在C语言中,字符串总是以'\0'
作为结尾,所以'\0'也被称为字符串结束标志,或者字符串结束符。
C语言在处理字符串时,会从前往后逐个扫描字符,一旦遇到'\0'
就认为到达了字符串的末尾,就结束处理。'\0'
至关重要,没有'\0'
就意味着永远也到达不了字符串的结尾。
下图演示了"C program"
在内存中的存储情形:
由
" "
包围的字符串会自动在末尾添加'\0'
。例如,"C program"
从表面看起来只包含了 9 个字符,其实不然,C语言会在最后隐式地添加一个'\0'
,这个过程是在后台默默地进行的,所以我们感受不到。当用字符数组存储字符串时,要特别注意
'\0'
,要为'\0'
留个位置;这意味着,字符数组的长度至少要比字符串的长度大 1。请看下面的例子:
char str[7] = "abc123";
需要注意的是,逐个字符地给数组赋值并不会自动添加'\0'
,例如:
char str[] = {'a', 'b', 'c'};
数组 str 的长度为 3,而不是 4,因为最后没有
'\0'
。
接下来没看懂的。。。
要想避免这些问题也很容易,在字符串的最后手动添加'\0'
即可。修改上面的代码,在循环结束后添加'\0'
#include <stdio.h> int main(){ char str[30]; char c; int i; for(c=65,i=0; c<=90; c++,i++){ str[i] = c; } str[i] = 0; //此处为添加的代码,也可以写作 str[i] = '\0'; printf("%s\n", str); return 0; }
第 9 行为新添加的代码,它让字符串能够正常结束。根据 ASCII 码表,字符
'\0'
的编码值就是 0。
但是,这样的写法貌似有点业余,或者说不够简洁,更加专业的做法是将数组的所有元素都初始化为“零”值,这样才能够从根本上避免问题。再次修改上面的代码:
#include <stdio.h> int main(){ char str[30] = {0}; //将所有元素都初始化为 0,或者说 '\0' char c; int i; for(c=65,i=0; c<=90; c++,i++){ str[i] = c; } printf("%s\n", str); return 0; }
字符串长度
在C语言中,我们使用string.h
头文件中的 strlen() 函数来求字符串的长度
#include <stdio.h>
#include <string.h> //记得引入该头文件
int main(){
char str[] = "http://c.biancheng.net/c/";
long len = strlen(str);
printf("The lenth of the string is %ld.\n", len);
return 0;
}
C语言字符串的输入和输出
字符串的输出
- puts():输出字符串并自动换行,该函数只能输出字符串。
- printf():通过格式控制符 %s输出字符串,不能自动换行
#include <stdio.h>
int main(){
char str[] = "I.Love.You";
printf("%s\n", str); //通过字符串名字输出
printf("%s\n", "I.Love.You"); //直接输出
puts(str); //通过字符串名字输出
puts("I.Love.You"); //直接输出
return 0;
}
输出字符串时只需要给出名字,不能带后边的[ ]
字符串的输入
- scanf():通过格式控制符
%s
输入字符串。 - gets():直接输入字符串,并且只能输入字符串。
scanf() 和 gets() 是有区别的:
- scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以***无法读取含有空格的字符串。***
- gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,所以,不管输入了多少个空格,只要不按下回车键,对 gets() 来说就是一个完整的字符串。换句话说,***gets() 用来读取一整行字符串。***
#include <stdio.h> int main() { char str1[30] = {0}; char str2[30] = {0}; //gets() 用法 printf("Input a string: "); gets(str1); //scanf() 用法 printf("Input a string: "); scanf("%s", str2); //注意这行scanf() printf("str1: %s\n", str1); printf("str2: %s\n", str2); return 0; }
就目前学到的知识而言,int、char、float 等类型的变量用于 scanf() 时都要在前面添加
&
,而数组或者字符串用于 scanf() 时不用添加&
,它们本身就会转换为地址。
C语言字符串处理函数
C语言提供了丰富的字符串处理函数,可以对字符串进行输入、输出、合并、修改、比较、转换、复制、搜索等操作,使用这些现成的函数可以大大减轻我们的编程负担。
string.h
是一个专门用来处理字符串的头文件
字符串连接函数 strcat()
strcat 是 string catenate 的缩写,意思是把两个字符串拼接在一起,语法格式为:
strcat(arrayName1, arrayName2);
strcat() 将把 arrayName2 连接到 arrayName1 后面,并删除原来 arrayName1 最后的结束标志'\0'
。这意味着,arrayName1 必须足够长,要能够同时容纳 arrayName1 和 arrayName2,否则会越界(超出范围)。
strcat() 的返回值为 arrayName1 的地址。
#include<stdio.h>
#include<string.h>
int main()
{
char s1[100]="AC ";
char s2[100];
gets(s2);
strcat(s1,s2);
puts(s1);
return 0;
}
输入:
is not the true happiness.
输出:
AC is not the true happiness.
字符串复制函数 strcpy()
strcpy 是 string copy 的缩写,意思是字符串复制,也即将字符串从一个地方复制到另外一个地方,语法格式为:
strcpy(arrayName1, arrayName2);
strcpy() 会把 arrayName2 中的字符串拷贝到 arrayName1 中,字符串结束标志'\0'
也一同拷贝。
strcpy() 要求 arrayName1 要有足够的长度,否则不能全部装入所拷贝的字符串。请看下面的例子:
#include <stdio.h>
#include <string.h>
int main(){
char str1[50] = "AC不是真正的快乐。";
char str2[50] = "AC is not the true happiness.";
strcpy(str1, str2);
printf("%s\n", str1);
return 0;
}
***字符串比较函数 strcmp()
strcmp 是 string compare 的缩写,意思是字符串比较,语法格式为:
strcmp(arrayName1, arrayName2);
字符本身没有大小之分,strcmp() 以各个字符对应的 ASCII 码值进行比较。strcmp() 从两个字符串的第 0 个字符开始比较,如果它们相等,就继续比较下一个字符,直到遇见不同的字符,或者到字符串的末尾。
返回值:若 arrayName1 和 arrayName2 相同,则返回0;若 arrayName1 大于 arrayName2,则返回大于 0 的值;若 arrayName1 小于 arrayName2,则返回小于0 的值。
对4组字符串进行比较:
#include <stdio.h>
#include <string.h>
int main(){
char a[] = "aBcDeF";
char b[] = "AbCdEf";
char c[] = "aacdef";
char d[] = "aBcDeF";
printf("a VS b: %d\n", strcmp(a, b));
printf("a VS c: %d\n", strcmp(a, c));
printf("a VS d: %d\n", strcmp(a, d));
return 0;
}
运行结果:
a VS b: 32
a VS c: -31
a VS d: 0
6.5排序问题
对数组元素进行排序的方法有很多种,比如冒泡排序、归并排序、选择排序、插入排序、快速排序等,其中最经典最需要掌握的是「冒泡排序」。
以从小到大排序为例,冒泡排序的整体思想是这样的:
- 从数组头部开始,不断比较相邻的两个元素的大小,让较大的元素逐渐往后移动(交换两个元素的值),直到数组的末尾。经过第一轮的比较,就可以找到最大的元素,并将它移动到最后一个位置。
- 第一轮结束后,继续第二轮。仍然从数组头部开始比较,让较大的元素逐渐往后移动,直到数组的倒数第二个元素为止。经过第二轮的比较,就可以找到次大的元素,并将它放到倒数第二个位置。
- 以此类推,进行 n-1(n 为数组长度)轮“冒泡”后,就可以将所有的元素都排列好。
整个排序过程就好像气泡不断从水里冒出来,最大的先出来,次大的第二出来,最小的最后出来,所以将这种排序方式称为冒泡排序(Bubble Sort)。
经典例题:排序;
题目描述:
输入N个数据(整数,至少1个,但不多于20个),按照升序输出,数据项之间有一个空格
输入:
输入中包含多个正整数,读取数据,直到输入结束(至少1个,但不多于20个)
样例输入:
100
8 5
10 80 24
样例输出:
100
5 8
10 24 80
选择排序法
#include<stdio.h>
int main()
{
int i,j,t,n,a[20];
for(i=0;;i++)
{
if(scanf("%d",&a[i])!=1) break;
}
n=i; //读取数组时要令n有范围
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++) //
{
if(a[i]>a[j])
{t=a[i];a[i]=a[j];a[j]=t;}
}
printf("%d ",a[i]);
}
}
冒泡排序法
a[i] a[j]
(10 15 )| 8 7 6 12 9
i=0,j=1,a[0]=10与a[1]=15两个相邻的数先进行比较,不用交换
a[i] a[j]
10 |( 8 15 )| 7 6 12 9
i=1,j=2,a[1]=15与a[2]=8进行比较,需要引入新变量t来达到交换的目的
以此类推
。
。
完成了第一轮
10 8 7 6 12 9 15
第二轮
8 7 6 10 9 12 15
第三轮
7 6 8 9 10 12 15
第四轮
6 7 8 9 10 12 15
#include<stdio.h>
int main()
{
int i,j,t,n,a[20];
for(i=0; ;i++)
{
if(scanf("%d",&a[i])!=1) break;
}
n=i; //读取数组时要令n有范围
for(i=1;i<n;i++)
{
for(j=0;j<n-i;j++)
{
if(a[j]>a[j+1])
{t=a[j];a[j]=a[j+1];a[j+1]=t;}
}
}
for(j=0;j<n;j++)
{
printf("%d ",a[j]);
}
}
二、典型例题
主要是本学年做过的一些典型题,比较有借鉴和反思的地方。
一维数组
溢出,查数,排序(主要都与循环结构搭配)
统计数据的个数
题目描述:输入一组数据(整数,至少1个,但不多于20个),按顺序输出这组数据,并在数据之前输出数据的个数
#include<stdio.h>
int main()
{
int i,n=20,a[20]; //n=20,a[20]只是定义时随意取值,不固定;
for(i=0;i<=n-1;i++)
{
if(scanf("%d",&a[i])!=1) //if(scanf("%d",&n)==1)说明成功读入了n的值;
break; //用户端再输入完数组后输入字符显然不能成功读取时,
//便会结束循环,防止数组溢出;
}
n=i; //把此时结束循环时的i值赋给n,即要求的数据个数;
printf("%d",n); //立刻输出而不能让n进入数组输出的循环结构中;
for(i=0;i<=n-1;i++)
{
printf(" %d",a[i]); //注意输出数组时同样需要循环;
}
}
输入:1 2 3 4 5aaaaa
输出:5 1 2 3 4 5
for(i=0;i<=n-1;i++)
{
if(scanf("%d",&a[i])!=1) 如果没有正确输入一个整型数给数组中的一个元素.
break; 就会结束循环。
}
逆序输出数据
输入一组数据(整数,不多于20个),逆序输出这组数据
#include<stdio.h>
int main()
{
int i,n=20,a[20],k;
scanf("%d",&k);
for(i=0;i<=n-1;i++)
{
if(scanf("%d",&a[i])!=1) break;
}
n=i; //这个条件不能少!!!
for(i=n-1;i>=0;i--)
{
printf(" %d",a[i]);
}
}
个人理解:n=i 这一行读取了输入的数组的数据长度,进而影响下面倒序输出数组时循环的条件。
成绩统计:低于平均值的人数与分数
输入一组成绩(整数,介于[0,100]之间,至少1个,但不多于20个),输出低于平均值的人数与分数
#include<stdio.h>
int main()
{
int i,n=20,a[20],s=0;
float average;
for(i=0;i<=n-1;i++)
{
if(scanf("%d",&a[i])!=1) break;
s=s+a[i];
}
n=i;
average=(s*(1.0)/n);
int k=0,m;
for(i=0;i<=n-1;i++)
{
if(a[i]<average)
{
k=k+1;
}
}
printf("%d",k);
}
我的错误代码只算出了低于平均值的人数,分数没有搞定。
#include<stdio.h>
int main()
{
int i,n,a[100],s=0,k;
for(i=0;;i++)
{
if(scanf("%d",&a[i])!= 1) break;
s=s+a[i];
}
n=i;
k=0;
for(i=0;i<=n-1;i=i+1)
{
if(a[i]<1.0*s/n) k=k+1;
}
printf("%d",k);
for(i=0;i<=n-1;i=i+1)
{
if(a[i]<1.0*s/n)
printf(" %d",a[i]);
}
}
有被自己蠢到😂
#include<stdio.h>
int main()
{
int i,n=20,a[20],s=0;
float average;
for(i=0;i<=n-1;i++)
{
if(scanf("%d",&a[i])!=1) break;
s=s+a[i];
}
n=i;
average=(s*(1.0)/n);
int k=0,m;
for(i=0;i<=n-1;i++)
{
if(a[i]<average)
{
k=k+1;
}
}
printf("%d",k);
for(i=0;i<=n-1;i++)
{
if(a[i]<average)
{
printf(" %d",a[i]);
}
}
}
成绩统计:最小值、最大值、平均值与均方差
输入一组成绩(整数,介于[0,100]之间,至少1个,但不多于20个),计算并输出这组成绩的最小值、最大值、平均值(一位小数)与均方差(两位小数),数据之间空一格
注:均方差的计算公式为:,其中μ为数据的平均值
均方差能够体现各数据项与平均值的偏差程度
例如,一组学生的成绩:80、82、84、86,平均值为83.0
方差D=[(80-83)2+(82-83)2+(84-83)2+(86-83)2]/4=5,均方差σ=2.24(方差D的平方根)
而另一组学生的成绩:82、82、83、85,平均值也为83.0
但是方差D=[(82-83)2+(82-83)2+(83-83)2+(85-83)2]/4=1.5,均方差σ=1.22
说明这一组学生的成绩比较稳定,与平均值的偏差较小
#include<stdio.h> #include<math.h> int main() { int i,n=20,a[20],s=0; float u; for(i=0;i<n;i++) { if(scanf("%d",&a[i])!=1) break; s=s+a[i]; } n=i; u=s*(1.0)/n; printf("%d %d %0.1f",a[0],a[n-1],u); float o,m; int p=0; for(i=0;i<n;i++) { m=(a[i]-u)*(a[i]-u); p=p+m; } o=sqrt((p*1.0)/n); printf(" %0.2f",o); }
小KK的环(竞赛题)
题目描述:
小KK是一个玩圆环的高手。这天,小KK买回来了3个完全相同的圆环,小KK发现这三个圆环通过任意的摆放形成的图形的面积是不同的。小KK决定通过摆出不同的形状的图形来算出图形的面积。请你编写一个程序帮助小KK计算出图形的面积。
以下是三个圆环的其中七种摆放方式,我们将其分别从1~7编号:
输入:
给定一个T代表样例的个数,接下来T行每行给出r,n,s,分别为圆的半径,相交类型的编号(1~7)以及任意两圆相交部分的面积,6号图(三圆相交)会额外给出公共部分的面积p。
PS:请注意π请使用3.14进行计算
输出:
对于每一组输入样例,按照样例格式输出,结果只保留整数部分,样例编号从1开始。
样例输入:
3
2 4 12.56
6.5 6 5 2.1
3 7 2
样例输出:
#Case1 : 25
#Case2 : 385
#Case3 : 54
二维数组
点阵字符
题目描述:
点阵字符是计算机系统中对文字(包括字母、数字、标点符号)字型信息的一种存储方式,其中每个字形都以一组二维像素信息表示,文字笔画经过的区域存储为1,否则存储为0
输入:
输入一个正整数N(N≤24)以及由数值0和1构成的NxN点阵。
输出:
输出对应的字符。
样例输入:
8
0 0 1 1 1 0 0 0
0 1 1 0 1 1 0 0
1 1 0 0 0 1 1 0
1 1 0 0 0 1 1 0
1 1 1 1 1 1 1 0
1 1 0 0 0 1 1 0
1 1 0 0 0 1 1 0
0 0 0 0 0 0 0 0
样例输出:
ooo
oo oo
oo oo
oo oo
ooooooo
oo oo
oo oo
又没复盘出来
#include<stdio.h>
int main()
{
int a[24][24],n;
scanf("%d\n",&n);
int i,j;
scanf("%d",a[i][j]);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(a[i][j]==0) printf(" ");
if(a[i][j]==1) printf("o");
}
}
}
正解
#include<stdio.h>
int main()
{
int i,j,n,a[24][24];
scanf("%d",&n);
for(i=0;i<=n-1;i=i+1)
{
for(j=0;j<=n-1;j=j+1)
{
scanf("%d",&a[i][j]);
}
}
for(i=0;i<=n-1;i=i+1)
{
for(j=0;j<=n-1;j=j+1)
{
if(a[i][j]==1) printf("o");
else printf(" ");
printf("\n");
}
}
}
矩阵转置
题目描述:
输入一个矩阵,共M行N列(1≤M,N≤10),矩阵中的每个元素均为整数,将其转置后输出
输入格式为:两个正整数M,N,之后共有M行N列的整数值
输出:
矩阵转置之后的结果,共N行M列的整数值,每个整数值之前有一个空格,每行结尾有一个\n
样例输入:
2 3 1 2 3 4 5 6 3 2 1 4 2 5 3 6
样例输出:
1 4 2 5 3 6 1 2 3 4 5 6
#include<stdio.h>
int main()
{
int i,j,m,n,a[24][24];
scanf("%d %d",&m,&n);
for(i=0;i<=m-1;i=i+1)
{
for(j=0;j<=n-1;j=j+1)
{
scanf("%d",&a[i][j]);
}
}
for(j=0;j<=n-1;j=j+1)
{
for(i=0;i<=m-1;i=i+1)
{
printf(" %d",a[i][j]);
}
printf("\n");
}
}
杨辉三角
#include<stdio.h>
int main()
{
int a[30][30],i,j,n;
scanf("%d",&n);
for(i=0;i<n;i++)
{
a[0][0]=1;
a[i][i]=1;
for(j=0;j<n;j++)
{
if(i>=j) a[i][j]=a[i-1][j]+a[i-1][j-1];
else printf(" ");
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d",a[i][j]);
}
printf("\n");
}
}
有错误 if(i>=j) a[i][j]=a[i-1][j]+a[i-1][j-1]; ???
#include<stdio.h>
int main()
{
int n,i,j,a[40][40];
scanf("%d",&n);
for(i=0;i<=n;i=i+1)
{
a[i][0]=1;
for(j=1;j<=i;j=j+1)
{
if(i==j) a[i][j]=1;
else a[i][j]=a[i-1][j]+a[i-1][j-1];
}
}
for(i=0;i<=n;i=i+1)
{
for(j=0;j<=i;j=j+1)
printf("%d ",a[i][j]);
printf("\n");
}
}
这里for循环中的条件范围值得深究
#include<stdio.h>
int main()
{
int i,j,n,a[40][40];
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<=i;j++)
{
if(j==0||j==i) a[i][j]=1;
else a[i][j]=a[i-1][j]+a[i-1][j-1];
}
}
for(i=0;i<n;i++)
{
for(j=0;j<=i;j++)
{
printf("%d",a[i][j]);
}
printf("\n");
}
}
字符串数组
判断回文、排序
字符串倒序输出
题目描述:
输入一个字符串,以换行符号作为结束(字符串长度不超过50)将输入内容倒序输出
样例输入:
flow
样例输出:
wolf
正解
1.
#include<stdio.h>
#include<string.h>
int main()
{
char a[100],i,n;
gets(a);
n = strlen(a);
for(i=n-1;i>=0;i=i-1)
printf("%c",a[i]);
}
2.
#include<string.h>
#include<stdio.h>
int main()
{
char s[100];
int i,n,j;
gets(s);
for(i=0; ;i++)
{
if(s[i]=='\0') break;
}
n=i;
for(j=n-1;j>=0;j--)
{
printf("%c",s[j]);
}
}
运行错误或答案错误非正解
#include<stdio.h>
#include<string.h>
int main()
{
char a[50];
int n,i,j,t;
gets(a);
n=strlen(a);
for(i=0,j=n-1;i<=j;i++,j--)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
for(i=0;i<n;i++)
{
printf("%c",a[i]);
}
}
#include<stdio.h>
#include<string.h> //记得引入该头文件
int main()
{
char a[100],i,n;
gets(a); // gets()
n = strlen(a);
for(i=n-1;i>=0;i=i-1)
printf("%c",a[i]); // %c
}
最后一行我用%s输出的是一堆数字
【字符串】回文
题目描述:
输入一行字符串(长度不超过100),判断是否为回文。例如ABA是回文字符串,ABC不是回文字符串。
输入:
键盘输入的一行字符串(没有空格)。不包含结尾的\n
输出:
yes 或 no 表示是否为回文
正解(网上答案)
#include<stdio.h>
#include<string.h>
int main(void)
{
int i,j;
int len; //用于记录字符串长度
char S1[1005];
char S2[1005];
gets(S1);
len = strlen(S1);
for(i=len-1,j=0;i>=0;i--,j++)
{
S2[j] = S1[i]; //将S1逆序赋给S2
}
for(i=0,j=0;i<len;i++,j++)
{
if(S1[i]!=S2[i]) //如果S1正序和逆序不同,则不是回文字符串
{
printf("no");
break;
}
else if(i==len-1)
{
printf("yes");
}
}
return 0;
}
答案错误25%
#include<stdio.h>
#include<string.h>
int main()
{
char s[105];
gets(s);
int i,j,n,k=0;
n=strlen(s);
for(i=0,j=n-1;i<=j;i++,j--)
{
if(s[i]!=s[j]) k=k+1; break;
}
if(k==0) printf("yes");
if(k==1) printf("no");
}
答案错误25%
#include<stdio.h>
#include<string.h>
int main()
{
char s[105];
gets(s);
int i,j,n,k=0;
n=strlen(s);
for(i=0,j=n-1;i<=j;i++,j--)
{
if(s[i]!=s[j]) k=k+1; break;
}
if(k) printf("no"); //啥意思
else printf("yes");
}
运行错误 50%
#include <stdio.h>
#include <string.h>
int main()
{
char str[50];
int i,n,k=0;
gets(str);
n = strlen(str);
for (i = 0; i <= n/2; i++ )
{
if (str[i] != str[n - 1 - i])
{
k=k+1;break;
}
}
if(k==0) printf("yes");
if(k==1) printf("no");
}
运行错误 50%
#include <stdio.h>
#include <string.h>
int main()
{
char str[50];
int i,n;
gets(str);
n = strlen(str);
for (i = 0; i <= n/2; i++ )
{
if (str[i] != str[n - 1 - i])
{
printf("no");
break;
}
else
if (i == n / 2)
printf("yes");
}
}
纠正英文语句中的大小写拼写错误
题目描述:
在书写英文语句时,语句中第一个单词的第一个字母通常需要大写的形式,如 Hello,how are you.
但在录入英文语句时,有时会出现大小写拼写的错误。
请编写程序,纠正录入的英文语句中出现的大小写拼写错误(暂不考虑语句中会出现的缩略词语,如IBM、ZWU)
输入:
输入英文语句,以换行符号作为结束(语句长度不超过50,并且第一个单词之前没有空格或其他符号)
输出:
输出正确的书写形式
样例输入:
hello,How are you.
样例输出:
Hello,how are you.
#include<stdio.h>
#include<string.h>
int main()
{
char a[100];
gets(a);
int i,n,m;
n=strlen(a);
for(i=0;i<=n-1;i++)
{
if(a[0]>=91) a[0]=a[0]-32;
if(a[i]==44)
{
if(a[i+1]<=91&&a[i+1]>=65) a[i+1]=a[i+1]+32;
}
printf("%c",a[i]);
}
}
我们知道,计算机在存储字符时并不是真的要存储字符实体,而是存储该字符在字符集中的编号(也可以叫编码值)。对于 char 类型来说,它实际上存储的就是字符的 ASCII 码。
#include
int main()
{
char s=44;
printf("%c",s);
}
输出:,
大写英文字母:65-90
小写英文字母:97-122
总结
以上就是我所分享的内容,本文仅仅是c语言入门,我也只是计算机小白,希望自己和大家能够在接下来的学习中共同进步,加油。