嵌入式学习(c)

函数的概念

#include <stdio.h>
/*
c语言的基本组成单位:函数
函数:将一堆可能被反复使用的代码封装在一个函数内
根据传参的不同,从而计算出特定的结果。

函数封装的原则:
1.保持功能的单一性:一个函数内尽量只完成一个功能
2.可复用性:函数支持多场景下重复使用。(前提就是保证功能的
单一性)
3.健壮性强:函数外部无论如何传参,代码都可以正常运行(不发生崩溃或者影响后续代码)
*/
/*
函数的基本概念:
    1.函数的定义:有具体的实现,函数实现的过程的编写
        特点:全局唯一,函数名在同一个作用域内不能冲突    
    2.函数的声明:只有函数名,形参,返回值,没有具体的实现
        特点:声明可以声明多次,没有定义也可以声明
              声明的形参可以只有类型,没有变量名
        用途:主要对外展示,告诉用户函数的使用说明
    3.函数的调用:使用这个函数
        特点:传参的个数不能多也不能少,可以进行默认类型转换
*/

/*
函数的基本组成:
函数名:遵从标识符的命名规范:
形参:形式参数,主要用于外部传参
返回值:主要用于调用处获取函数执行的结果
函数体:{}中的内容,函数具体的实现
*/

int func(int,int);  //函数的声明
int func(int a, int b);  //函数的声明
int func(int a, int b);  //函数的声明
int main(void)
{
    //函数的调用
    //函数形参的传参可以传具体的值也可以传变量
    //传参:100,200:实参
    //传参的实质:int a = 100.99,int b = 200;
    func(100, 200); 
    return 0;
}

//函数的定义
int func(int a, int b)  //int a,int b:形参(形式参数) 
{
    printf("hello world!\n");
    int sum = a + b;
    printf("sum = %d\n", sum);
    return sum;
}

 

#include <stdio.h>
#define ERRORYEAR  500
#define ERRORMONTH 501
#define ERRORDAY   502

#define LEAPYEAR   1000
#define COMMONYEAR 1001
/*
函数的封装方法:
1.先写函数名,返回值和参数先不管(都写成void)
2.实现函数的功能
3.实现功能的途中,某些参数必须从外部获取,
  将其定义为形参。
4.根据调用出的需求,决定返回值的类型
5.对所有设计的形参进行入参判断
*/

/*
函数的传参方式:
1.值传递:传递变量的值(一般用于不需要改变
                      变量的值)
2.地址传递:传递变量的地址(一般用于需要修改变量的值)
*/
void InputParm(int* year, int* month, int* day);
void Swap(int* x, int* y);
void CountDays(int year, int month, int day, int* count);
void CountDiffValue(int count1, int count2, int year1, int year2, int* DiffValue);
int JudgeLegalYear(int year);
int JudgeLeapOrCom(int year);
int JudgeLegalDay(int year, int month, int day);
int JudgeLegalMonth(int month);
int main(void)
{
    int year1 = 0, month1 = 0, day1 =0;
    int year2 =0, month2 =0, day2 =0;
    int count1 = 0, count2 = 0;
    int DiffValue = 0;
    //输入参数
    InputParm(&year1,&month1,&day1);
    InputParm(&year2, &month2, &day2);
    //将较小值赋值给year1,保证year1 < year2
    //JudgeLegalYear(int year);
    //JudgeLegalDay(int year, int month, int day);
    //JudgeLegalMonth(int month);
    if (year1 > year2)
    {
        Swap(&year1,&year2);
        Swap(&month1, &month2);
        Swap(&day1, &day2);
    }  // year1 <= year2

    //计算这一年的第多少天
    CountDays(year1, month1, day1,&count1);
    CountDays(year2, month2, day2, &count2);

    //计算差值
    CountDiffValue(count1,count2,year1,year2,&DiffValue);
    printf("差值为:%d\n", DiffValue);
    return 0;
}

