C语言基础(有关三角形面积,阶乘算法,sqrt,pow函数,海伦公式,gets,getchar,scanf的区别,字符转换,增长率计算,的分支和循环的结构程序设计)

简介: C语言基础(有关三角形面积,阶乘算法,sqrt,pow函数,海伦公式,gets,getchar,scanf的区别,字符转换,增长率计算,的分支和循环的结构程序设计)

一、多的不吹少的不唠(开头必须是我的校园生活)

今天我们学校是异常的神奇,6点10就要起床(起床就起床吧,干点跑步之类的有益于身体健康的事情就算了),可惜居然是起床做核酸(想笑),充分打扰我的作息,搞得我核酸回来睡到了10点(要死),上午第一节课是高数,后排就是快乐,剩下的都还正常,我就讲一讲下午的体育课吧,还是挺搞笑的,比如我的神奇舍友做了150个俯卧撑(游戏小天才,没办法),哈哈,不像我,大高手。


二、今天我就把我多天来关于分支和循环的的武功给我自己再讲一讲

(一).首先是分支

1.分支结构的控制语句主要就只有两个:if语句和switch语句

至于如何使用if语句呢?先让下面这个代码告诉你:

#include<math.h>
#include<stdio.h>
int main()
{
  float a, b, c;//定义三边
  float z;     //定义半周长
  float h;     //定义海伦公式的第一小步
  float s;     //定义最后的面积
  printf("请输入三角形的三边:");
  scanf("%f%f%f",&a,&b,&c);//这步就是正常的定义变量,然后使我们可以输入3边
  //根据海伦公式,来求解只知道三边而不知道高时的三角形面积
  //有的博客连海伦公式都不介绍一下(过分),海伦公式:首先知道半周长 z=(a+b+c)/2,(但是要注意算面积是用的都是float(单精度浮点数))
  //所以要用float来定义我的半周长,知道半周长后,公式为:z*(z-a)*(z-b)*(z-c)的开平方(就是开根号,怕你不懂,多写一点呢)
  z = ((a + b + c)/2);
  h = (z * ((z - a) * (z - b) * (z - c)));
  //弄完上面那么多,无论你是否看明白了,都无关紧要,重要的是我们的分支结构(if语句)来了
  if ((a + c <= b) || (a + b) <= c || (b + c <= a))
  {
    printf("你是小天才吧!小学数学是体育老师教的吧!\n");
    printf("error: 三角形的两边之和要大于第三边哦!");
  }
  else
  {
    s = sqrt((float)h);//有的博文也是的,算一个这个不把sqrt的作用说一下(sqrt:就是对一个数进行开平方计算,就是与上文说的海伦公式有关)
    //但是特别要注意这里的sqrt,这个东西在使用使一定要注意开平方对象的类型o(咱要做一个细节的男人)
    printf("%.3f",s);
  }
  return 0;
}

虽然这里面的内容大部分与分支无关,但是这个能充分说明(if语句)的使用场景和方法,例如:按照我们小学的逻辑,三角形的两边之和大于第三边的法则,我们也可以把上面代码中的(if语句)改成 if ((a+c>b ) &&( a+b>c ) &&( b+c>a)) 相反过来,然后此时就可以在 (if语句)中打印面积,而不是上面代码中的那个东西。(这里就可以更加充分证明 if 的这个判断条件其实是与你的后面内容息息相关的,说明判断很重要,古语有云:无规矩不成方圆。但现在我有云:无 if 不成程序逻辑)。

#include<stdio.h>
int main()
{
  char ch1 = 0;
  char ch2 = 0;
  printf("请输入一个字符:");
  ch1 = getchar();//这个getchar的作用跟scanf是一样的,就是输入的意思(但是还是有很大的区别的在使用时)
  //比如getchar就跟它的字面意思一样(char嘛)所以只跟字符类型有关,每一次可以输入一个字符,并且是不连续性的。
  //然而像我们的scanf跟它比就是大高手啦!(有参数可变,类型多样的同时,还可以连续输入,但是也有一定的鸡肋,那就是在某些特定的时候用法不如(gets),下面是部分区别:
  //gets的输入分割符只有回车,因此gets是能够读入空格的。如果输入为"hello world"时,上面程序的运行结果是"hello world",然而假如用scanf的话就只能输出hello,这就是用法上最大的区别
  if (ch1 >= 'a' && ch1 <= 'z')
  {
    ch2 = ch1 - 32;//这两步字符转换没什么好说的,自己理解一下,不明白也无关紧要啦!
  }
  else if (ch1 >= 'A' && ch1 <= 'Z')
  {
    ch2 = ch1 + 32;
  }
  else
  {
    ch2 = ch1 + 1;//这个的意思就是不是英文字母的转换情况下发生的事情,就是进行别的除了英文字母外的字符的转换
  }
  putchar(ch2);
  return 0;
}

