目录
1 数组
- 是一种容器(放东西的东西)
- 其中所有的元素具有相同的数据类型;
- 一旦创建,无法改变大小
- *(数组中的元素在内存中是连续依次排列的)
找出比平均数大的所有数
#include<stdio.h>
int main()
{
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){
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,所以最多只能输入100个数字。
利用数组将每个数保存下来,再进行遍历。
(1)定义数组
- <类型>变量名称[元素数量]
- int grades[100]
- double weight[20]
- 元素数量必须是整数
- c99之前:元素数量必须是编译时刻确定的字面量
(2)数组的单元
- 数组的每个单元就是数组类型的一个变量
- 使用数组时放在[]中的数字叫做下标或索引,下标从0开始计数:
1)有效的下标范围
- 编译器和运行环境都不会检查数组下标是否越界,无论是对数组单元做读还是写
- 一旦程序运行,越界的数组访问可能造成问题,导致程序崩溃
- segmentation fault
- 但是也有可能运气好,没造成严重的后果
- 所以这是程序员的责任来保证程序只使用有效的下标值:[0,数组的大小-1]
(3)数组展示 统计数的个数(找出0~9出现了几次)
#include<stdio.h>
int main()
{
int x;
int count[10];
int i;
for(i=0;i<10;i++){
count[i]=0;
}
scanf("%d",&x);
while(x!=-1){
if(x>=0&&x<=9){
count[x]++;
}
scanf("%d",&x);
}
for(i=0;i<10;i++){
printf("%d:%d\n",i,count[i]);
}
return 0;
}
但这样写的代码在想要更改范围(更改数组的大小)时比较麻烦,需要改的地方较多容易出现遗漏。
所以利用一个constant int number定义数组的大小,然后用number将10替换掉便于以后代码范围的更改
#include<stdio.h>
int main()
{
const int number=10;
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<=9){
count[x]++;
}
scanf("%d",&x);
}
for(i=0;i<number;i++){
printf("%d:%d\n",i,count[i]);
}
return 0;
}
(4)数组运算
1)数组的集成初始化
int a[]={2,4,3,6,8,4,12,34}
- 直接用大括号给出数组的所有元素的初始值
- 不需要给出数组大小,编译器会自己数
int a[7]={[1]=2,4,[5]=6}
- 对应的数组被赋予大括号中的值
- [1]后有两个值,第一个赋给数组[1],后边的自动赋给数组[2]
- 剩下没有特别指定的都赋值为0
int a[]={[1]=2,4,[5]=6}
- 此数组没有设定数组大小
- 看后边最大的值则为数组的大小
2)数组大小
- sizeof给出整个数组所占据的内容的大小,单位是字节
- sizeof(a)/sizeof(a[0])
- sizeof(a[0])给出数组的单个元素的大小,于是相除就得到了数组的单元个数
- 这样的代码,一旦修改数组中初始的数据,不需要修改遍历的代码
3)数组的赋值
- 数组变量本身不能被赋值
-
要把一个数组的所有元素交给另一个数组,必须采用遍历for(i=0;i<length;i++){b[i]=a[i];}
(5)利用数组判断是否为素数
1) 没利用数组的代码
int isprime(int x)
{
int ret=1;
int i;
if(x==1)
ret=0;
for(i=2;i<x;i++){
if(x%i==0){
ret=0;
break;}
}
return ret;}
此循环走n-1遍
2 利用数组的代码
去掉偶数后,从3到x-1,每次加2
int isprime(int x)
{
int ret=1;
int i;
if (x==1||(x%2==0&&x!=2))
ret=0;
for(i=3;i<x;i+=2){
if(x%i==0){
ret=0;
break;}
}
return ret;}
循环(n-3)/2+1遍
对比可得数组的运用使得循环次数减少,提高了代码的质量和效率
3)利用数组打印素数表
#include<stdio.h>
#define number 10
int isprime(int x,int knownprimes[],int numberofknownprimes);
int main(void)
{
int prime[number]={2};
int count=1;
int i=3;
while(count<number){
if(isprime(i,prime,count)){
prime[count++]=i;
}
i++;
}
for(i=0;i<number;i++){
printf("%d",prime[i]);
if((i+1)%5)printf("\t");
else printf("\n");
}
return 0;
}
int isprime(int x,int knownprimes[],int numberofknownprimes){
int ret=1;
int i;
for(i=0;i<numberofknownprimes;i++){
if(x%knownprimes[i]==0){
ret=0;
break;}
}
return ret;
}
4)反向思维构造素数表
欲构造n以内的素数表
1 令x为2
2 将2x、3x、4x、直至ax<n的数标记为非素数
3 令x为下一个没有标记为非素数的数,重复2;直到所有的数都已尝试完毕
代码思路
1 开辟prime[n],初始化其所有的元素为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()
{
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;i*x<maxnumber;i++){
isprime[i*x]=0;
}
}
}
for(i=2;i<maxnumber;i++){
if(isprime[i]){
printf("%d\t",i);
}
}
printf("\n");
return 0;
}