Press "Enter" to skip to content

Month: July 2017

C语言概述

程序(program)由一个或多个函数组成,其中必须有一个名为main()的函数。函数的描述由函数头和函数体组成。函数头(header)包括预处理语句和函数名。可通过圆括号识别一个函数名,圆括号内部可以为空。而函数体(body)位于花括号中并有一系列语句组成,每个语句以一个分号结束。


/*一个简单的C程序*/
#include<stdio.h>
/*
 * 预处理器命令,头文件(header)。
 * 头文件包括了建立最终的可执行程序市编译器需要的信息。
 * 但函数实际代码被包含在库文件中,而不是头文件。
 * 编译器的链接部分负责找到您需要的库代码。
*/

int main(void)
/*
 * 调用main函数,并不接受参数,int表示main()函数返回一个整数。
 * main()是必须开始的函数,是C的基本模块。
 * int指明了函数的返回类型。
 * C90允许使用main(),但C99不允许。建议使用main(void).
 */
 {
//花括号划定了main()函数的界限。
    int num;
    /* 定义一个名为num的变量。这一行叫做声明语句。
     * 说明函数中有一个叫做num的参数,该参数为整数类型。
     * int是C语言的关键字。
     * 在C语言中,所有变量都必须在使用之前定义。
     * 变量命名可供使用的字符有大小写字母、数字和下划线。
     * 第一个字符必须是字母或者下划线。
     * C语言区分大小写。*/
    num = 1;        /*为num赋值,赋值是C的基本操作之一*/

    printf("I am a simple ");   /*调用printf()函数*/
    printf("computer.\n");      /*再次调用printf()函数*/
    printf("My favorite number is %d because it is first.\n",num);
    /* 把num的值给printf()附参,并打印输出,%d表示输出值的位置和形式。
     * printf()是C语言的一个标准函数。圆括号表明printf是一个函数名。
     * 圆括号中的内容是从main函数传递到printf函数的信息,它被成为参数。*/
    return 0;   /*返回语句*/
    /* 返回语句是程序的最后一个语句。int main(void)要求返回一个整数值,
     * 则由return函数返回一个整数值0表示程序的结束。
}   /*结束*/

让程序具有可读性是一个良好的编程习惯。
常用的技巧有:
+ 选择有意义的变量名和使用注释;
+ 使用空行来分隔一个函数概念上多个部分;
+ 每个语句用一行;
+ 程序在开始处用一个注释说明文件的名称和程序的目的;
+ 多个声明


// two_func.c 在一个文件中使用两个函数
#include<stdio.h>
void butler (void);
/* 通知编译器要用到该函数.原型是一种声明的形式,用于告诉编译器使用自定义的函数。
 * butler函数第一个void说明butler()不返回值。
 * 第二个void说明没有参数。
 * void表明是空的,而非无效的。 */
int main(void){
        printf("I will summon the butler function.\n");
        butler();   /*调用函数*/
        printf("Yes. Bring me some tea and writeable CD-ROMS.\n");
        return 0;       
}

void butler(void){  /*函数定义*/
    printf("You rang, sir?\n"); //注意不需要return()函数返回值
}

一门语言的语法就是一套规则,用于管理这种语言中的合法语句组织在一起的方式。语句的语义就是它所表达的意思。编译器可以帮助您发现语法上的错误,但是程序里的语义错误只有在编译完之后才能从程序的行为中表现出来。检测语义错误可能包括跟踪程序的状态,即程序每执行一步之后所有变量的值。

关键字是C语言的词汇。

通过手工方式一步一步的跟踪程序,并记录每个变量,这样就可以监视程序状态。程序状态(program state)是指程序执行过程中的给定点上所有变量值的集合。它是当前计算状态的一个快照。
跟踪程序状态的方法有:
1. 逐步执行程序;
2. 在程序的关键点处加入printf()语句以监视所选变量的值。通过观察变量值的变化来了解程序的执行情况;
3. 使用调试器。调试器是一种程序,它可以一步一步运行另一个程序并检查程序的变量值。


推箱子游戏

使用C来实现一个简单的推箱子游戏..

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
int main(){
    char a[50][50]={
    "   ###     ",
    "   #*#     ",
    "   # #     ",
    "####O######",
    "#*  OS O *#",
    "#####O#####",
    "    # #    ",
    "    #*#    ",
    "    ###    ",
    };

    int i,f=0; //控制变量 
    int x=4,y=5; //控制点坐标 

    char ch; //定义控制输入端

    //打印输出地图
    for(i=0;i<12;i++){
        puts(a[i]);
    }
    puts("游戏尚未开始,请按键……");

    //f标记值0.1.2.3共计4次循环 
    while(f<4)//开始循环
    {
        ch=getch();

        if(ch=='s') //按下s键
        { 
            if(a[x+1][y]!='#'&&a[x+1][y]!='@')//未碰墙未达目的地 
            {
                if(a[x+1][y]!='O') //前面没有O的时候 
                {
                    a[x][y]=' ';    //现坐标为空 
                    x++;            //x坐标向下移动一位 
                    a[x][y]='S';    //新坐标标记为S 
                }
                else    //前面有O标记时 
                {
                    if(a[x+2][y]!='#')  //前面两坐标有墙 
                    {
                        if(a[x+2][y]!='*')  //O前面没有目的地时 
                        {
                            a[x][y]=' ';    //现坐标为空     
                            x++;            //x坐标向下移动 
                            a[x][y]='S';    //新坐标标记为S 
                            a[x+1][y]='O';  //前面一个坐标为O 
                        }
                        else    //O前面有目的地坐标时 
                        {
                            a[x][y]=' ';    //现坐标为空 
                            x++;            //x坐标向下移动 
                            a[x][y]='S';    //新坐标标记为S 
                            a[x+1][y]='@';  //目的地坐标改为@ 
                            f=f+1;          //f标记值增加1 
                        }
                    }
                }
            }
        }

        if(ch=='w') //按下w键
        { 
            if(a[x-1][y]!='#'&&a[x-1][y]!='@')
            {
                if(a[x-1][y]!='O') 
                {
                    a[x][y]=' ';
                    x--;
                    a[x][y]='S';
                }
                else
                {
                    if(a[x-2][y]!='#')
                    {
                        if(a[x-2][y]!='*')
                        {
                            a[x][y]=' ';                            
                            x--;
                            a[x][y]='S';
                            a[x-1][y]='O';
                        }
                        else
                        {
                            a[x][y]=' ';
                            x--;
                            a[x][y]='S';
                            a[x-1][y]='@';
                            f=f+1;
                        }
                    }
                }
            }
        }

        if(ch=='d') //按下d键
        { 
            if(a[x][y+1]!='#'&&a[x][y+1]!='@')
            {
                if(a[x][y+1]!='O') 
                {
                    a[x][y]=' ';
                    y++;
                    a[x][y]='S';
                }
                else
                {
                    if(a[x][y+2]!='#')
                    {
                        if(a[x][y+2]!='*')
                        {
                            a[x][y]=' ';                            
                            y++;
                            a[x][y]='S';
                            a[x][y+1]='O';
                        }
                        else
                        {
                            a[x][y]=' ';
                            y++;
                            a[x][y]='S';
                            a[x][y+1]='@';
                            f=f+1;
                        }
                    }
                }
            }
        }

        if(ch=='a') //按下a键
        { 
            if(a[x][y-1]!='#'&&a[x][y-1]!='@')
            {
                if(a[x][y-1]!='O') 
                {
                    a[x][y]=' ';
                    y--;
                    a[x][y]='S';
                }
                else
                {
                    if(a[x][y-2]!='#')
                    {
                        if(a[x][y-2]!='*')
                        {
                            a[x][y]=' ';                            
                            y--;
                            a[x][y]='S';
                            a[x][y-1]='O';
                        }
                        else
                        {
                            a[x][y]=' ';
                            y--;
                            a[x][y]='S';
                            a[x][y-1]='@';
                            f=f+1;
                        }
                    }
                }
            }
        }

    system("cls"); //清屏
    for(i=0;i<12;i++)
        {
        //输出变量变更之后的地图 
        puts(a[i]);
        }
    printf("\n已达成:%d 颗星。",f);
    }


    Sleep(500);  
    system("cls"); //清屏
    puts("恭喜,你赢了!");
    return 0;
} 

Shell的循环与函数函数

循环结构


for循环

语法结构以及特点

for 变量名 in 值列表
do
    命令序列
done

for循环的执行流程

脚本应用示例

C语言风格的for循环 cfor.sh

#!/bin/bash
for ((i=1;i<=5;i+=2))
do
    echo $i
done

chkhosts.sh
批量检测多个主机的存活状态:
1. 多个目标IP地址,存放在ipadds.txt;
2. ping检测;
3. 脚本遍历主机,并反馈存活状态;

#!/bin/bash
HLIST=$(cat ./ipadds.txt)
for IP in $HLIST
do
        ping -c 3 -i 0.2 -W 3 $IP &>/dev/null
        if [ $? -eq 0 ] ;then
                echo "Host $IP is up."
        else
                echo "Host $IP is down."
        fi
done

while循环

语法结构以及特点

while 条件测试
do
    命令序列
done

while循环的执行流程

脚本应用示例

检测192.168.4.0/24网段,列出不在线的主机地址
whilechkhosts.sh

#!/bin/bash
PREFIX="192.168.4." ; i=0
while [ $i -le 255 ]
do
        IP=${PREFIX}$i
        ping -c 3 -i 0.2 -W 3 $IP &>/dev/null
        if [ $? -eq 0 ];then
                echo "Host $IP  is up."
        else
                echo "Host $IP is down."
        fi
        let i++
done

服务脚本设计

case分支结构

语法结构以及特点

case 变量值 in
模式1)
    命令序列1 ;;