经过我的深思熟虑还是得再强调一下(if语句)的重要性,所以这边我加了一个代码(就是上面那个字符转换而已啦!),虽然代码不怎么样,但是还是把(if语句)用的很到位的,所以给各位讲解一下,

现在轮到啥了我也不多说自己悟,所以到底如何使用switch语句呢?让下面这个代码告诉你:

这个代码的重点都在(图中的注释中自己仔细看一下,有点重要),知识点如下:1.gets,getchar和scanf区别(注意都是输入函数)

2.(if语句)的使用,上述代码的if,else if 和else用的方式

3.还有就是我也不知道,反正就是认真代码的看注释就行

****(强调一下刚刚那个求面积代码是刚写的,还热乎的呢,但是现在这个捏,我就要拿出我的压箱底了,为了进度嘛,见谅见谅)

#include<stdio.h>
int main()
{
  int day = 0;
  scanf("%d\n",&day);
  switch(day)
  {
    case 1:                          //case入口 break出口
  printf("星期1\n");           //适合做多分支的代码  switch case语句
    break;
  case 2:
  printf("星期2\n");
    break;
  case 3:
  printf("星期3\n");
    break;
  case 4:
  printf("星期4\n");
    break;
  case 5:
  printf("星期5\n");
    break;
  case 6:
  printf("星期6\n");
    break;
  case 7:
  printf("星期天\n");
      break;
  }
  return 0;
}

这个我也不多做介绍,就是一个典型的switch case语句,没什么好讲的(主要就是去理解一下那个switch后面那个括号里面放的东西),剩下的自己慢慢悟,重点是在于后面的这个题目:

#define default
#include<stdio.h>
int main()
{
  int n = 1;
  int m = 2;
  switch(n)
  {
  case 1:m++;
  case 2:n++;  //这题的关键就是理解 Switch(n)中括号里的 n   假如n为1时就执行case1  假如你为2时就执行case2 不执行case1
  case 3:
    switch(n)
    {
    case 1:n++;
    case 2:m++;
         n++;
      break;
    }
  case 4:m++;
    break;
        default;
      break;
  }
  printf("m = %d, n = %d\n",m,n);
  return 0;
}

就是如上面switch代码中的那句注释,就是最重要的东西了啦!脑袋瓜要灵光一点啦!(也就是switch括号的正解)

哦!对了,身为一个细节的男人,差点忘记把答案告诉你们了,答案是(3,5),不会没做对吧!(没做对就再看一遍,关键就是注意第二个switch语句,那个地方的n++,后就会导致n=2,所以此时的case2中的m++和n++都会执行,OK!),这边在家一小个知识点:就是使用到switch语句的时候,一般都会配合上break和continue的使用,用法就是字面意思,停止和持续的意思,自己悟啦!然后这边再用一个小标题说一下:if语句的用处很多很多,早知道多拿一个代码证明一下了,谁让我居然用来两个代码来证明switch,也是怪我。哎!下次再写哈!所以这边的 if语句不是很好,没有全面的展示出精髓。


(二).然后是循环

1.现在来到了循环了各位(但是现在是北京时间10点了,为了稳重,先让我停一下,让我去提交一下我的代码啦,不然我的小绿点就会被某个人超掉了(宏某人给我注意点,晚上不要谁太早))

(二、)循环就像是分支一样(分为两种主要的循环,哦,不对是三种(哼!谁让do while循环我属实不怎么用,但是估计大神应该经常用,大神的境界不是我这个小辈能揣摩的,嗯,有道理!)),好,现在让我们了解一下什么叫for和while循环:

1.第一个小代码(先拿一个你们好理解的,具体请看书本(C语言程序设计84页))

#include<stdio.h>
#include<math.h>
int main()
{
  int n = 14;//目前人口,单位亿
  int year = 0;
  double number = 0;
  double rate = 0.02;//这个0.02题目意思的增长率啦,不要怕
  for (year = 1; year < 10; year++)//注意啦,注意啦,这个才是重点,这个就是我的循环控制语句,也就是我的目的,别的看不懂不怕
  {
    number = n * pow((1 + rate), year);//这个又涉及到了一个数学函数,所以要引一个<math.h>函数,不然跑步起来哦!
    //然后这边写一下pow函数的作用:就是跟刚刚求三角形面积那个(sqrt函数)有一点像,但是是反过来的像
    //所以pow其实就是用来求一个数的次方的,例:pow((1 + rate),year)这个的意思就是求(1+rate)的year次方的意思,不理解无所谓
    printf("%d年后,人数为:%.2f亿\n",year,number);
    //这个打印方法还是很帅的,同时打印两个变量,可以注意一下,学一学
  }
  return 0;
}