void InputParm(int* year, int* month, int* day)
{
    printf("请输入第一个日期:(以空格隔开):\n");
    scanf_s("%d %d %d", year, month, day);
}
void Swap(int* x, int* y)
{
    *x = *x + *y;
    *y = *x - *y;
    *x = *x - *y;
}
void CountDays(int year, int month, int day, int* count)
{
    int ret = JudgeLegalYear(year);
    if (ret == ERRORYEAR)
    {
        printf("[CountDays]年份输入错误!\n");
        return;
    }
    ret = JudgeLegalMonth(month);
    if (ret == ERRORMONTH)
    {
        printf("[CountDays]月份输入错误!\n");
        return;
    }
    ret = JudgeLegalDay(year,month,day);
    if (ret == ERRORDAY)
    {
        printf("[CountDays]日期输入错误!\n");
        return;
    }
    switch (month)
    {
    case 12:
        *count += 30;
    case 11:
        *count += 31;
    case 10:
        *count += 30;
    case 9:
        *count += 31;
    case 8:
        *count += 31;
    case 7:
        *count += 30;
    case 6:
        *count += 31;
    case 5:
        *count += 30;
    case 4:
        *count += 31;
    case 3:
        *count += 28;
    case 2:
        *count += 31;
        break;
    default:
        break;
    }
    *count += day;
    if (month > 2)
    {
        if (LEAPYEAR == JudgeLeapOrCom(year))
        {
            (*count)++;
        }
    }
}
void CountDiffValue(int count1, int count2, int year1, int year2, int* DiffValue)
{
    int ret = 0;
    for (int i = year1; i < year2; i++) //2000 12 31 2001 1 1
    {
        ret = JudgeLeapOrCom(year1);
        if (ret == LEAPYEAR)
        {
            *DiffValue += 366;
        }
        else if(ret == COMMONYEAR)
        {
            *DiffValue += 365;
        }
    }
    *DiffValue += count2 - count1;
    if (DiffValue < 0)
    {
        *DiffValue = -*DiffValue;
    }
}
int JudgeLeapOrCom(int year)
{
    if (year < 0)
    {
        return ERRORYEAR;
    }
    if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
    {
        return LEAPYEAR;
    }
    else
    {
        return COMMONYEAR;
    }
}
int JudgeLegalDay(int year,int month,int day)
{
    if (day < 0 || day > 31)
    {
        return ERRORDAY;
    }
    int ret;
    switch (month)
    {
    case 4:
    case 6:
    case 9:
    case 11:
        if (day > 30)
        {
            return ERRORDAY;
        }
        break;
    case 2:
        ret = JudgeLeapOrCom(year);
        if (ret == COMMONYEAR && day > 28)
        {
            return ERRORDAY;
        }
        else if (day > 29)
        {
            return ERRORDAY;
        }
    default:
        if (day > 31)
        {
            return ERRORDAY;
        }
    }
}
int JudgeLegalMonth(int month)
{
    if (month < 0 || month > 12)
    {
        return ERRORMONTH;
    }
}
int JudgeLegalYear(int year)
{
    if (year < 0)
    {
        return ERRORYEAR;
    }
}

#include <stdio.h>
/*
函数的调用过程:
1.根据函数名找到函数的入口地址
2.根据函数的形参和函数体分配相应的空间
3.将实参传递给形参
4.执行函数体
5.返回调用处,将return后面的值带回(返回值为void忽略)
6.释放函数调用时申请的局部变量的空间
*/

/*
函数的返回值说明
    语法层面:(编译是否能通过)
        1.函数的返回值(return后面的值)和返回值类型要保持一致
    用法层面:
        2.根据实际需要确定返回值的类型
        3.调用处可以接受这个返回值,也可以不接收这个返回值
          如果返回值类型为void,则不能接收返回值
        4.接收返回值时,也要遵从等号左右等价一致原则。
*/
/*
示例1-1:设计一个函数,判断指定数据是否为质数?
设计流程:
    函数名、形参列表、返回值类型、函数体。
    函数名:IsPrimeNum
        形参列表:int  n
        返回值类型:int
*/
/*
函数形参的说明:
输入参数:input 通常认为是只用不改的参数  
输出参数: ouput 通常认为需要通过函数修改实参的值

*/
/*
日期:
作者:
功能:判断一个数是否为质数
参数:
    输入参数 :
              x:需要判断的数 
    输出参数:无
    
返回值:
    0:表示该数为非质数
    1:表示该数为质数
*/
int IsPrimeNum(int);
int main(void)
{
    int ret = IsPrimeNum(19);
    if (ret == 1)
    {
        printf("该数为非质数!\n");
    }
    else if (ret == 0)
    {
        printf("该数为质数!\n");
    }
    return 0;
}
int IsPrimeNum(int x)
{
    if (x < 2)
    {
        return 1; //非质数
    }
    for (int i = 2; i <= x / 2; i++)
    {
        if (x % i == 0)
        {
            return 1; //非质数
        }
    }
    return 0;  //质数
}

