小学生都看得懂的C语言入门(3): 数组与函数
- #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 ;
- }
这是每次的number 数组的存储情况,再输入-1终止计算,得到
但是上述存在很明显的问题: 定义了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 ;
- }
结果
(二) 定义函数
实例: 求从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
由此若要初始化一个长度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): 数组与函数的更多相关文章
- 小学生都看得懂的C语言入门(4): 数组与函数
// 之前判断素数, 只需要到sqrt(x)即可,//更加简单的, 判断能够比已知的小于x的素数整除, 运行更快 #include <stdio.h> // 之前判断素数, 只需要到sqr ...
- 小学生都看得懂的C语言入门(1): 基础/判别/循环
c基础入门, 小学生也可以都看得懂!!!! 安装一个编译器, 这方面我不太懂, 安装了DEV-C++ ,体积不大,30M左右吧, 感觉挺好用,初学者够了. 介绍下DEV 的快键键: 恢复 Ctrl+ ...
- 小学生都看得懂的C语言入门(5): 指针
现在已经学到C语言的后面了, 快学完咯.... (一)取地址运算 先来看一下sizeof 计算所占字节 #include<stdio.h> int main() { int a; a=; ...
- 小学生都看得懂的C语言入门(6): 字符串
1.字符用 char 表示 #include<stdio.h> int main() { char c; char d; c=; d='; if (c==d){ printf(" ...
- 小学生都看得懂的C语言入门(2): 判别 循环的一些应用实例
1.bool 类型 定义bool类型之前需要导入#include <stdbool.h> #include <stdio.h> #include <stdbool.h&g ...
- JS对象 JavaScript 中的所有事物都是对象,如:字符串、数值、数组、函数等,每个对象带有属性和方法。
什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方法: ...
- Go语言入门教程(十)之函数
Hello 各位小伙伴大家好,我是小栈君,假期一眨眼就过去了.不知道大家玩的是否开心呢? 上次我们讲到了关于Go语言的流程控制,小栈君也希望小伙伴跟着小栈君一步一个脚印的敲一下代码,相互进步.本期我们 ...
- C语言二维数组作为函数的参数
前言:今天在实现装配线调度程序时候,用到了二维数组,并将其作为函数的参数.在写程序的时候,遇到一些问题,即二维数组做函数的参数应该如何正确表示.我写程序的错误如下程序所示: #include < ...
- 小学生都能读懂的网络协议之:WebSocket
目录 简介 webSocket vs HTTP HTTP upgrade header websocket的优点 webScoket的应用 websocket的握手流程 WebSocket API 总 ...
随机推荐
- tcp黏包
转载https://www.cnblogs.com/wade-luffy/p/6165671.html 无论是服务端还是客户端,当我们读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制. 回 ...
- PTA 逆散列问题 (30 分)(贪心)
题目链接:https://pintia.cn/problem-sets/1107178288721649664/problems/1107178432099737614 题目大意: 给定长度为 N 的 ...
- python - 爬虫入门练习 爬取链家网二手房信息
import requests from bs4 import BeautifulSoup import sqlite3 conn = sqlite3.connect("test.db&qu ...
- python读取两个文件并且判断是否一致
''' 判断两个文件是否相同,如果不同请指出第几行不相同 ''' def f1vsf2(name1,name2): f1 = open(name1) f2 = open(name2) count = ...
- android studio设置窗口颜色和字体
1.设置左边窗口颜色和字体: 设置中间代码编辑窗口:
- auto 和 decltype
一, auto 1, auto的作用 一般来说, 在把一个表达式或者函数的返回值赋给一个对象的时候, 我们必须要知道这个表达式的返回类型, 但是有的时候我们很难或者无法知道这个表达式或者函数的 ...
- SpringCloud Hystrix
⒈Hystrix是什么? Hystrix使一个用于处理分布式系统的延迟和容错的开源库.在分布式系统里,许多依赖不可避免的因服务超时.服务异常等导致调用失败,Hystrix能够保证在一个依赖出现问题的情 ...
- 20165231 2017-2018-2 《Java程序设计》第7周学习总结
教材学习内容总结 第十一章 MySQL数据库管理系统,简称MySQL,是世界上最流行的开源数据库管理系统,其社区版(MySQL Community Edition)是最流行的免费下载的开源数据库管理系 ...
- 其他-n个互相独立的连续随机变量中第i小的数值期望
提出问题 有\(n\)个互相独立的\(0\)至\(1\)之间等概率生成的随机变量,求从小到大排序后第\(i\)个数的数值期望 一个简化的问题 我们先来求解一个简化的问题:最大值的数值期望是多少? 我们 ...
- codeforces 161D Distance in Tree 树上点分治
链接:https://codeforces.com/contest/161/problem/D 题意:给一个树,求距离恰好为$k$的点对是多少 题解:对于一个树,距离为$k$的点对要么经过根节点,要么 ...