附上打印结果,其实就那样啦!


5.png

这个代码具体详情还是在注释之中,认真看(顺便讲一下,注释其实是个好东西,没事多注释哈!) for (year = 1; year < 10; year++)这个东东就是传说中的for循环,for循环就是又三个表达式构成的,(第一个表达式的意思就是,year从1开始执行)(第二个表达式的意思就是,year循环是次数,就是用来控制循环次数的,例如这个就表示这个循环9次后就会停止,因为第10次的时候year=10,不符合year<10这个判断表达式,所以停止执行)(第三个就是year++,写成year+=1,也是一个意思,或者year=year+1),随你心意好吧!说以以上就是for循环的大致构成,多的不说少的不唠,主要是想睡觉了。


2.下面再给你演示一个代码

#include<stdio.h>
#include<math.h>
int main()
{
    int i = 0;
    for (i = 0; i <= 100000; i++)
    {
        //这个括号里面实现的就是判断i是否为自幂数
        //1.计算i的位数   n位数  123
        int n = 1;
        int tmp = i;
        int ret = 0;
        int sum = 0;
        while (tmp /= 10)
        {
            n++;//如果这样写(就会导致i的数字直接变成了0,后面就不能用i了),所以应该用一个东西把i给替换,例:int tmp = i;
        }
        //2.有了位数我就要开始计算i的每一位的n次方之和(但前提是算出每位是什么)//123
        tmp = i;
        while (tmp)
        {
           sum += pow(tmp % 10, n);
           tmp /= 10;
            /*ret = tmp % 10;
            pow(ret, n);
            tmp = tmp / 10;
            sum += ret;*/
        }
        //3.比较  
        if (sum == i)
        {
            printf("这些数是自幂数:%d\n",i);
        }
    }
    return 0;
}

本来是想用阶乘的那个的,可惜我的小金库里这个比较好找,代码正规理解,就是代码注释,感兴趣你就理解一下,看不懂没关系,这个代码同时把for循环和while循环给用上了(说明只要你牛,你爱怎么写怎么写)以下是小知识点:

1.还是 先讲for循环,因为刚刚讲完,各位应该还有点印象,这边这个for循环的目的就是可以获得(0到10000)之间的所有数字,(这边就有一个小好处,就是以后不管你遇到什么题目就是叫你求,多少多少数字到多少多少数字,然后要这些数字干嘛干嘛的时候,你第一步就应该要想到有循环这种东西,先闭住眼睛把循环写上去),所以这个跟上面那个次数循环是有一点点的不一样的。

2.现在先抽象的讲一下while循环,按照上面那个代码中的while来讲:就是要注意的是while后面的括号(就跟switch中的括号一样要理解清楚),while()的这个括号的意思就是判断(最终这个括号里的东西是不是0的 意思(因为0为假,为假时它就会停止循环,执行下一步了))所以使用起来就是想上述代码一样 while (tmp), while (tmp /= 10)或者写成while(tmp!=‘\0’),while(tmp!=‘\0’),不用疑惑,其实这好理解,就是因为’\0’的ASCII码值为0,所以为’\0’就是为0,也就是为假,所以一个道理,循环停止, while (tmp), while (tmp /= 10),并且这种 写法属于简写(意思就是tmp不为0的意思和tmp/=10不为0的意思),不为0,循环就继续,为0就停止,这样的好处,按上述代码的意思来讲就是可以很简单的算出(tmp是一个几位数和tmp的个位,十位,百位的位数的次方),看不懂没关系,因为都不重要,重要的是循环是什么,怎样去理解循环(如果你觉得你自己理解了,那么你就可以去尝试理解一下阶乘的算法了,加油我的好兄弟!)算了,我还是把阶乘的算法赋在下面吧!省得你们找了。代码如下:

