2.懵懵懂懂的第一章和第三章

本文介绍了UNIX环境下编程的基础概念和技术,包括目录操作、进程控制、文件描述符管理等关键内容。通过具体示例展示了如何使用opendir、readdir进行目录读取,如何通过fork和execlp实现进程创建及执行,以及open、close、lseek等文件操作函数的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  刚刚开始看unix高级环境编程,看了一天,好像什么都懂,但是更像什么都不懂,先记一记,说不定下次再看的时候,会有新的感悟。

  1.目录的一些操作

     opendir,返回一个DIR结构的指针,将指针传入readdir函数,会读取里面的目录,直到里面的目录都被读取完。

#include "apue.h"
#include <dirent.h>

int main(int argc, char *argv[])
{
        DIR             *dp;
        struct dirent   *dirp;
        if(argc != 2)
                err_quit("usage: ls directory_name");
        if((dp = opendir(argv[1])) == NULL)
                err_sys("can't open %s", argv[1]);
        while((dirp = readdir(dp)) != NULL)
                printf("%s\n", dirp->d_name);

        closedir(dp);
        exit(0);
}
  2.进程控制

  主要是execlp在执行,另外父进程采用fork()创建子进程,fork对父进程返回新的子进程的进程ID,对子进程则返回0

#include "apue.h"
#include <sys/wait.h>

static void sig_int(int);

int main(void)
{
        char buf[MAXLINE];
        pid_t pid;
        int status;

        if(signal(SIGINT, sig_int) == SIG_ERR)
                err_sys("signal error");

        printf("%% ");
        while(fgets(buf, MAXLINE, stdin) != NULL){
                if(buf[strlen(buf) - 1] == '\n')
                   buf[strlen(buf) - 1] = 0;
                if((pid = fork()) < 0){
                   err_sys("fork error");
                } else if(pid == 0){
                   execlp(buf, buf, (char *)0);
                   err_ret("couldn't execute: %s", buf);
                   exit(127);
                }

                if((pid = waitpid(pid, &status, 0)) < 0)
                   err_sys("waitpid error");
                printf("%% ");
        }
        exit(0);
}

void sig_int(int signo)
{
        printf("interrupt\n%% ");
}

 

  3. 文件描述符。

    0代表与标准输入关联,1代表与标准输出关联,2代表与标准错误关联。

 

 4.open函数

    主要有一系列的参数,例如O_RDONLY,O_WRONLY,O_RDWR等等。用它可以替代creat

 

 5.close函数

    int close(int fd); //fd代表文件标识符,成功返回0,出错返回-1。

 

 6.lseek函数

    off_t lseek(int fd, off_t offset, int whence); //成功返回文件的偏移量,失败返回-1

    whence = SEEK_SET,则将该文件的偏移量设置为距文件开头offset个字节。

    whence = SEEK_CUR,则将该文件的偏移量设置为其当前值加offset,offset可为正或负

    whence = SEEK_END,则将该文件的偏移量设置为文件长度加上offset,offset可为正或负


  7.当文件偏移量大于文件的长度时,会形成文件空洞用0填充


  8.read函数

    ssize_t read(int fd, void *buf, size_t nbytes);  //返回值:读到的字节数,如果已到文件尾,返回0;若出错,返回-1

    从终端设备读,通常一次最多读一行。

  

  9.write函数

    ssize_t write(int fd, char *buf, unsigned nbytes);  //若成功,返回已写的字节数,如出错返回-1。


  10.原子操作。 多步操作组合成的一个操作,要么不执行,要么执行完。


  11.dup,dup2。

    更改设置文件标志符。

    int dup(int fd); //返回当前文件描述符中的最小数值

    int dup2(int fd, int fd2); //类似与fd = fd2,并且关闭fd2


  12. sync, fsync, fdatasync.

      sync只是将修改过的块缓冲区排入写队列,就返回,不等待实际写磁盘操作结束。

      fsync只对一个文件起作用,并且要等待磁盘操作结束后再返回。

      fdatasync只影响数据部分。

      原型:void sync(void),int fsync(int fd),int fdatasync(int fd);


  13.fcntl函数(改变打开文件的属性)

      int fcntl(int fd, int cmd, .....);

      主要是一系列的命令参数,比如F_GETFD,F_SETFD,F_GETFL,F_SETFL。

#include "apue.h"
#include <fcntl.h>

int main(int argc, char *argv[])
{
        int val;
        if(argc != 2)
                err_quit("usage: a.out <descriptor#>");
        if((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)
                err_sys("fcntl error for fd %d", atoi(argv[1]));
        switch(val & O_ACCMODE){
        case O_RDONLY:
                printf("read only");
                break;
        case O_WRONLY:
                printf("write only");
                break;
        case O_RDWR:
                printf("read write");
                break;
        default:
                err_dump("unknown access mode");
        }
        if(val & O_APPEND)
                printf(", append");
        if(val & O_NONBLOCK)
                printf(", nonblocking");
        if(val & O_SYNC)
                printf(", synchronous writes");

#if !defined(_POSIX_X_SOURCE) && defined (O_FSYNC) && (O_FSYNC != O_SYNC)
        if(val & O_FSYNC)
                printf(", sychronous writes");
#endif

        putchar('\n');
        exit(0);
}

  14.函数ioctl和/dev/fd  还不是太理解。

资源下载链接为: https://pan.quark.cn/s/9e7ef05254f8 行列式是线性代数的核心概念,在求解线性方程组、分析矩阵特性以及几何计算中都极为关键。本教程将讲解如何用C++实现行列式的计算,重点在于如何输出分数形式的结果。 行列式定义如下:对于n阶方阵A=(a_ij),其行列式由主对角线元素的乘积,按行或列的奇偶性赋予正负号后求得到,记作det(A)。例如,2×2矩阵的行列式为det(A)=a11×a22-a12×a21,而更高阶矩阵的行列式可通过Laplace展开或Sarrus规则递归计算。 在C++中实现行列式计算时,首先需定义矩阵类或结构体,用二维数组存储矩阵元素,并实现初始化、加法、乘法、转置等操作。为支持分数形式输出,需引入分数类,包含分子分母两个整数,并提供与整数、浮点数的转换以及加、减、乘、除等运算。C++中可借助std::pair表示分数,或自定义结构体并重载运算符。 计算行列式的函数实现上,3×3及以下矩阵可直接按定义计算,更大矩阵可采用Laplace展开或高斯 - 约旦消元法。Laplace展开是沿某行或列展开,将矩阵分解为多个小矩阵的行列式乘积,再递归计算。在处理分数输出时,需注意避免无限循环除零错误,如在分数运算前先约简,确保分子分母互质,且所有计算基于整数进行,最后再转为浮点数,以避免浮点数误差。 为提升代码可读性可维护性,建议采用面向对象编程,将矩阵类分数类封装,每个类有明确功能接口,便于后续扩展如矩阵求逆、计算特征值等功能。 总结C++实现行列式计算的关键步骤:一是定义矩阵类分数类;二是实现矩阵基本操作;三是设计行列式计算函数;四是用分数类处理精确计算;五是编写测试用例验证程序正确性。通过这些步骤,可构建一个高效准确的行列式计算程序,支持分数形式计算,为C++编程线性代数应用奠定基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值