初始C语言-2.C语言程序的四种基本结构

简介: 语句组中,可为单个句子,也可为多条语句,如果为单条语句,{}可以省略不用;若为多条语句,则必须要加{},否则会有语法错误。

学习C语言二,C语言的四大基本结构


还有下的视频在我B站主页找。


概要:C语言的四种基本结构是很重要的,程序主要是由这些结构组成,学完这些结构,便可以写一些基本的程序。。


一,四种基本结构


6209da5937f34976a87d721d6b334ec9.png


二,四种基本结构精析


       一.分支结构(if-else)


if(表达式){
  语句组1; 
}
else{
  语句组2; 
} 


1.1首先,if()后面的


表达式一定为真,才能继续后面的语句,否则运行else中的语句。(为真的意思就是非0);


1.2语句组中,可为单个句子,也可为多条语句,如果为单条语句,{}可以省略不用;若为多条语句,则必须要加{},否则会有语法错误。


b2793a97583f46c79f5a33eb233fe797.png


1.3上述结构叫做双分支结构


,当然也会有单分支结构,也有多分支结构,还有一种很变态的多分支结构。(后面会着重介绍)


//本题目要求计算下列分段函数f(x)的值:
#include<stdio.h>
int main(){
    float x,r;
    scanf("%f",&x);
    if(x!=0)
    {r=1/x;
        printf("f(%.1f) = %.1f",x,r);
    }   else
        printf("f(0.0) = 0.0");
        return 0;
}


6fbe88f410d84b2885bccab560a7b1b8.png


**这里再给大家一个例题自己尝试。


单分支结构(if结构)

有的人就会问了,为啥单分支结构只是if结构?不能是else结构吗?          不行

if的英文意思是”如果“,没有”如果“哪里来的”另外“?


即if可以单独使用,而else不行。


if(){
    语句组;
}


**重点还是要说一下if命令的嵌套使用,基本除了顺序结构外,每一种结构的嵌套都很重要且常用!


1.4什么叫嵌套?


1.if(){
  if(){
  }
  else{
  }
} 
2.if(){
}
else{
  if(){
  }
  else{
  }
}
3.if(){
  if(){
  }
  else{
  }
}
else{
  if(){
  }
  else{
  }
}


这样看确实会有点眼花缭乱,我太懒了。。。


顾名思义,嵌套就是在一个里面加了其他的东西,可能就加了一个,也可能加了好多。只要你想,你可以一直循环着嵌套。


但是如果这样的话,问题又来了;


那么多if和else,要怎么才能知道,谁跟谁是互相配对的呢?


嵌套时,else总与最靠近它的,没有与别的else配对过的if相匹配。


当对某个问题的限制条件仍有限制时,可以选择if的嵌套结构。


64df263927ff49208e7cb6a8fc37413f.png


这也是一个很好的例题,希望大家能搞懂。


1.5多分支结构;

多分支结构与嵌套结构往往是用的比较多的;


if(){
}else if(){
}else{
}


else if可以写好多个,依题目而定。当问题有好多个限制条件把这个问题分为若干个小部分时,可以选择多分支结构。


//猜数字游戏
#include<stdio.h>
int main(){
  int mynumber=789;
  int yournumber;
  printf("please input a digit:");
  scanf("%d",&yournumber);
  if(mynumber==yournumber)
  printf("good guess!");
  else if(yournumber>mynumber)
  printf("Too big");
  else
  printf("Too small");
  return 0;
}


例如这个题目,题目要么对,要么错,但是错的时候却有太大和太小,所以我选择用多分支结构。


1.6(变态的)多分支结构(swith结构)

a4c7b16fef5f45bbaca6873eb16a81bc.png


*** switch后面的表达式中只能是整型式,或者字符型(特殊的整型);


因为浮点型数字并不能精准存放,它也不能拿出来作为比较的量。


总的来说,switch结构就是比较方便一点的多分支结构,多分支结构一旦分支太多,可能会导致错误,因为if else实在太多,同时程序的可读性也不强。switch相比多分支结构更简洁,清晰。


但是switch的限制也比较大,只能用于整型。


610055bcc0df4f6e96ef7d00839e04a1.png


着重讲一下这个default,这个是很必要的,如果switch接收到的量不是case中的任何一个,我们又想让程序有操作,也便于我们找出错误的地方,所以选择这个default,意思就是如果上面的case一个都不满足,就执行它;


来点邪恶的东西,如果我把default放在所有case的前面会怎么样?


当这个时候,程序先执行除了default的代码,最后执行default。