n的阶乘正常版
#include<stdio.h>
int main()
{
  int n = 0;
  int i = 0;
  int sum = 1;
  scanf("%d",&n);
  for(i=1;i<=n;i++)
  {
    sum = sum * i;//这步最好替换成sum *= i;
  }
  printf("sum=%d\n",sum);
  return 0;
}
#include<stdio.h>
int main()
{
  int i = 0;
  int sum = 0;//这边保存的才是最终结果,也就是阶乘相加
  int n = 0;
  int ret = 1; //这个地方就是为了保存,的阶乘而已
  scanf("%d",&n);
  for (i = 1; i <= n; i++)
  {
    int ret = 1;
    int j = 0;
    for(j=1;j<=i;j++)//这边就是为了产生 ‘1到i’的所有数字而已
    {
      ret *= j;//假如这边的现在是3的话,那这边就是为了算3的阶乘,所以这边的for循环要循环3次,表示从1*2*3,代表3的阶乘
    }            //出错的原因就是没有将ret给重新赋值,导致ret不再是1,而是2;
    sum += ret;
  }
  printf("%d\n",sum);
  return 0;
}

对循环(有关阶乘)的深入讲解:(结合代码仔细看)

这两个代码上面那个算的是某一个数的阶乘(用到了一个for循环),而下面这个讲的是(等一下哈,让我仔细看一下讲的是什么 鬼,好滴,这个讲的就是,你输入一个数,然后你就可以得到从1开始到这个数的所有数字的阶乘的和了),这个比上面那个单独求一个数的阶乘更高级一点点,所以用到了两个for循环,(其中第一个for循环是:用来得到 1 到我输入那个数之间的所有的数的,这个应该能看明白的。然后第二个for循环就是为了:得打1到我输入数之间所有数的阶乘的),然而为了实现得到 1 到我输入那个数之间的所有的数,(代码中的(i<=n)就显得尤为的重要了),因为只要当 i<=n时,这个循环就会执行,所以我就实现了得到 1 到我输入那个数之间的所有的数的这个目的了。然而又为了得到 1到我输入数之间所有数的阶乘,第二个for循环中的 ret *= j ,这步就显得比较关键(前提是ret=1,不然如果ret=0,那就一直得到的都是0(具体原理,问你小学老师)), ret *= j ,这个还是写常规一点:ret=ret * j,这个的意思就是把 j 的值每次都乘到 ret 中,然后再赋值给ret,这样就可以实现 ret 的 连续相乘,得到从 1 到 这个循环中的那个数之间的所有数字的相乘(也就是传说中的阶乘啦!)(这边还是举个例子,比较形象,例如:此时 输入n=5,i此时为1,小于5,判断为真,所以进到循环里面,进来后就来到第二个for循环,也成立,进来到赋值这步ret=ret * j,赋值完,此时的ret就是等于1,因为是第一次循环),所以照猫画虎,这样的循环重复5次(第一个循环循环5次,然后这边特别 要注意的就是第二个for循环),因为第二个for循环每次都是从 1 开始的,所以无论第一个for循环循环了几次,第二个for循环永远从一开始(也就是导致要从 1 开始循环到此时第一个for循环的那个次数,比如第一个for循环此时第3次,那么我的第二个for循环就要从 1 循环到3,只有这样我才能完美的实现阶乘这个算法)。所以你理解了吗?入所理解了,你就算是对循环有了一定的理解了。


三、多的不说,少的不唠(个人浅薄理解)

其实重要的是要有耐心,多看多理解,假如你能看完这些,那么证明你是一个有耐心的人,然后就是排版不是很有条理,见谅见谅,睡觉大吉!

相关文章
|
18天前
|
负载均衡 算法 应用服务中间件
面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
字节跳动面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
32 0
|
20天前
|
存储 编译器 Linux
【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参
【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参
|
1天前
|
C语言
【C语言】字符分类函数与字符转换函数
【C语言】字符分类函数与字符转换函数
7 1
|
1天前
|
存储 缓存 编译器
C语言之scanf浅析
C语言之scanf浅析
6 0
|
2天前
|
C语言 C++
C语言利用ASCII码表统计字符串每个字符出现的次数
C语言利用ASCII码表统计字符串每个字符出现的次数
5 0
|
2天前
|
C语言
C语言:字符函数和字符串函数(strlen strcat strcmp strncmp等函数和模拟实现)
C语言:字符函数和字符串函数(strlen strcat strcmp strncmp等函数和模拟实现)
|
11天前
|
算法 前端开发
前端算法 岛屿的最大面积 DFS(深度优先搜索)
前端算法 岛屿的最大面积 DFS(深度优先搜索)
11 0
|
12天前
|
C语言
【C语言】用三种循环语句 计算1到1000之间能被2或3整除的数的总和
【C语言】用三种循环语句 计算1到1000之间能被2或3整除的数的总和
|
20天前
|
存储 算法
【算法与数据结构】深入解析二叉树(二)之堆结构实现
【算法与数据结构】深入解析二叉树(二)之堆结构实现
|
23天前
|
存储 C语言
【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)&&三种strlen模拟实现1
【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)&&三种strlen模拟实现