小学生都看得懂的C语言入门(3): 数组与函数

时间:2023-01-31 23:40:25
#include <stdio.h>
int main()
{
int x;
double sum=;
int cnt=;
scanf("%d",&x){
sum+=x;
cnt++;
scanf("%d",&x);
}
printf("the mean is %d",sum/cnt);

这是之前求平均数的代码,

上述没有记录每一个输入的数, 一旦输入就加上去, 没有记录
//现在问题变了, 需要你求平均数 并且输出大于平均数的值 , 那么有必要记录每一个
输入的数字, 如何实现?

现在需要用到数组进行记录. 在上述代码基础上增加 number[10] 定义,在while 循环中增加number[cnt]=x记录输入的值

#include <stdio.h>
int main()
{
int x;
double sum=;
int number[]; //长度是10的数组, 可以放10个int
int cnt=;
scanf("%d",&x);
while(x!=-){
number[cnt]=x; //记录 赋值
sum+=x;
cnt++;
scanf("%d",&x);
}
if (cnt>){
printf("the mean is %f\n",sum/cnt); int i; //遍历每一个数 找到大于平均数的值
for(i=;i<cnt;i++){
if(number[i]>sum/cnt){
printf("%d\n",number[i]);
}
}
}
return ;
}

为了清楚的知道number[cnt]=x 的存储机制,增加一段调试代码

#include <stdio.h>
int main()
{
int x;
double sum=;
int number[]; //长度是10的数组, 可以放10个int
int cnt=;
scanf("%d",&x);
while(x!=-){
number[cnt]=x; //记录 赋值
// --用于调试
{
int i;
printf("%d\t",cnt);
for(i=;i<=cnt;i++){
printf("%d\t",number[i]);
}
}printf("\n");
//--用于调试
sum+=x;
cnt++;
scanf("%d",&x);
}
if (cnt>){
printf("the mean is %f\n",sum/cnt); int i; //遍历每一个数 找到大于平均数的值
for(i=;i<cnt;i++){
if(number[i]>sum/cnt){
printf("%d\n",number[i]);
} }
}return ;
}

小学生都看得懂的C语言入门(3): 数组与函数

这是每次的number 数组的存储情况,再输入-1终止计算,得到

小学生都看得懂的C语言入门(3): 数组与函数

但是上述存在很明显的问题: 定义了number [10] ,如果实际输入了超过10 怎么办?

别急啊, 首先掌握下数组的定义

int grades[100];

double weight[20];

数组的特点: 1.数组中的每个元素具有相同的数据类型, 2. 一旦创建数组, 之后不能改变大小,

int a[10] 的顺序是 a[0], a[1],... a[9] ,[] 中的数字是索引, 索引从0开始计数!!

编译器不会检查数组下标是否越界, 越界就出现segmentation fault ,

int a[0] 可以存在, 但是没有任何用处..

实例: 输入数量不定的在[0,9]之间的整数, 统计每一种数字出现的次数, 输入-1表示结束

程序如下, 用一个10元数组来作为计数器,

#include <stdio.h>
int main(void)
{
const int num=; //num决定数组大小
int x;
int i;
int cnt[num];
for (i=;i<num;i++){
cnt[i]=;
} //初始化数组的每一个元素, scanf("%d",&x);
while(x!=-){
if (x>= && x<=){
cnt[x] ++;
}
scanf("%d",&x);
}
for (i=;i<num;i++){
printf("%d出现了%d次\n",i,cnt[i]);
}
return ;
}

结果

小学生都看得懂的C语言入门(3): 数组与函数

(二) 定义函数

实例: 求从m -n 之间所有素数的和sum

#include <stdio.h>
int main()
{
int m,n;
int sum=;
int cnt=;
int i;
// 求素数的和
scanf("%d %d",&m,&n); //m=10 n=31
if (m==)m=;
for (i=m;i<=n;i++){
int isprime=;
int k;
for (k=;k<i-;k++){
if (i%k==){
isprime=;
break;
}
}
if(isprime){
sum+=i;
cnt++;
}
}
printf("有%d个素数, 和为%d\n",cnt,sum);
return ;
}

我们可以将上述素数判别的单独拿出来 形成一个函数.

#include <stdio.h>
// 定义一个函数 isprime
int isprime(int i)
{
int ret=;
int k;
for (k=;k<i-;k++){
if (i%k==){
ret=;
break;
}
}
return ret;
}
//
int main()
{
int m,n;
int sum=;
int cnt=;
int i;
// 求素数的和
scanf("%d %d",&m,&n); //m=10 n=31
if (m==)m=;
for (i=m;i<=n;i++){
if(isprime(i)){
sum+=i;
cnt++;
}
}
printf("有%d个素数, 和为%d\n",cnt,sum);
return ;
}

实例 : 求 1-10 , 20-30  35-45 三者的和

'代码复制是程序不良的表现'!!!! keep it  in mind~~, 不利用与将来程序的维护.

#include <stdio.h>

void sum(int begin ,int end)
{
int i;
int sum=;
for (i=begin;i<=end;i++){
sum+=i;
}
printf("%d到%d 的和是%d \n",begin,end,sum);
} int main()
{
sum(,);
sum(,);
sum(,);
return ;
}

综合上述两个例子, 我们来看什么是函数, 如何定义?

void sum(int begin ,int end) 称为函数头, sum是函数名, void 表示函数没有返回的东西, ()内是参数, 参数用逗号, 分开

以下部分称为函数体

{
 int i;
 int sum=0;
 for (i=begin;i<=end;i++){
  sum+=i;
 }
 printf("%d到%d 的和是%d \n",begin,end,sum);
 }

函数头中的圆括号很重要, 调用函数也要加(), 否则出错

#include <stdio.h>
void fun()
{
printf("nihao");
}
int main()
{
fun(); // 要加() !!!
return ;
}

而判断别素数的函数 是有返回值的

int isprime(int i)

函数体中有return ret

定义一个最大值函数

int max(int a, int b)
{
int ret ;
if(a>b){
ret=a;
}
else{
ret=b;
}
return ret;
}
#include <stdio.h>
int max(int a, int b)
{
int ret ;
if(a>b){
ret=a;
}
else{
ret=b;
}
return ret;
} int main()
{
int x;
x=max(,);// 将函数值赋给x
printf("%d\n",x);
}

上述函数头也可以写成

#include <stdio.h>
int max(int a, int b)
{
int ret ; if(a>b){
return a;
}
else{
return b;
}
//return ret;

但是这样不好, 使得函数有多个出口(多个return), 可行但是不建议用这种!!

函数可以嵌套用 比如max(10, max(100,11));

没有返回值的函数 则定义为

void 函数名(参数表)

那么之后不能用 return 某个值;

如果函数有返回值, 则必须使用带值的return.

注意: 在书写时, 先定义函数再之后进行调用, 不要把函数的定义放在main  后面, 但是也可以通过函数声明实现

#include <stdio.h>

int max(int a, int b); // 函数声明!! , 加分号!! 也可以不加 参数, int max(int , int )
int main()
{
int x;
x=max(,);// 将函数值赋给x
printf("%d\n",x);
} int max(int a, int b)
{
int ret ;
if(a>b){
ret=a;
}
else{
ret=b;
}
return ret;
}

其他问题:

C语言不允许函数的嵌套定义

int main () 实际上也是一个函数,

---- 二维数组

int a[3][5]  表示3*5矩阵

a[0][0], a[0][1],... a[0][4]

..

a[2][0], a[2][1], ...a[2][4]

int a[][]={
{,,},{,,},
}; // 定义数组列数一定要给出, 行数可以不给, 计算机会自己数

实例:   // tic-tac -toe game, 3*3 矩阵中,写1 或者0 ,当有一行 一列或者对角线

可以连成线, 则一方胜出, 游戏结束, 如何判别游戏结束?
 遍历每行 每列, 每个对角线 进行判别

#include <stdio.h>
int main()
{
const int size=;
int board[size][size];
int i,j;
int n1;
int n0;
int result=-; // -1没有人胜出,1 表示写1方胜出, 0表写0方胜出
//下面读入矩阵
for (i=;i<size;i++){
for(j=;j<size;j++){
scanf("%d",&board[i][j]);
}
} // 检查行
for (i=;i<size&&result==-;i++){
n0=n1=;
for(j=;j<size;j++){
if(board[i][j]==){
n1++;
}else{
n0++;
}
}
if (n0==size){
result=;
}else if(n1==size){
result=;
}
} //再检查列
if (result==-){
for (j=;j<size&&result==-;j++){
n0=n1=;
for(i=;i<size;i++){
if(board[i][j]==){
n1++;
}else{
n0++;
}
}
if (n0==size){
result=;
}else if(n1==size){
result=;
}
}
} // 再检查正对角线
if (result==-){
n0=n1=;
for(i=;i<size;i++){
if(board[i][i]==){
n1++;
}else{
n0++;
}
}
if (n0==size){
result=;
}else if(n1==size){
result=;
}
} // 最后检查次对角线
if (result==-){
n0=n1=;
for(i=;i<size;i++){
if(board[i][size--i]==){
n1++;
}else{
n0++;
}
}
if (n0==size){
result=;
}else if(n1==size){
result=;
}
} // 下结论
if (result==){
printf("1 win");
} else if(result==){
printf("0 win");
}else{
printf("nobody win, have an another try");
} return ;
}

接下来, 学习数组的搜索等其他

数据的集成初始化

#include <stdio.h>
int main(void)
{
int a[]={,,,};// 数组的集成初始化
for (int i=;i<;i++){
printf("%d\t",a[i]);
} }

换一种形式

#include <stdio.h>
int main(void)
{
int a[]={};// 数组的集成初始化
for (int i=;i<;i++){
printf("%d\t",a[i]);
}
}

 得到第一个是1 ,后面自动补0

小学生都看得懂的C语言入门(3): 数组与函数

由此若要初始化一个长度n 的数组a 为0, 只需要int a[n]={0};

对于稀疏数组, 大部分是0 ,只有少数几个值非零, 则可以

#include <stdio.h>
int main(void)
{
int a[]={[]=,[]=};// 没给定义的位置自动填充0 ,但是只有C99 才可以这样做
for (int i=;i<;i++){
printf("%d\t",a[i]);
}
}

如何让编译器自动数数组长度?, 用sizeof

#include <stdio.h>
int main(void)
{
 int a[]={1,2,3,4};
  printf("%d\t",sizeof(a)); //16
  printf("%d\t",sizeof(a[0])); //4
  printf("数组长度是%d\t",sizeof(a)/sizeof(a[0])); 
}

得到数组长度是sizeof(a)/sizeof(a[0])

注意数组的赋值

#include <stdio.h>
int main(void)
{
int a[]={,,,};
int b[]=a; // 错误! 不能这么赋值
}

数组赋值必须采用遍历

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

实例:

#include <stdio.h>
//搜索一个数是否在数组中存在
int search(int key, int a[],int length);
int main(void)
{
int a[]={,,,,,,,,};
int x;
int loc;
printf("please input a number\n");
scanf("%d",&x);
int length=sizeof(a)/sizeof(a[]);
loc=search(x,a,length); // 调用search函数
if(loc!=-){
printf("%d在%d位置上\n",x,loc);
}else{
printf("%d doesn't exist\n",x);
}
return ;
} int search(int key, int a[],int length)
{
int ret=-; // 记录key 在数组x 中的位置, 0 表示位置1
int i;
for(i=;i<length;i++){
if (a[i]==key){
ret=i;
break;
}
}
return ret;
} // 注意,数组作为函数参数时, 必须再用另一个参数传入该数组的大小,
//因为不能在[] 中给出数组的大小, 不能再利用sizeof 来计算数组的元素个数

小学生都看得懂的C语言入门(3): 数组与函数的更多相关文章

  1. 小学生都看得懂的C语言入门&lpar;4&rpar;&colon; 数组与函数

    // 之前判断素数, 只需要到sqrt(x)即可,//更加简单的, 判断能够比已知的小于x的素数整除, 运行更快 #include <stdio.h> // 之前判断素数, 只需要到sqr ...

  2. 小学生都看得懂的C语言入门&lpar;1&rpar;&colon; 基础&sol;判别&sol;循环

    c基础入门, 小学生也可以都看得懂!!!! 安装一个编译器, 这方面我不太懂, 安装了DEV-C++  ,体积不大,30M左右吧, 感觉挺好用,初学者够了. 介绍下DEV 的快键键: 恢复 Ctrl+ ...

  3. 小学生都看得懂的C语言入门&lpar;5&rpar;&colon; 指针

    现在已经学到C语言的后面了, 快学完咯.... (一)取地址运算 先来看一下sizeof 计算所占字节 #include<stdio.h> int main() { int a; a=; ...

  4. 小学生都看得懂的C语言入门&lpar;6&rpar;&colon; 字符串

    1.字符用 char 表示 #include<stdio.h> int main() { char c; char d; c=; d='; if (c==d){ printf(" ...

  5. 小学生都看得懂的C语言入门&lpar;2&rpar;&colon; 判别 循环的一些应用实例

    1.bool 类型 定义bool类型之前需要导入#include <stdbool.h> #include <stdio.h> #include <stdbool.h&g ...

  6. JS对象 JavaScript 中的所有事物都是对象,如&colon;字符串、数值、数组、函数等,每个对象带有属性和方法。

    什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方法: ...

  7. Go语言入门教程&lpar;十&rpar;之函数

    Hello 各位小伙伴大家好,我是小栈君,假期一眨眼就过去了.不知道大家玩的是否开心呢? 上次我们讲到了关于Go语言的流程控制,小栈君也希望小伙伴跟着小栈君一步一个脚印的敲一下代码,相互进步.本期我们 ...

  8. C语言二维数组作为函数的参数

    前言:今天在实现装配线调度程序时候,用到了二维数组,并将其作为函数的参数.在写程序的时候,遇到一些问题,即二维数组做函数的参数应该如何正确表示.我写程序的错误如下程序所示: #include < ...

  9. 小学生都能读懂的网络协议之&colon;WebSocket

    目录 简介 webSocket vs HTTP HTTP upgrade header websocket的优点 webScoket的应用 websocket的握手流程 WebSocket API 总 ...

随机推荐

  1. 用JavaScript调用WCF Service

    原创地址:http://www.cnblogs.com/jfzhu/p/4039604.html 转载请注明出处 前面介绍过<Step by Step 创建一个WCF Service>和& ...

  2. 在UltraEdit的查找和替换中使用正则表达式 &lpar;转&rpar;

    很多朋友都用过或者正在用UltraEdit,这个编辑器陪伴我也好几年了,从很多地方影响着我写代码的快捷键习惯,Ultraedit提供了非常丰富的编辑功能,其中非常重要的查找和替换功能一定大家都用过,U ...

  3. CSS line-height 和 vertical-align 精解(下篇)

    申明本文转自:http://hi.baidu.com/wolongxzg/item/2383860ec8ac8b173a53eeb0 vertical-align 7.4.1 语法 vertical- ...

  4. 4柱汉诺塔(zz)

    多柱汉诺塔可以用Frame–Stewart算法来解决. The Frame–Stewart algorithm, giving a presumably optimal solution for fo ...

  5. Java导出Excel和CSV&lpar;简单Demo&rpar;

    Java导出Excel和CSV的简单实现,分别使用POI和JavaCSV. JavaBean public class ReportInfo { int id; String date; int nu ...

  6. hdu4417 Super Mario 树阵离线&sol;划分树

    http://acm.hdu.edu.cn/showproblem.php?pid=4417 Super Mario Time Limit: 2000/1000 MS (Java/Others)    ...

  7. 17&lowbar;8&lowbar;9 Spring 注入

    1 Spring 的 Bean 的属性注入: 构造方法的方式注入属性: <!-- 第一种:构造方法的方式 --> <bean id="car" class=&qu ...

  8. 能在xcode5中开发基于IOS7sdk的应用程序兼容ios4&period;3之后的系统吗?

    能在xcode5中开发基于IOS7sdk的应用程序兼容ios4.3之后的系统吗?

  9. window下redis nosql初试

    1:redis官方下载地址http://redis.io/download   下载下来,有32位的,有64位的,自己选择. 2:将redis文件夹放到D盘:D:\redis watermark/2/ ...

  10. MyBatis配置数据库连接

    <environments default="default"> <environment id="default"> <tran ...