如果default后面没有break,程序会执行default下面的代码,无视case匹配,直到又遇到break;


2e92cd022a1e4ad89621722cc3903119.png


这是一个很好的解释例子,这个代码中case的顺序也不是按顺序来的,default也不按常理出牌,但是最后仍然输出了-1,但是为什么又输出了3?


因为default中没有break,程序继续向后执行,直到遇见break,在这里,return和break有一样的作用。    看下下面的这个例子;


#include<stdio.h>
int main(){
  int choice,i;
  double price;
  printf("[1].......\n");
  printf("[2].......\n");
  printf("[3].......\n");
  printf("[4].......\n");
  printf("[5]exit\n");//提供选择 
  for(i=1;i<=5;i++)//给五次选择的机会 
  {
      printf("请输入选择:");
      scanf("%d",&choice);
      if(choice==5)
      break;
      switch(choice)
  {
    case 1:price=1;break;
    case 2:price=2;break;
    case 3:price=3;break;
    case 4:price=4;break;
    default:price=0;break;
  }
  printf("price=%.1f\n",price);
  }
  printf("Thanks\n"); 
  return 0;
}


1.7条件运算表达式


这里用的是比较少的一个表达式因为运用条件比较苛刻,只有当一个问题有两种情况时才能使用,一般到了后面就很难遇到这么简单的题目了;


表达式1?表达式2:表达式3;条件运算表达式由?:;组成,是C语言中提供的唯一一个三目运算符 。


64b6ca74ae24468caf2226513281bc4b.png


如上,首先判断n是否大于5,如果n大于5,执行表达式2,如果小于等于5,则将n赋值为0;


77328e922df8459e927e1a4155ef02c8.png


此刻就相当于一个双分支结构。这个并不常见,就不做过多讲解了。


***二,循环结构


如果没猜错的话,循环绝对会是大部分同学的噩梦,不管是初学者还是学过一段时间的人,学过好久的人也免不了在这里踩坑,一定一定要用心认真搞清楚!!!


 541bee18366d40eda4ae2f37e222b548.png


循环主要分为两种,一种是for循环一种是while循环,两者实际上是相通的,只有在某种情况下谁更合适而已。


   一,for循环

for循环是C语言中比较常用的一种结构了,尤其在数组中,更为明显。

1.for循环的基本结构


for(表达式1;表达式2;表达式3;){
  语句组; 
} 


我们来分析一下这个结构,如下图,我也会做一些补充。


d9d96068a01049a1a736a0db1e5f8339.png


我们对缺省做一下分析,表达式1是一般是不能缺省的,因为表达式1的作用是初始化变量,当然,如果你非要不写在里面,那就写在外面,看个人喜好,但是写在里面的可读性更好。


......那如果是表达式2缺失呢?我们一定要学会一种思维,想问题的时候要追根溯源,例如这里,表达式2缺失会怎么样?我们选择溯源去想,表达式2的作用是什么呢?表达式2的作用是判断。。也叫做循环的限制语句,如果限制条件没有了,系统会默认表达式二为真,则会很容易造成死循环,这个时候就不得不讲一讲break和continue命令了;


1fd8b7b5f0d7455880ea6e5ee2cd6822.png


4b28c09648564cacab8d69243fc27dd4.png

                                                                          continue常用于if结构中;


由上可知,除非有break或者continue,你就等着死循环吧。


如果,表达式3缺省呢?这就跟表达式1一样了,这里不写,其他的地方也要写,不写就等着死循环吧。


它的运行顺序又是怎么样的呢?


d98fe97319e74ec5b6be182e8402da2b.jpg

#include<stdio.h>
int main(){
  int count,num,i;
  double score,total;
  printf("Enter num:");
    scanf("%d",&num);
    printf("请输入%d个成绩:",num);
    total=0;
    count=0;
    for(i=1;i<=num;i++)
    {
      total=total+score;
      if(score<60)
      count++;
      scanf("%lf",&score);
  }
    if(num!=0){ 
  printf("Averge is %.2f\n",total/num);
  printf("Number of failure is %d\n",count);
  } 
  else
  printf("Averge is 0");//是除法时,则要专门写一个if,来考虑分母为0的情况!!! 
  return 0;
}


e6ef8c555d01486e8d7732e3ef01f895.png


二,while循环与do-while循环

while(表达式){
    循环体(所有的都是这样,花括号中只有一条语句时,可不要花括号)
}


do{
    循环体;
}while(表达式);


两个循环结构中虽然都有while,都是也有不相同。


