zoukankan      html  css  js  c++  java
  • linux高级编程day03 笔记

    一、make与makefile
      1.回顾:
        目标的语法
        目标名:依赖目标
          @命令
          @命令
          
        make的命令行使用
          make -f make脚本文件  目标名
      2.目标的划分
        目标依赖

      3.默认规则:
        a.不指定目标,执行第一个目标
        b.不指定make文件,默认文件是makefile Makefile
          makefile优先
      4.目标的调用规则:(make把目标当作文件)
        make执行目标:
          搜索与目标相同的文件
          如果文件存在,则判定日期。
          日期最新,则停止执行,输出提示
          日期不是最新,则进行执行。

          比较:当前目标与依赖目标
      5.建议:
        只要有文件输出,就把任务作为一个目标,并且把输出的文件作为目标名。
        
      6.潜规则(不建议)
        .c目标与.o目标。
        查找.o目标,目标不存在,就把.o替换成.c
        如果.c存在,实施潜规则:直接调用gcc把.c执为.o
      7.变量
        变量名=值 值
        
        $(变量名)  ${变量}  
      8.伪目标:
        不把目标作为文件处理的目标称为伪目标
        声明伪目标  
    没有:
      1.make的配置
      2.make的变量的操作函数
      3.多make文件使用

    二、环境变量
      1.使用main的参数
      int main(int args,char *argv[],char **arge)
      {
      }
      命令行参数argv与环境行arge都是字符串数组.
      约定:最后一个字符串是NULL/0
      2.在C的标准库提供:外部变量
       extern char **environ;

    View Code
    #include <stdio.h>
    #include <unistd.h>
    extern char **environ;
    int main(/*int args,char *argv[],char*arge[]*/)
    {
        /*
        while(*arge)
        {
            printf("%s\n",*arge);
            arge++;
        }
        */
        /*
        int i=0;
        while(arge[i])
        {
            printf("%s\n",arge[i]);
            i++;
        }
        */
        while(*environ)
        {
            printf("%s\n",*environ);
            environ++;
        }
    }

      3.修改获取某个环境变量
        getenv/setenv/unsetenv

    View Code
    #include <stdlib.h>
    #include <stdio.h>
    main()
    {
        char *val;
        val=getenv("PATH");
        printf("%s\n",val);
    }    

    三、IO的基础
      1.认识内核对象
        不允许访问内核设备和内存,但可以通过内核系统函数去访问.
        对每个内核对象进行编号ID.
        如果访问内核对象,只能通过ID.
        编程模型:
          申请得到一个ID
          在内核系统函数中使用ID得到对应内核对象数据
      2.怎么访问文件
        使用函数,传递一个文件,系统打开文件,加载文件数据,
        返回一个ID.
        使用函数,传递ID,得到数据.
        使用函数传递ID,告诉系统释放文件.
            
        ID:文件描述符号.file description (fd)
        
        每个程序执行的时候都有一个目录,存放打开的文件描述符号
      3.每个程序默认打开三个文件设备:
        0:标准输入
        1:标准输出
        2:错误输出
      4.操作文件描述符号
        ssize_t write(int fd,
         void *buf,//要写入内核对象的数据
         size_t size);//写入数据大小
        返回:
          >0 实际写入的数据
          -1 写入错误 
        ssize_t read(int fd,
          void *buf,//返回数据的空间
          size_t size);//空间大小
        返回:
          >0:实际读取的数据
          =0:碰到文件结束符号EOF (ctrl+d)
          -1:读取错误
        
        建议:
          0:输入
          1:输出
          2:错误输出
    课堂练习:
      1.使用write向0 1 2 写数据
      2.使用read从0 1 读取数据,并判定输入的情况,然后根据相应的结果输出提示

    View Code
    #include <stdlib.h>
    #include <stdio.h>
    main()
    {
        //printf("%d\n",getpid());
        //while(1);
        /*
        int r=write(0,"Hello\n",6);
        write(1,"world\n",6);
        write(2,"louis\n",6);
        int a=20;
        
        write(1,&a,4);
        */
        char buf[32];
        //memset(buf,0,32);
        bzero(buf,32);
        
        int r=read(0,buf,30);
        printf("实际输入:%d\n",r);
        if(r>0)
        {
            buf[r]=0;
            printf("::%s\n",buf);
        }
        if(r==0)
        {
            printf("ctrl+d\n");
        }
        if(r==-1)
        {
            printf("输入错误!\n");
        }
    }

    三.基于文件的描述符号
      1.得到文件描述符号/释放文件描述符号
       a.文件类型
        目录文件d
        普通文件f
        字符设备文件c
        块设备文件b
        软连接文件l
        管道文件p
        socket文件s   
       b.文件的属性
         1.属性的表达方式:绝对模式(0666类似的八进制数),字符模式(rwx)
           0    0   0    0
              拥有者   组   其他用户
           0666
         2.文件的权限属性:
           读
           写
           执行
           粘附位权限
           用户设置位权限
           组设置位权限
          0   0         0      0       0
            特殊权限   Owner  group  其他用户

           s:
           S
           t
           T
          2.1.  s设置位
              2:组设置位
              4:用户设置位
             s对执行有效
             无效的设置位使用S表示
             
             设置位向其他用户开放拥有者权限的权限.用户设置位
             设置位向其他用户开放组用户权限的权限.组用户设置位
             设置位只对执行程序有意义(执行权限有意义)
             
          2.2.  t设置位
              1:表示沾附位设置
              t对写文件有意义
             没有执行权限的沾附位使用T表示.
             沾附的目的:防止有些权限的用户删除文件.
          
          程序在执行的时候到底拥有的是执行者用户的权限
          还是文件拥有者的权限.
           程序执行中有两个用户:
              实际用户
              有效用户      
       总结:
         沾附位的作用: 防止其他有写权限用户删除文件
         设置位的作用: 向其他执行者开发组或者用户的权限.
    练习:
      1.使用cat创建一个文件
      2.设置沾附位,并观察属性
      3.设置用户设置位, 并观察属性
      4.设置组设置位, 并观察属性
      5.考虑w权限与沾附位的关系
      6.考虑x权限与设置位的关系.

      2.通过文件描述符号读写各种数据.      
        open函数与creat函数

                    int open(
                        const char *filename,//文件名
                        int flags,//open的方式[创建/打开]
                        mode_t mode//权限(只有创建的时候有效)
                        )

        返回:
          >=0:内核文件描述符号.
          =-1:打开/创建失败
      
        open的方式:
          必选方式:O_RDONLY O_WRONLY O_RDWR,必须选择一个
          创建/打开:O_CREAT
          可选方式:
              对打开可选方式:O_APPEND  O_TRUNC(清空数据)
              对创建可选方式:O_EXCL
         组合:
            创建:
              O_RDWR|O_CREAT
              O_RDWR|O_CREAT | O_EXCL 
            
            打开:          
              O_RDWR
              O_RDWR|O_APPEND
              O_RDWR|O_TRUNC
         权限:
           建议使用8进制数
        关闭
        void  close(int fd);           

    案例1:
      创建文件
    案例2:
      创建文件并写入数据
        20  short float
        tom  20   99.99
        bush  70   65.00
        达内  40   100.00
      注意:
        文件的创建的权限受系统的权限屏蔽的影响
        umask    //显示屏蔽权限.
        umask 0666  //设置权限屏蔽.  
        
        ulimit -a 显示所有的其他限制.

    View Code
    /*创建文件*/
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    main()
    {
        int fd;
        
        char name[20];
        short age;
        float score;
        char sex;
        
        fd=open("test.dat",
            O_RDWR|O_CREAT|O_EXCL,
            00666);
        if(fd==-1) printf("open error:%m\n"),exit(-1);
        
        
        //写第一条
        memcpy(name,"tom",strlen("tom")+1);
        age=20;
        score=99.99;
        sex='F';
        
        write(fd,name,sizeof(name));
        write(fd,&age,sizeof age);
        write(fd,&score,sizeof(float));
        write(fd,&sex,sizeof(sex));
        
        //写第二条
        memcpy(name,"Bush",strlen("Bush")+1);
        age=70;
        score=65.00;
        sex='M';
        write(fd,name,sizeof(name));
        write(fd,&age,sizeof age);
        write(fd,&score,sizeof(float));
        write(fd,&sex,sizeof(sex));
        
        //写第三条
        
        memcpy(name,"达内",strlen("达内")+1);
        age=10;
        score=99.00;
        sex='F';
        write(fd,name,sizeof(name));
        write(fd,&age,sizeof age);
        write(fd,&score,sizeof(float));
        write(fd,&sex,sizeof(sex));
            
        close(fd);
    }

    案例3:
      打开文件读取数据
      重点:
        怎么打开读取
        文件尾的判定
      
      基本类型的数据读写.

    View Code
    #include <fcntl.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    
    main()
    {
        char name[20];
        short age;
        float score;
        char sex;
        int fd;
        int r;
        fd=open("test.dat",O_RDONLY);
        if(fd==-1) printf("open error:%m\n"),exit(-1);
        
        while(1)
        {
            r=read(fd,name,sizeof(name));
            if(r==0) break;
            r=read(fd,&age,sizeof(short));
            r=read(fd,&score,sizeof(float));
            r=read(fd,&sex,sizeof(sex));
            printf("%s,\t%4hd,\t%.2f,\t%1c\n",
                    name,age,score,sex);
        }
        
        close(fd);
    }

    案例4:
      结构体读取
      描述:从键盘读取若干条数据,保存到文件
         数据追加

    View Code
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <string.h>
    struct stu
    {
        int no;
        char name[20];
        float score;
    };
    /*
    1.判定文件是否存在,存在打开,不存在创建
    2.输入记录
    3.保存记录
    4.提示继续输入
    5.继续/不继续
    6.关闭文件
    */
    int openfile(const char *filename)
    {
        int fd;
        fd=open(filename,O_RDWR|O_CREAT|O_EXCL,0666);
        if(fd==-1)//表示文件存在,则打开
        {
            fd=open(filename,O_RDWR|O_APPEND);
            return fd;
        }
        return fd;
    }
    void input(struct stu *record)
    {
        bzero(record,sizeof(struct stu));
        printf("输入学号:");
        scanf("%d",&(record->no));
        printf("输入姓名:");
        scanf("%s",record->name);
        printf("输入成绩:");
        scanf("%f",&(record->score));
    }
    void save(int fd,struct stu *record)
    {
        write(fd,record,sizeof(struct stu));
    }
    int iscontinue()
    {
        char c;
        printf("是否继续输入:\n");
        //fflush(stdin);
        //fflush(stdout);
        scanf("\n%c",&c);    
        if(c=='Y' || c=='y')
        {
            return 1;
        }
        return 0;
    }
    
    int main()
    {
        int fd;
        int r;
        struct stu s={0};
        fd=openfile("stu.dat");
        if(fd==-1) printf("openfile:%m\n"),exit(-1);
        
        while(1)
        {
            input(&s);
            save(fd,&s);
            r=iscontinue();
            if(r==0) break;
            system("clear");
        }
        close(fd);
        printf("输入完毕!\n");    
    }

      3.文件描述符号与重定向
         1.判定文件描述符号与终端的邦定关系
         int isatty(int fd)
         返回非0:fd输出终端
            0:fd输出被重定向
         2.防止重定向
           /dev/tty

    View Code
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        int fd;
        printf("Hello\n");
        write(1,"World\n",6);
        fd=open("/dev/tty",O_WRONLY);
        if(isatty(1))
        {
            write(1,"notredir\n",9);
        }
        else
        {
            write(1,"redir\n",6);
        }
        write(fd,"Killer\n",7);
    }    

    总结:
      1.make的多目标依赖规则以及伪目标
      2.文件的创建与打开(了解设置位的作用)
      3.文件的读写(字符串/基本类型/结构体)
      4.了解描述符号与重定向

    作业:
      1.完成上课的练习.
      2.写一个程序使用结构体读取1种的数据,
         并全部打印数据,
         并打印平均成绩
      3.写一个程序:
        查询1种的数据.比如:输入姓名,查询成绩
      4.写一个程序,录入保存如下数据:
        书名  出版社  价格  存储量  作者  
      5.写一个程序负责文件拷贝
        main 存在的文件  新的文件名
        要求:
          文件存在就拷贝,不存在提示错误.

  • 相关阅读:
    centos 7 安装vsftpd
    Goland 使用插件一键发布Docker到线上centos服务器
    Docker alpine 添加bash+修改时区发布镜像到docker.io
    centos 7 nginx 配置Let's Encrypt证书,并自动更新
    centos 7 源码方式安装nginx(1.16.1) + ssl + 阿里证书配置
    centos nginx 卸载
    influxdb time duration literal
    阿里云标准-Redis安全基线检查
    配置systemctl(zookeeper、hadoop、redis)
    【转】Hadoop2.7.7 API: yarn-site.xml 解析
  • 原文地址:https://www.cnblogs.com/tangzhengyue/p/2648849.html
Copyright © 2011-2022 走看看