“There’s always more to learn, and there are always better ways to do what you’ve done before.”

(Donald Ervin Knuth ,现代计算机科学的鼻祖, 经典巨著《计算机程序设计的艺术》的作者)

语句

语句是构成程序的基本元素。对应着一条或者多条机器指令。

定义一个变量

int a = 100 ;

声明一个变量

extern int a ;

调用printf函数

printf("hello world");

这些形式的语句都是简单语句。简单语句形式比较简洁,都以;结尾。
除了简单语句在C语言中还提供了一些形式固定的语句,复合语句。

条件分支语句

  • if
if(条件表达式)
{
    // 如果条件为真,就执行该代码块
}

练习-验证用户密码是否正确,伪代码演示。

  • if else
if( 条件 )
{
    // 代码块1; //条件为真,执行代码块1
}
else
{
    // 代码块2; //条件为假,执行代码块2
}
  • if-else if
if(条件1)
{
   // 代码块1;
}
else if(条件2)
{
   // 代码块2;
}
else if(条件3)
{
   // 代码块3;
}
else
{
   // 默认代码块;
}

哪个条件成立就执行对应的代码块,如果所有的条件都不成立,就执行else代码块中的代码。
注意:在多分支if语句里,else总是和上面最近的那个if配对。

switch分支语句

与break,default

  • switch语句的使用
switch(量)
{
    case1:
        // 代码块1
        break;
    case2:
        // 代码块2
        break;
    case3:
        // 代码块3
        break;
    default:
        // 所有case都不满足,就执行该代码块。
}

解释:如果量的值和case后面的值相等,就执行相应的语句,break跳出switch语句。
如果所有的case都不匹配,就执行default语句。

break如果省略之后会发生非常有趣的现象。

case穿透

每个case语句之后如果没有break语句就会产生case穿透。
没有break如果是非故意的那就会造成BUG。

练习- 输入月份 输出该月份对应的季节(春345 夏678 秋91011 冬1212)

关联性的if语句和switch语句的联系

如果判断条件是整数类型常数值类型的时候 switch和if都可以使用
switch语句显得更加简洁

#include <stdio.h>
int main(void)
{
    int num = 0;
    scanf("%d",num);
    int num = num % 3;

    if ( num == 0 )
    {
        printf("余数是0\n");
    }else if( num == 1)
    {
        printf("余数是1\n");
    }else
    {
        printf("余数是2\n");
    }
    return 0;
}

使用switch语句实现一样的功能应该是这样的形式

#include <stdio.h>
int main(void)
{
    int num = 0;
    scanf("%d",num);
    int num = num % 2;
    switch( num )
    {
        case 0:
            printf("余数是0\n");
            break;
        case 1:
            printf("余数是1\n");
            break;
        default:
            printf("余数是2\n");
            break;
    }
    return 0;
}

如果判断条件中是非整数类型(浮点数、表达式)时必须使用if语句。

条件运算符

  • 格式 (条件) ? 值1 : 值2 ; 当条件成立(逻辑成立)时,表达式的值为值1,否则,表达式的值为值2.

goto语句与标号

执行原理:当执行到goto语句,CPU就会跳转到标签的地方执行代码。

重要的事情说三遍

int main()
{
    int i = 0;
    loop:
        i++;
        printf("你个猴子!\n");
        if(i == 3)
        {
            goto end;
        }
        goto loop;
    end:  
        printf("重要的事情说三遍,不再说你是猴子\n"); 

    return 0;
}

注意:

1、标签名随意,但是要符合标识符的命名规则和规范。

2、标签名可以往前跳,也可以往后跳。

3、只能在当前函数中跳。

4、标签名下面的那一句代码不能声明变量。

5、如果使用goto能够简化代码,就可以使用,其他情况下,不建议使用。

代码风格

google C/C++编码风格部分

国际C语言混乱代码大赛(IOCCC)