1.while循环可能一次都不发生,只要表达式为假。


2.do-while一定至少发生一次,先执行后判断;do-while只是一条单语句,所以后面要加;分号。


4e6a5b09865148018d78423347d5a0e1.png


09a3cecd9005487f8db29339372bfa8f.png

1b594a236cf64620b4aa1177a47ea11e.png


试着把这些例子看懂,能看懂就很棒了;


 三,循环嵌套

1.for循环嵌套;


这可太简单了,就是for里面再加一个for(俗称套娃),当然,可以无限套。


2.其他的循环嵌套也都是这样,都是一个套一个的。直接上例题吧。


65fc5f39ee734068844a5f82714bad75.png813b27641e7b4e0dada272088eba6d3c.png


还有一些,循环与分支结构的互相嵌套,这个概念还是很好理解的,就直接上题了;


476164bbfe2c4340a635bc766679f2b6.png


这道题难度很大,一定要搞懂!!!!!!!


3ce9e207a3aa4ba2beed9344ea155b52.png


这个也要好好看看。


d9689127b1804adc8137376063d9ba93.png


525ef237d1044ea984b86a3af217c902.png


上面几道题都要好好看看。


四,子程序结构(函数结构)

1.函数是C语言程序的基本组成单元,迄今为止编写的每一个程序都需要用到函数。


基本结构就是函数声明,函数调用,加上函数定义。


int sum (int m,int n);//函数声明;
  //sum前面的int是返回值类型
  //sum是函数名
  //后面的两个int是形参的数据类型