-------------------------------------------------------------------------------------------------------

2

#include <stdio.h>
/*
示例1-2:设计一个函数,计算出从1到n之间共有多少个质数。
*/
int CountPrimeNum(int n)
{
    if (n < 2)
    {
        return 0; 
    }
    int flag = 0;
    int count = 0;
    for (int i = 2; i <= n; i++)
    {
        flag = 0;
        for (int j = 2; j <= i / 2; j++)
        {
            if (i % j == 0)
            {
                flag = 1;
                break;
            }
        }
        if (flag == 0)
        {
            count++;
        }
    }
    return count;
}
int main(void)
{
    printf("请输入一个数:\n");
    int n;
    scanf_s("%d",&n);
    int ret = CountPrimeNum(n);
    printf("1 ~ %d 之间有 %d个质数!\n",n,ret);
    return 0;
}

------------------------------------------------------------------------------------------------------------------------

3

#include <stdio.h>
/*
示例2:设计一个函数,忽略正负号,计算出指定数据的位数。(比如:数据若为1234,返回4)
思路:n位数数值范围是在10的n-1次方到10的n次方之间。
在原数值的绝对值的基础上,连续进行除10运算,恰好在第n次除10后,结果为0。
*/
int CountBitNum(int num)
{
    int count = 0;
    while (num)
    {
        num /= 10;
        count++;
    }
    return count;
}
int main(void)
{


    printf("请输入一个数:\n");
    int n;
    scanf_s("%d", &n);
    int ret = CountBitNum(n);
    printf("%d 的位数为 %d\n",n,ret);
    return 0;
}

-------------------------------------------------------------------------------------------------



4#include <stdio.h>
/*
示例3:设计一个函数,输出1~n之间一共出现过多少个1。
比如:n = 1时,返回1;n = 10时,返回2;n=11时,返回4;n=20时,返回12。
思路:先分解出另一个函数,通过多次调用该函数,完成最终的函数。
*/
int CountOneNum(int n)
{
    if (n < 1)
    {
        return 0;
    }
    int count = 0;
    int temp = 0;
    //用于依次判断每个数中有几个1
    for (int i = 1; i <= n; i++)
    {
        temp = i;
        while (temp)
        {
            if (temp % 10 == 1)
            {
                count++;
            }
            temp /= 10;
        }
    }
    return count;
}
int main(void)
{
    printf("请输入一个数:\n");
    int n;
    scanf_s("%d", &n);
    int ret = CountOneNum(n);
    printf("1 ~ %d 之间有 %d 个1\n",n,ret);
    return 0;
}

------------------------------------------------------------------------------------------------------------------

#include <stdio.h>
/*
示例4:现有5分、2分和1分硬币若干,每种至少一枚,总价值为1元。
设计一个函数,指定硬币总个数为n枚,列出所有满足条件的组合。若无解,则输出无解。
*/
void CoinPlan(int n)
{
    int flag = 1;
    for (int i = 1; i < 20; i++)
    {
        for (int j = 1; j < 50; j++)
        {
            int k = n - i - j;
            if ((k >= 1) && (i * 5 + j * 2 + k) == 100)
            {
                flag = 0;
                printf("5分:%d个 2分:%d个 1分:%d个\n",i,j,k);
            }
        }
    }
    if (flag == 1)
    {
        printf("无解!\n");
    }
}
int main(void)
{
    printf("请输入一个数:\n");
    int n;
    scanf_s("%d", &n);
    CoinPlan(n);
    return 0;
}

----------------------------------------------------------------------------------------------#include <stdio.h>

/*
示例5:设计一个函数,计算出指定整数的二进制形式中有多少个1。
*/
int CountOneNum(int num)
{
    int count = 0;
    while (num)
    {
        printf("num = %d\n",num);
        printf("ret = %d\n", num & 1);
        if ((num & 1) == 1)
        {
            count++;
        }
        num >>= 1;  //num = num >>1;
    }
    return count;
}
int main(void)
{
    printf("请输入一个数:\n");
    int n;
    scanf_s("%d", &n);
    int ret = CountOneNum(n);
    printf("%d 的二进制数有 %d 个1\n",n,ret);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值