#include <stdio.h>
#define _$()                                         0
#define __$()                                        1
#define _$_()                                        10
#define $_$(a)                                       a;
#define $_(b,a)                                     a##b
#define r(a,b)                                  r##a##b##urn 0;
#define m(b,a,x) };                               m##a##b##n
#define $(b,a,x)                                  a##b##x
#define                                         ____ + __
#define $_$_                                         =
#define __(...)  (                              $(n,i,t))(\
$(ze,si,of)(($(n,i,t)[]) { _$(), ##__VA_ARGS__})/$(ze,si,of) ($(n,i,t))-__$())
$(n,i,t)  (*___)   ($(n,i,t))  = $(tch,  pu,  ar);   $(ub,do,le) _<::> $_$_ <%
-2, 1, -1.3, 1.3     /* <-- Configure here: X1, X2, Y1, Y2 */
,_$(), _$(),_$(),_$(),_$() ,_$(), __( ',',',',',' ,',' ,',')  * _$_() ,( _$_()
- __('_','_')) * _$_(), _$(),_$(),_$(),__('_','_')*__('_','_', '_','_', '_') *
__('_','_', '_','_', '_')*__('_','_', '_','_', '_')+__('_','_', '_','_' , '_')
,__('_','_','_','_','_','_','_','_',), _$() m(i,a,u)($(n,i,t) $_)<% $_ (f,i) (
$_ $_(=,=) __(_) ) $_$($_(f,i)(_[ _$_()____(_,_) ]>_[ _$_()] )_[_$_()____ (_,_
,_,_,_,_,_)] $_$_ __(_) )$_(f,i)(_[_$_()____(_ ,_ ,_)] >_[  _$_()+ __$() ]  ||
_[_$_()____(_,_,_,_,_,_,_)] $_ (=,=) __$()) r(e,t) _[__(_,_,_ ,_,_ ,_)] $_$_ _
[__ (_,_,_,_,_,_,_)____(_,_,_,_,_,_) ]/_[__(_,_,_,_,_) ____(_,_,_,_,_,_)]*( _[
  __$()]-_[_$()])+_[ _$() ];_[__(_,_,_,_,_,_,_)] $_$_ _[__(_,_,_,_,_,_,_) ____
(_,_,_,_,_)]/_[_$_()]*(_[__(_,_,_,)]-_[__(_,_,)] )+_[__(_,_,)];_[__(_,_,_,_, _
,_,_,_)] $_$_ _[_$_() - __$()] $_$_ _[__(_,_,_,_,_)+ _$_()-__$()]  $_$_  _$();
_f:_[__(_,_,_,_)]  $_$_  _[__( _,_,_,_, _,_,_, _)] * _ [__(_,_,_, _,_,_,_,_)];
_[__(_,_,_,_,_)] $_$_ _[_$_() - __$()]*_[_$_() - __$()];_[__(_,_,_,_,_,_,_,_,_
)] $_$_ __(_,_)*_[__(_,_,_,_,_,_,_,_)]*_[_$_() -__$()]+ _[__ (_,_,_,_,_,_,_)];
_[__(_,_,_,_,_,_,_,_)] $_$_ _ [ __(_,_,_,_) ]-_[__(_,_,_,_,_)]+_[__(_,_,_,_,_,
_)];$_$(_[_$_()____(_,_,_,_,)]++)$_(f,i)((_ [_$_() ____ (_,_,_,_,)]< _ [_$_ ()
____ (_,_,_,_,_)])&&(_[__(_,_,_,_)]+ _[__(_,_,_,_,_)]<_[_$_()____(_,_,_,_,_,_)
])) $_(to,go) _f; $_(ar,ch) $(m,i,au)[] $_$_ <% __(_,_,_) * _$_()____(_,_), __
(_,_,_,_) * _$_()____(_,_,_),__(_,_,_,_,_,_) * _$_()____(_,_,_,_), __(_,_,_,_)
*_$_() ____(_,_,_,_,_),__(_,_,_,_) * _$_() ____(_,_,_,_,_,_),__(_,_,_,_) * _$_
()____(_,_) %>;___($(m,i,au)[($(n,i,t)) _[_$_()____(_,_,_,_)]%__(_,_,_,_,_)]);
$_$(_[__(_,_ ,_,_ ,_,_,_) + __(_,_,_,_,_,_)]++){m(i,a,u) ( _$()) ;$_$ (_[_$_()
____(_,_)]++)$_$(_[_$_()____(_,_,_)] $_$_ _$()) $_(f,i)(_ [__(_,_,_,_,_,_,_) + 
_$_()] != __(_)) ___(_$_()) ;{  m(i,a,u)(__$()); r(e,t)    /* IOCCC 2014*/  %>

是不是很眼熟 ????

案例

求自然数之和

用户输入任意一个整数n,求:从1到n之间所有自然数之和。
比如:用户输入10, 那么就计算 1+2+3+4+5+6+7+8+9+10 = ?

参考答案:

int main(void)
{
    int n;
    printf("请输入一个整数:");
    scanf("%d", &n);
    int sum = 0; // 保存自然数之和
    int i=0;
    while(i<=n)
    {
        sum += i;
        i++;
    }   
    printf("1~%d之间的自然数之和为:%d\n", n, sum);   
    return 0;
}

求整数的位数

任意输入一个整数,假设用户输入了123,程序运行输出"百
如果用户输入了2896,程序输出 千
10000,输出万 10000

参考答案:

int main(void)
{
    int count = 0; // 计数器
    printf("请输入一个整数:");
    int a;
    scanf("%d", &a);
    while (a > 0)
    {
        count++;
        a /= 10;
    }
    switch(count)
    {
        case 1:
            printf("个\n");
            break;
        case 2:
            printf("十\n");
            break;
        case 3:
            printf("百\n");
            break;
        case 4:
            printf("千\n");
            break;
        case 5:
            printf("万\n");
            break;
        case 6:
            printf("十万\n");
            break;
    }
    return 0;
}

求水仙花数

求100到999之间所有的水仙花数

水仙花数是什么?
一个数百位的立方 + 十位的立方 + 个位的立方 = 这个数本身
371就是一个水仙花数
3 3 3 + 7 7 7 + 1 1 1 = 371

参考答案

int main(void)
{  
    int i;
    for (i=100; i < 1000; i++)
    {
        int bai = i / 100;
        int shi = i % 100 / 10;
        int ge = i % 10;
        int res = bai*bai*bai + shi*shi*shi + ge*ge*ge;
        if (res == i)
        {
            printf("%d是水仙花数!\n", i);
        }
    }
    return 0;
}

等腰三角形

在屏幕输出一个等腰三角形

  *
 ***
*****

要求:不能用printf一行一行打印输出等腰三角形

printf\("      _\n"\);  
printf\("     \*\*_\n"\);  
printf\("    **\***\n"\);

参考答案:

// 输出等腰三角形
int main(void)
{
    printf("请输入等腰三角形的行数(大于等于3): \n");
    int hangshu;
    scanf("%d", &hangshu);
    if (hangshu < 3)
    {
        printf("行数要求大于等于3!\n");
        return 10;
    }
    for (int i = 1; i <= hangshu; ++i) // 一共打印多少行
    {
        for (int j = 0; j < hangshu-i; ++j) // 当前行要打印多少空格
        {
            printf(" ");
        }
        for (int k = 0; k < 2*i-1; ++k) // 当前行要打印多少*
        {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

练习

  1. 打印1个5*5的棋盘(0表示空,1表示有子),用户输入1个位置(例如 2 3),重新打印棋盘。
    input:3
    output:
    000
    000
    000
    input location:2 3
    output:
    000
    001
    000
  1. 一个数各个约数(真约数)的和等于它本身的自然数叫做完全数(Perfect number)。
    (例如:6 = 1 + 2 + 3) 请找出1-1000以内的完全数。

  2. 一个 n 位数 ( n≥3 ) 每个位上的数字的 n 次幂之和等于它本身的数叫做水仙花数。
    (例如:1^3 + 5^3 + 3^3 = 153) 请找出 n = 3 的水仙花数。

  3. 打印一个数字(位数可能为1-10,不确定)的个位,十位,百位... 直到最高位。

    input:123456 output:654321 input:2101211024 output:4201121021

  4. 猜数字游戏。
    由计算机使用 rand() 函数产生一个数字,然后由用户B来猜这个数字,B输入猜的数字之后,程序告诉用户B是大还是小,直到最后用户B猜对为止。
    output: gernate random number sucessful.please gucess it. input: 12 output: < input: 100 output: > input: 55 output: = !!!!! good guys。

  5. 求出1-10000之间最大的素数。
    素数即质数,除了1和本身之外没有其他的约数,否则就不是质数。

  6. 使用while、do-while、for、goto求出1-n(1<=n<=10)的阶乘。 n从键盘输入。

  1. 从屏幕上输入5个学生的C语言测试成绩,打印出5个人成绩的平均分和每个人的分数。 input:99 66 88 55 59 output:avg score is:367 every one's score is:99 66 88 55 59
  2. 编写代码求出给定的整数中bit位从最高位上连续为1的位数 比如输入127的二进制是0111 1111 输出0 比如输入240的二进制是1111 0000 输出4 int main() { int number = 0; scanf("%d",&number); int weight= 128; int count = 0; for(int i =0 ;i< 8;++i) {

      if(number / weight == 1)
          count++;
      else
          break;
      number -= weight;
      weight /= 2;
    

    } printf("%d\n",count);

    return 0; }