#include<stdio.h>
double cylinder(double r,double h);//函数声明; 
int main(){
  double height,radius,volumn;
  printf("Enter radius and height:");
  scanf("%lf%lf",&radius,&height);
  volumn=cylinder(radius,height);//函数调用,将返回值赋给volumn; 
  printf("volumn=%.3f",volumn); 
  return 0;
} 
double cylinder(double r,double h){//定义求圆柱面积的函数; 
  double result;
  result=3.1415926*r*r*h;
  return result;//返回结果; 
}
/*也可不声明函数,但需要将新定义的函数放在main函数之前*/
#include<stdio.h>
double cylinder(double r,double h){//定义求圆柱面积的函数; 
  double result;
  result=3.1415926*r*r*h;
  return result;//返回结果; 
int main(){
  double height,radius,volumn;
  printf("Enter radius and height:");
  scanf("%lf%lf",&radius,&height);
  volumn=cylinder(radius,height);//函数调用,将返回值赋给volumn; 
  printf("volumn=%.3f",volumn); 
  return 0;
}


我们这里说的函数都是自定义函数,当然,那些系统函数也是人写的,身份不一样而已。


2.依据上方代码可知,自定义函数要先声明(向系统表明我已经创造了这个函数,系统会给这个函数分配地址),再在main函数中对其调用(也不一定非要在main函数中调用,后面讲)。调用之后,就要在main函数之外写自定义函数了。


问题来了,为什么要在main函数之外去写这个自定义函数。


*****敲黑板的内容来了:


函数定义不能嵌套,至于为什么,我也不知道。


3.现在再来说一下参数问题,在函数中,参数又分形参和实参,啥叫实参?啥叫形参?


简单来说,形参就是形式参数,在声明中,变量名是可有可无的,在自定义函数入口处其实也可以省略,只要自定义函数中不用到那个变量,当然,一般都是要用到的。


那么实参呢?实参就是实际接受到的数据,这个是必须要有名字的,不然怎么将数据传到里面?


那么根据我上面的解释,你们知道在上面那个代码中,哪个是形参哪个是实参吗?


没错,自定义函数后面接的括号里面的内容就是形参,函数声明中的也是形参,而函数调用中的参数就是实参。


说省略的问题只是为了让大家了解这个知识,而不是提倡大家去省略,一定不要以为这样写的少就很帅,一个好的程序跟他的可读性还是有很大关联的。


4.那么,我们为什么要自定义函数呢?好像大部分的操作在main函数中也能完成。


这个在之后写大项目时便能知道函数的方便之处,其实函数的用处是很大的,它给了我们更多的选择,是我们在处理问题时也更加的方便。


话不多说,直接上代码。


#include<stdio.h>
#include<math.h>
int prime(int m){
  int i,limit;
  if(m<=1)
  return 0;
  else if(m==2)
  return 1;
  else{ 
  limit=sqrt(m)+1;
  for(i=2;i<=limit;i++){//1不是素数,所以从2开始 
      if(m%i==0)
      return 0;
    }
  }
  return 1;
}
int main(){
  int x,y,k,count=0;
  printf("请输入x,y:");
  scanf("%d%d",&x,&y);
  if(x<1||y>500||x>y)
  printf("Invalid!\n");
  else{
    for(k=x;k<=y;k++){
      if(prime(k)==1){//根据返回值判断。 
        printf("%6d",k);
        count++; 
      }
      if(count%10==0)
      printf("\n");
    }
  }
  return 0;
}


#include<stdio.h>
int sum(int m,int n){
  int i,result=0;
  for(i=m;i<=n;i++){
    result+=i;
  }
  return result;
}
int main(){
  int m,n,sum_;
  printf("Enter m,n:");
  scanf("%d%d",&m,&n);
  sum_=sum(m,n);
  printf("%d",sum_);
  return 0;
}


还有要注意的就是函数的返回值问题,首先,函数一次只能返回一个值,再一个就是,新手经常会混淆返回值是谁的这个问题,其实很简单,主函数调用时,要的是什么值,就返回什么值。

5.参数传递


首先,参数只能由实参传向形参,形参的改变是无法干扰实参的;


60d2399d60e14454ba87e0cec662755a.png


见上面的代码;


说的都差不多了,再给大家拓展一下;有关静态变量的问题(static)


c25ebc689a544f0289c765609e934977.png

2fecc27ea46044d1b30bd88493dd6a5a.png


37d72ef24d4a4c058bc3fc8150c84215.png


这是为什么呢?这里就又要讲一讲有关C语言程序的储存内容了;


就像形参为什么不能影响实参?


cfdd507378dc4b64b97bcee53143f1c9.png


系统会给自定义函数开辟一个空间,当自定义函数结束后,空间就会被释放。存储的变量就也被释放了。所以形参不能影响实参。如果我加上了static,我就将自定义函数中的变量放到了静态区中,成了静态变量。知道main函数执行完毕,变量空间才会被释放。


希望大家能有所收获!!!一定要把我上面写的代码看懂哦,这样基本上这些结构你就能搞清楚了,这类问题便很难难到各位了。

目录
相关文章
|
18天前
|
C语言
C语言之分支结构
C语言之分支结构
23 0
|
1月前
|
C语言
C语言结构体内存对齐
C语言结构体内存对齐
|
1月前
|
存储 编译器 Linux
【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参
【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参
|
1月前
|
存储 编译器 C语言
深入探索C语言动态内存分配:释放你的程序潜力
深入探索C语言动态内存分配:释放你的程序潜力
32 0
|
7天前
|
C语言
第一章 C语言知识点(程序)
第一章 C语言知识点(程序)
17 0
|
6天前
|
存储 自然语言处理 编译器
“ Hello world ”中的秘密之【C语言程序编译和链接】
作为C语言最经典的代码,大家都可以轻易写出。但是代码的运行过程却很少有人清楚,接下来我将介绍代码运行的奥秘。
16 0
|
8天前
|
自然语言处理 编译器 C语言
C语言程序编译和链接
在ANSI C的任何⼀种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换为可执⾏的机器指令(⼆进制指令)。 第2种是执⾏环境,它⽤于实际执⾏代码。
|
10天前
|
网络协议 物联网 数据处理
【C 言专栏】C 语言实现网络通信程序
【5月更文挑战第4天】本文探讨了使用C语言实现网络通信程序的方法,包括理解网络通信基本概念如协议和套接字,以及TCP/UDP通信的实现步骤。通过创建套接字、绑定端口、监听连接、数据传输和错误处理等关键环节,阐述了C语言在网络通信中的优势。文中还提到了实际应用案例、程序优化策略及未来发展趋势,旨在帮助读者掌握C语言在网络通信领域的应用技巧。
【C 言专栏】C 语言实现网络通信程序
|
12天前
|
并行计算 算法 测试技术
【C 言专栏】优化 C 语言程序性能的策略
【5月更文挑战第2天】本文探讨了优化C语言程序性能的策略,包括算法优化(选择合适的时间和空间复杂度)、代码结构优化(减少函数调用,合理使用循环)、内存管理优化(合理分配和及时释放内存)、编译器优化(选择优化级别,内联函数,循环展开)、数据结构优化(根据需求选择数组、哈希表或堆)、并行计算优化(多线程、多进程和MPI编程)以及性能测试与分析(使用性能分析工具、基准测试和分析执行路径)。通过这些方法,可以提升C语言程序的效率和运行速度。
|
14天前
|
存储 Linux C语言
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)-2
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)