C语言初识结构

C语言是一门结构化的程序设计语言
生活中只有三种结构:顺序结构,选择结构,循环结构
控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定符组成,C语言有九种控制语句。
可分为以下三种情况:
1条件判断语句也叫分支语句:if语句,switch语句
2循环执行语句:do……while语句,while语句,for语句
3转向语句:goto语句,return语句,break语句,continue语句
选择结构——分支语句
if,switch
什么是语句?
被一个;隔开的就是一条语句
空语句指仅有一个分号,无内容
if语句 
    if(表达式) 
        语句;  
          
    if(表达式)  
        语句1;  
    else     
          语句2; 
   
多分支:
        if(表达式) 
             语句1;  
        else  if(表达式2)  
             语句2;
        else
           语句3;
若要执行多行语句,则要使用大括号
       if(表达式)
         {
               语句列表;
         }
但这样的语句结构是合理的
if(……)
    if(……)
        printf("……");
    else
        printf("……");
else悬空原则与上方最近的,未匹配的if进行匹配
return返回值只有一个,return语句意味着一个函数模块的结束
函数返回类型为void时,也可以有return语句,但不能有任何返回值,只能用return;
switch语句 (switch允许嵌套使用)
switch(整形表达式)   
    语句项; 
}
语句项是一些case语句 
case    整形表达式:  (case后必须是常量,而不是表示整形的变量)
语句; (超过2行要大括号)
switch(整形表达式)可以是字符型(整形为字符对应的ASCII码值)
case会在符合对应值后执行,即符合值后语句全部执行(无论有无case)要想只执行case对应值后语句,
需在case语句结尾加上一个新的语句:break;
default:                    当switch整形表达式与case整形常量表达式无匹配项时执行
    语句;                多用于处理错误
default,case无顺序要求,两个语句后的是冒号(:)
switch中continue无意义,continue用于循环语句,switch不是循环
循环结构——循环语句
while,do……while,for
while语句
while(表达式)        //循环语句两行以上要加大括号
    循环语句;
while中break的作用:跳出循环
            continue的作用:跳出本次循环语句,进入下一次循环。
例题: (?EOF和书上的不一样)
#include<stdio.h>
    int  ch=0; 
    while(ch=getchar()!=EOF)
        putchar(ch); 
    return 0; 
}
//循环说明:只有获得EOF才停止循环
//getchar()接受一个键盘的字符
//putchar(ch);相当于printf("%c\n",ch);
//getchar在遇到读取错误或文件结束标志时,会返回EOF,其本质是-1,为整形,char类型放不下
//当输入三个字符EOF时,getchar读三次,读一个E,打印,读一个O,打印,读一个F,打印.结束
//ctrl+z时才会输入一个EOF,结束循环
//EOF—end of file   ——文件结束标志 (相当于字符串中的\0)
确认ASCII码值的方法:  printf("%d\n",'被测内容');
getchar输入一个字符
输入类型为:空,返回类型为:整形
putchar输出一个字符
输入类型为:整形,返回类型为:整形
getchar,putchar一次只能操作一个字符
例题:输入密码后,输入Y确认
int  ret=0;
char  password[20]={0};                           
printf("请输入密码:>");
scanf("%s",password); 
printf("请确认(Y/N):>");
ret=getchar(); 
if(ret=='Y')
    printf("确认成功\n");
else
    printf("放弃确认\n");
运行结果:输入密码后,放弃确认
//scanf.getchar为输入函数。其工作原理为:scanf读一个字符串,读前检测输入缓冲区,第一次输入,输出缓冲区为空白,在满足输入缓冲区为空白时,scanf等待输入,输入123456后回车,输入缓冲区内存为123456\n,scanf读取123456,还剩\n,getchar确认缓冲区时自动读取\n,\n不等于Y,放弃确认
//解决方案:在scanf下添加一个语句:getchar();
问题进阶:输入123456空格ABCD回车(scanf只读取空格前的)  
scanf读取字符串时,遇到空格就结束了
问题在如何消除空格后的影响,而不是确认密码为123456空格ABCD
解决方案:定义变量ch:int  ch=0;
             在scanf下加上:while((ch=getchar())!='\n')
                                       {
                                            ;
                                       }
for循环         while循环的缺点,条件的初始化,判断,调整距离较远,改代码时易出错
语法:for(表达式1;表达式2;表达式3)
                循环语句(超过两行要大括号)//break与continue与while一致
