函数and数组

前言:星期五的C语言实验课写6道题,有关分支结构程序设计的题。真的是所有低级的错误都出现了。比如“=”(赋值运算符)与“==”(比较运算符)即使老师经常强调,但有时真的会弄混,然后发现Dev-C++的调试我也不怎么熟练。因为这周写的题出了很多bug所以真的是去百度搜调试怎么弄,现在应该熟练了。调试真的是抵bug的重要的途径之一。

学习内容:

1.函数(函数是一块,接收零个或多个参数,做一件事情,并返回零个或一个值。

1.1函数的定义

例:

返回类型  函数名(参数)

void sum(int begin, int end)    //该行叫函数头,void表示没有,不返回任何东西

{

                                             //{}内为函数体

}

1.2调用函数

函数名(参数值)      //()起到了表示函数调用的重要作用

参数值是表达式的结果,包括:

字面量  变量    函数的返回值   计算的结果

  10         a           sum(1,10)          23+45    

类型不匹配

调用函数时给的值与参数的类型不匹配是C语言传统上最大的漏洞

编译器总是悄悄替你把类型转换好,但是这很可能不是你所期望的,所以要注意调用函数时给的值与参数的类型要匹配

C++/Java在这方面很严格

1.3从函数中返回值

return停止函数的执行,并送回一个值

一个函数里可以出现多个return语句,但不符合单一出口,修改代码时要修改多处

1.4函数原型

函数头以分号;结尾就构成了函数的原型

为了在前面进行函数的声明,这样函数的定义可放在后面

1.5本地变量

定义在函数内部的变量就是本地变量,参数也是

可定义在块内,函数的块内,语句的块内,随便拉一对大括号来定义也行

1.5.1变量的生存期和作用域

生存期:什么时候这个变量开始出现了,到什么时候它消亡了

作用域:再次(代码的)什么范围内可以访问这个变量(这个变量可以起作用)

对于本地变量,这两个问题的答案是统一的:大括号内(块内)

tips:

程序运行进入这个块之前,其中的变量不存在,离开这个块,其中的变量就消失了

块外面定义的变量在里面仍然有效

块里面定义了和外面同名的变量则掩盖外面的

不能在一个块内定义同名的变量

本地变量不会被默认初始化

参数在进入函数的时候被初始化

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

2.数组

是一种容器(放东西的东西),特点是:其中所有的元素具有相同的数据类型,一旦创建,不能改变大小。数组的元素在内存中是连续依次排列的。

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

double weight[20];         //元素数量必须是整数

2.1数组单元

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

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

2.2数组的集成初始化

int a[ ] ={    }

直接用大括号给出数组的所有元素的初始值

不需要给出数组的大小,编译器替我们数

2.3集成初始化的定位

int a[10] = {[0]=2, [2]=3,6}

得到: a[10]={2, 0, 3, 6, 0, 0, 0, 0, 0, 0}

用[n]在初始化数据中给出定位

没有定位的数据接在前面的位置后面

其他位置的值补零

特别适合初始数据稀疏的数组

2.4数组的大小

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

求数组的元素数量:

sizeof(a) / sizeof(a[0])      //总字节数除以单个元素所占的字节数等于元素数量

2.5数组的赋值(数组变量本身不能被赋值)

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

遍历数组

for(i=0; i<length; i++)

{

        b[i] = a[i];

}

常见错误:

循环结束条件是<=数组长度

离开循环后继续用i的值来做数组元素的下标  离开遍历 i=length(无效)

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

数组作为函数的参数时:

不能在[ ]中给出数组的大小。就算给出也无意义

不能在利用sizeof来计算数组元素个数

3.二维数组

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

a[0][0]  a[0][1]  a[0][2]  a[0][3]  a[0][4]

a[1][0]  a[1][1]  a[1][2]  a[1][3]  a[1][4]

a[2][0]  a[2][1]  a[2][2]  a[2][3]  a[2][4]

a[i,j]表示a[j]

3.1二维数组的初始化

int a[ ][5]={

        {0, 1, 2, 3, 4},

        {2, 3, 4, 5, 6},

}

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

每行一个{ },逗号分隔

如果省略,表示补零

也可以定位

代码展示:

1.箱子匹配(实验课的最后一题

#include <stdio.h>
int main() {
    int T, i;
    scanf("%d",&T);

    for(i=0; i<T; i++) 
    {
        int a1, b1, c1;
        int a2, b2, c2; 
        int min1, med1, max1;
        int min2, med2, max2;
        scanf("%d %d %d", &a1, &b1, &c1);
        scanf("%d %d %d", &a2, &b2, &c2);
        if(a1>=b1) 
        {
            if(a1>=c1) 
            {
                if(b1>=c1)
                {
                    max1=a1, med1=b1, min1=c1;
                }
                 else 
                {
                    max1=a1, med1=c1, min1=b1;
                }
            }
             else 
            {
                max1=c1, med1=a1, min1=b1;
            }
        }
        else 
        {
            if(b1>=c1)
            {
                if(a1>=c1)
                {
                    max1=b1, med1=a1, min1=c1;
                }
                else
                {
                    max1=b1, med1=c1, min1=a1;
                }
            }
            else
            {
                max1=c1, med1=b1, min1=a1;
            }
        }

        if(a2>=b2) 
        {
            if(a2>=c2) 
            {
                if(b2>=c2)
                {
                    max2=a2, med2=b2, min2=c2;
                }
                 else 
                {
                    max2=a2, med2=c2, min2=b2;
                }
            }
             else 
            {
                max2=c2, med2=a2, min2=b2;
            }
        }
        else 
        {
            if(b2>=c2)
            {
                if(a2>=c2)
                {
                    max2=b2, med2=a2, min2=c2;
                }
                else
                {
                    max2=b2, med2=c2, min2=a2;
                }
            }
            else
            {
                max2=c2, med2=b2, min2=a2;
            }
        }
        if(max1>=max2&&med1>=med2&&min1>=min2||max1<=max2&&med1<=med2&&min1<=min2)
        {
               printf("yes\n");
        }
        else
        {
            printf("no\n");
        } 
    }    

    return 0;
}

这道题找bug找了我很久,主要是调试不熟练

常见错误:

scanf输入在%d后加了换行符,导致在操作台那里回车之后没反应

==和=搞混,前是比较大小是否相等,后是赋值

2.定义一个函数来判断输入的数是否为素数

第一种(之前学的):循环的次数表达程序的效率怎么样,循环的次数越多,效率越差

第二种:

 第三种:sqrt(x)表示x的平方根注意:for循环的执行条件应该是i<=sqrt(x)。

否则如果当x=9,25,等等一些数会进不去for循环,致使返回值为1,被认为是素数

代码展示:

#include <stdio.h>
#include <math.h>
int isPrime(int  x)
{
    int ret = 1;
    int i;
    if(x == 1||(x%2==0 && x!=2))
    {
        ret = 0;
    }
    for(i=3; i<=sqrt(x); i+=2)
    {
        if(x%i==0)
        {
            ret = 0;
            break;
        }
    }
    return ret;
}
int main()

{
    int cnt=50, i=0, x=2;

    for(x; ;x++)
    {
        if(isPrime(x)==1)
        {
            printf("%d\t", x);
            i++;
        }
        if(i>=cnt)
        {
            break;
        }
    }
        
    return 0;
}

第四种:

 第五种的算法:

伪代码:

代码:(计算25以内的素数)

 3.二分法求多项式单根(用到了自定义函数)

#include <stdio.h>
double a3=0, a2=0, a1=0, a0=0;
double f(double x)
{
    double sum;
    sum = a3*x*x*x+a2*x*x+a1*x+a0;
    return sum;
}

int main()
{
    double a, b, mid;
    scanf("%lf %lf %lf %lf", &a3, &a2, &a1, &a0);
    scanf("%lf %lf", &a, &b);
    while(b-a>1e-3&&f(a)*f(b)<=0)
    {
        if(f(a)==0)
        {
            mid=a;
            break;    
        }
        else if(f(b)==0)
        {
            mid=b;
            break;
        }
        mid=(a+b)/2;
        if(f(mid)==0)
        {
            break;
        }
        else
        {
            if(f(a)*f(mid)>0)
            {
                a=mid;
            }
            else 
            {
                b=mid;
            }
        }
    } 
    printf("%.2lf", mid);
    
    return 0;
}

4.支票面额

#include <stdio.h>
int main()
//理解一下题意后会得到一个函数表达式
//2*y*100+2*f== f*100+y-n
//数学公式就是200y+2f=100f-n
//化简得:n=98f-199y
//由题意可知:0<n(正整数)<100,0<=f(整数)<100
//由化简的公式可得:y=(98f-n)/199
//而98f-n<=9701
//即y<49
{
    int n;
    scanf("%d", &n);
    int f, y, flag=0;
    for(y=0; y<49; y++)
    {
        for(f=0; f<100; f++)
        {
            if(98*f-199*y==n)
            {
                printf("%d.%d", y, f);
                flag=1;
                break;
            }
        }    
    }
    if(flag!=1)
    {
        printf("No Solution");
    }
    return 0;
}

5.龟兔赛跑

#include <stdio.h>
int main()

{
    int rabbit=0, tortoise=0, t, i, rest_t=0, s; 
    scanf("%d", &t);
    for(i=1; i<=t; i++)
    {
        tortoise += 3;
        if(rest_t==0)
        {
            rabbit += 9;
        }
        else
        {
            rest_t--;
        }
        if(i%10==0&&rest_t==0&&rabbit>tortoise)
        {
            rest_t += 30;
        }
    }
    if(rabbit>=tortoise)
    {
        s=rabbit;
        if(rabbit>tortoise)
        {
            printf("^_^");
        }
        else
        {
            printf("-_-");
        }
    }
    else
    {
        s=tortoise;
        printf("@_@");
    }
    printf(" %d\n", s);
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值