模式2)
    命令序列2 ;;
 .......
*)
    默认命令序列 ;;
esac

case分支的执行流程

脚本应用示例

判断用户输入键位类型
hitkey.sh

#!/bin/bash
read -p "请输入一个字符: " KEY
case "$KEY" in
        [a-z]|[A-Z])
                echo "字母。 " ;;
        [0-9])
                echo "数字。 " ;;
        *)
                echo "空格、功能键或者其他控制字符。"
        esac

编写服务脚本

系统服务控制

  • 查看服务列表、自启状态 chkconfig
  • 服务控制 service、/etc/init.d/服务名

服务脚本的case分支用法

自建系统服务

?????


函数以及中断控制

shell函数

关于函数的认识

  • 将一些需要重复使用的操作定义为公共的语句块,即可成为函数;
  • 使脚本代码简洁、增强易读性;
  • 提高效率

函数的定义与调用

function 函数名{
    命令序列
    ......
}

  • 调用已定义的函数
  • 函数传值

函数应用示例

针对给定两个整数,依次负责加减乘除结果并输出。
funexpr.sh

#!/bin/bash
myexpr(){
        echo "$1 + $2 = $[$1 + $2]"
        echo "$1 - $2 = $[$1 - $2]"
        echo "$1 * $2 = $[$1 * $2]"
        echo "$1 / $2 = $[$1 / $2]"
}
myexpr $1 $2