表达式1为初始化部分,用于初始化循环变量
表达式2为条件判断部分,用于判断循环是否终止
表达式3为调整部分,用于循环条件的调整
for循环的初始化,判断,调整都可以省略,判断部分如果省略,则条件恒为真(最好不要省略条件)
do……while循环
do
{
    循环语句;        循环语句必执行一次
}
while(条件语句);
例题:
编写一个查找数字位置的代码(前提是数字有序)
初方案:穷举查找
int  mian()
{
    int  arr[]={1,2,3,4,5,6,7,8,9,10};
    int   k=7;
    int   i=0;
    int   sz=sizeof(arr)/sizeof(arr[0]);
    for(i=0;i<sz;i++)
    {
          if(arr[]==k)
           {
                printf("找到了,下标是:%d\n",i);
                break;
           }
     }
      if(i==sz)
          printf("找不到\n");
     return  0;
}
进阶方法:二分查找法        查找的次数为log2(n),(n为数字总数)(余数为1)
int  main()
{
    int  arr[]={1,2,3,4,5,6,7,8,9};
//元素1  2  3  4  5  6  7  8  9
   下标0  1  2  3  4  5  6  7  8
    int  k=7;
    int  sz=sizeof(arr)/sizeof(arr[0]);
    int  left=0;
    int  right=sz-1;
    
    while(left<=right)
    {
        int  mid=(left+right)/2;
        if(arr[mid]>k)
            {
                right=mid-1;
            }
        else  if(arr[mid]<k)
            {
                left=mid+1;
            }
        else
            {
                printf("找到了,下标是:%d\n",mid);
                break;
            }
    }
//猜值范围:(0~9)mid=4,a[mid]=5<7,left=mid+1=5——第一次循环
                    (5~9)mid=7,a[mid]=8>7,right=mid-1=6——第二次循环
                    (5~6)mid=5,a[mid]=6<7,left=mid+1=6——第三次循环
                        mid=6,a[mid]=7==7
    if(left>right)
    {
          printf("找不到\n");  
    }
//若不存在则会出现左右下标交叉的现象,此时left>right
    return  0;
}
问题进阶:用子程序实现数字查找的算法
注意点:计算数组个数需要在主函数中进行,数组传参只能传首地址,无法计算整个数组的长度
例题:
编写代码演示多个字符从两端移动,向中间汇聚
基本思路:两个空间
welcome  to  bit!!!!!
###################
每次将最左和最右的字符替换下空间的#
int  main()
{
    char  arr1[]="welcome  to  bit!!!!!";
    char  arr2[]="####################";
    int  left=0;
    int  right=sizeof(arr1)/saizeof(arr1[0])-2;
    while(left<=right)
    {
        arr2[left]=arr1[left];
        arr2[right]=arr1[right];
        printf("%s\n",arr2);
        left++;
        right--;
    }
    return  0;
}
//考虑一点一点出来的效果,使用函数Sleep(时间),时间单位:毫秒,1000毫秒=1秒
//进一步考虑效果,以一个近似动态的效果,Sleep(1000);后加一个语句:system("cls");
//system是执行系统命令的一个函数
编写代码:实现模拟用户登录的情景,并且只能登录三次(只允许输入三次,正确成功,失败退出)
int  mian()
{
    int  i=0;
    char  password[20]={0};
    for(i=0;i<3;i++)
    {
        printf("请输入密码:");
        scanf("%s",password);
        if(strcmp(password,"123456")==0)
//==不能用来比较两个字符串是否相等,应当使用库函数strcmp
//strcmp(1,2)若括号内内容相等,则返回0,
//若1大于2,则返回一个大于0的数,若2大于1,则返回一个小于0的数
        {
            printf("登录成功\n");
            break;
        }
        else
        {
           printf("密码错误\n");
        }
    }
    if(3==i)
    {
        printf("三次密码错误,退出程序\n");
    }
    return  0;
}
例题:
编写代码,求两个数的最大公约数
方法:辗转相除法,用较大数除较小数,得第一余数(是余数),再用较小数除第一余数得第二余数,第一余数除第二余数,如此往复,当余数为0时,最后两个数中的较小数为最大公约数
int    main()
{
    int  m;
    int  n;
    int  r;
    scanf("%d%d",&m,&n);
    while(m%n)
    {
        r=m%n;
        m=n;
        n=r;
    }
    printf("%d\n",n);
    return  0;
}
例题:
打印出100~200之间的素数
若不为素数,则必可以写成a*b的形式,a,b必有一个小于质数的开平方
int  main()
{
    int  i=0;
    int  count=0;
    for(i=100;i<=200;i++)
//可以将偶数全部去掉
    {
        int  j=0;
        for(j=2;j<=sqrt(i);j++)
        {
            if(i%j==0)
            {
                break;
            }
        }
        if(j>sqrt(i))
        {
            count++;
            printf("%d",i);
        }
    }
    printf("\n count=%d\n",count);
    return  0;
}
%2d,两个位置右对齐,如打印2:    2 ,打印12: 1 2
%-2d,两个位置左对齐,如打印2: 2   ,打印12: 1 2
例题:
猜数字游戏:电脑会生成一个随机数,猜中它。
基本思路:1.作为一个游戏,要进入菜单,所以至少执行一次,选择do……while()循环
                 2.做一个具有提示意义的菜单
                 3.编写符合菜单和进入过程的代码
                 4.每进行一个阶段性过程检查一次效果
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
{
        printf( "***********************************\n");
        printf( "**********  输入:1进入   *********\n");
        printf( "**********  输入:0退出   *********\n");
}
void game()
{
         int out = 0;
         int n = rand()%10000+1;   
//打印n,确认是否随机
//rand:生成一个伪随机数在0,RAND_MAX之间
//查看RAND_MAX:声明头文件#include<stdlib.h>,选中RAND.MAX,右击鼠标,转到定义
//RAND.MAX为一个数字0x7FFF—>32767
         do
        {
               scanf( "%d", &out);
                if (out > n)
               {
                       printf( "猜大了\n");
               }
                else if (out < n)
               {
                       printf( "猜小了\n");
               }
                else
               {
                       printf( "猜中了\n");
               }
        } while (out != n);
}
int main()
{
         int i;
        srand(( unsigned int)time( NULL));
//在调用rand前用srand函数设置伪随机数生成器
//srand设置一个随机起点
//void  srand (unsigned  int seed);
//变量定义在当前代码前列
//若srand(1),ret=rand()打印全是41,若srand(2),ret=rand()打印全是45
//保证srand括号内整形不断变化,即可得到随机值,可以使用时间戳
//时间戳:一个时间与另一个时间的差值转换为秒的数字,即当前计算机时间减计算机起始时间(1970.1.1.00:00:00)
//用时间戳来设置随机数的生成起点,time函数:time_t  time(time_t*  timer);  
//time_t右击转到定义,可知time_t本质上是long
//time函数需要声明头文件#include<time.h>
//将srand放在void  game函数中则会生成多个随机起点,打印出随机数会趋向于变大
         do
        {
               menu();
               scanf( "%d", &i);
                switch (i)
               {
                        case 1:
                              game();
                               break;
                        case 0:
                              printf( "退出游戏\n");
                               break;
                        default:
                              printf( "选择错误\n");
                               break;
               }
        } while (i);
         return 0;
//注意点,n的赋值不能放到while循环中
goto语句    理论上goto语句不需要
C语言中提供了goto语句和标记跳转的符号   //goto语句使用多了极易出现bug
示例:  int  main()
            {
                again;
                    printf("hehe\n");
                    goto  again;
                return  0;
            }
执行结果:hehe死循环
在某些场合可以用上,如终止程序在某些深度嵌套的结构处理过程,例如跳出多层循环
示例:
for(……)
{
    for(……)
    {
        for(……)
        {
            if(disaster)//处理错误情况
                goto  error;
        }
    }
}
error;
一个关机程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
         char a[20];
        system( "shutdown -s -t 60");
        again:
        printf( "请输入牛逼,否则电脑将在60s内关机\n");
        scanf( "%s", a);
         if (strcmp(a, "牛逼\0")==0)
               system( "shutdown -a");
         else
                goto again;
         return 0;
}
//system()执行系统命令,声明头文件#include<stdio.h>
//应用—开始—搜索服务
//shutdown -s -t 60    在cmd中输入后回车,则60秒后关机
//-s设置关机,-t设置关机时间,60,60秒
//电脑   cmd   程序,command-命令行
//在输入shutdown -s -t 60后,如果要取消关机,则输入:shutdown -a 回车
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值