中断以及退出

中断/退出以及相关指令

  • 中断 break
  • 继续 continue
  • 退出 exit

脚本中断示例

脚本退出示例

Shell运算与if结构

整数运算


基本运算类别

  • 四则运算;
  • 取余运算;

expr运算工具

计算指定的表达式,并输出

$[]算式替换

  • 使用$[] $(())
  • 引用变量可省略$
  • 计算结果替换表达式本身,echo输出

变量的自增、自减

  • let命令
  • 使用$(());

小数运算

整数运算的局限性

shell默认不支持小数运算

使用bc实现小数运算

  • bc
  • scale=n 约束小数位

小数值的比较

  • 管道
  • echo输出

条件测试

测试操作概述

脚本智能化

  • 脚本识别能力;
  • 识别依据;

测试操作

常见测试操作

整数值比较

  • -eq 等于 equl
  • -ne 不等于 Not equl
  • -ge 大于或者等于 Great or Equal
  • -le 小于或者等于 Lesser or Equal
  • -gt 大于 Greater Than
  • -lt 小于 Lesser Than

字符串比较

[ $(who|wc -l) -le 5 ] && echo "OK"
tips:
+ []外部前后不需要空格、内部前后需要空格;
+ echo后需要空格

文件状态测试

  • -e 对象是否存在
  • -d 是否为目录
  • -f 是否为一般文件
  • -r 是否有可读权限
  • -w 是否有可写权限
  • -x 是否有可执行权限

组合多个条件

逻辑分隔操作

  • && 逻辑与,给定条件必须全为真,否则结果为假;
  • || 逻辑或,给定条件只要有一个为真,则结果为真

条件组合应用

if选择结构


单分支结构

语法格式以及特点

if 条件测试
    then 命令序列
fi

if单分支的执行流程

脚本应用示例

shell
#!/bin/bash
mount_dir="/media/cdrom"
if[ !-d $mount_dir ];then
    mkdir -p $mount_dir
fi

双分支结构

语法格式以及特点

fi 条件测试
   then 命令序列1
    else 命令序列2
fi

if双分支的执行流程

脚本应用示例

#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &>/dev/null
if[ $? -eq 0 ];then
    echo "Host $1 is up."
else
    echo "Host $1 is down."
fi

多分支结构

语法格式以及特点

if 条件测试
    then 命令序列1
elif 条件测试2
    then 命令序列2
    else 命令序列n
fi

if多分支的执行流程

脚本应用示例

示例:gradediv.sh

#!/bin/bash
read -p "请输入分数(0~100): " FS
if [ $FS -ge 85 ] && [ $FS -le 100 ];then
    ehco "$FS 分,优秀!"
elif [ $FS -ge 70 ] && [ $FS -le 84 ];then
    echo "$FS 分,合格!"
else
    echo "$FS 分,不合格!"
fi