Linux:文件管理(一)——文件描述符fd
目录
一、文件基础认识
二、C语言操作文件的接口
1.> 和 >>
2.理解“当前路径”
三、相关系统调用
1.open
2.文件描述符
3.一切皆文件
4.再次理解重定向
一、文件基础认识
- 文件 = 内容 + 属性。换句话说,如果在电脑上新建了一个空白文档,它虽然没有内容,但也是占据磁盘空间的。
- 想要修改一个文件的内容,比如用WPS这样的软件操作文件内容,本质上都需要CPU完成相关的指令,而CPU又只与内存交互,所以,打开文件的含义其实就是把文件加载到内存中。
- 在我们眼里,我们双击了一个文件就是打开了文件,但是在操作系统看来,并不是我们打开了文件,而是某一个正在运行的进程,文件是由进程打开的。
- 一个进程可以打开多个文件。
- 操作系统管理多个被打开文件,必然也会像操作系统管理多个进程一样,利用面向对象和数据结构,因此,内核中必然定义了结构体来描述被打开的文件。
- 从操作系统管理文件的角度看,文件被区分为被打开的文件(在内存中)和没有打开的文件(在磁盘中)。
二、C语言操作文件的接口
fopen以"w"方法打开一个文件。
#include <stdio.h>
#include <stdlib.h>
int main()
{FILE* pf = fopen("aaa.txt","w");if(pf == NULL){perror("fopen:");return 1;}const char* str = "aaaaaaaaaaaaaaaaaaaaaa\n";fputs(str,pf);fclose(pf);return 0;
}
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ ./a.out
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ cat aaa.txt
aaaaaaaaaaaaaaaaaaaaaa
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$
结果显示,文件aaa.txt中已经写入了一段字符串。修改源代码,将写入字符串的代码删除后,再执行编译运行一次。
#include <stdio.h>
#include <stdlib.h>
int main()
{FILE* pf = fopen("aaa.txt","w");if(pf == NULL){perror("fopen:");return 1;}
// const char* str = "aaaaaaaaaaaaaaaaaaaaaa\n";
// fputs(str,pf);fclose(pf);return 0;
}
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ cat aaa.txt
aaaaaaaaaaaaaaaaaaaaaa
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ gcc file.c
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ ./a.out
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ cat aaa.txt
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$
结果表明,aaa.txt文件中的内容都消失了。原因在于fopen打开文件的方式"w",使用man手册查看fopen打开文件方式的说明。
"w"方式打开文件时,会先清空文件中的所有内容。如果想保留文件中原来的内容做写入操作,就应该使用"a"的方式打开文件。
1.> 和 >>
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ cat aaa.txt
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ echo aaaaaaaaaaaa > aaa.txt
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ cat aaa.txt
aaaaaaaaaaaa
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ echo bbbbbbbbb > aaa.txt
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ cat aaa.txt
bbbbbbbbb
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$
通过echo做重定向操作向aaa.txt文件中先后写入两次,最终效果并不是有两段字符串,说明重定向操作符">"打开文件的方式本质上也是"w"的方式。(需要一提的是,echo重定向到文件中,本质上也要修改文件的内容,所以一定会打开文件)。
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ echo aaaaaaaaaaaaaaaa >> aaa.txt
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ cat aaa.txt
aaaaaaaaaaaaaaaa
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ echo bbbbbbbbbbbbbbbb >> aaa.txt
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$ cat aaa.txt
aaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbb
utocoo@utocoo-virtual-machine:~/Desktop/linux/241121$
而追加重定向操作符" >> "先后向aaa.txt文件写入两次后,最终效果是两段字符串都被保留了下来,说明 " >> "其实和"a"方式类似,是一种追加的形式。
2.理解“当前路径”
在使用C接口操作文件的时候,经常会听到说,“如果没有这个文件,则在当前路径下新建这个文件”,如何理解这个“当前路径”?
最简单直接的理解,就是我们当前程序的路径。
//file.c
#include <stdio.h>
#include <stdlib.h>
int main()
{FILE* pf = fopen("aaa.txt","w");if(pf == NULL){perror("fopen:");return 1;}fclose(pf);return 0;
}
当前路径就是file.c文件所在路径,编译运行前,该路径下没有aaa.txt文件,编译运行后,该路径下存在名为aaa.txt的文件。
utocoo@utocoo-virtual-machine:~/Desktop/linux/241122$ ll
总计 16
drwxrwxr-x 2 utocoo utocoo 4096 11月 22 12:22 ./
drwxrwxr-x 16 utocoo utocoo 4096 11月 22 12:19 ../
-rw-rw-r-- 1 utocoo utocoo 233 11月 22 12:19 file.c
-rw-rw-r-- 1 utocoo utocoo 64 11月 22 12:21 Makefile
utocoo@utocoo-virtual-machine:~/Desktop/linux/241122$ make
gcc -o file file.c
utocoo@utocoo-virtual-machine:~/Desktop/linux/241122$ ./file
utocoo@utocoo-virtual-machine:~/Desktop/linux/241122$ ll
总计 32
drwxrwxr-x 2 utocoo utocoo 4096 11月 22 12:23 ./
drwxrwxr-x 16 utocoo utocoo 4096 11月 22 12:19 ../
-rw-rw-r-- 1 utocoo utocoo 0 11月 22 12:23 aaa.txt
-rwxrwxr-x 1 utocoo utocoo 16048 11月 22 12:23 file*
-rw-rw-r-- 1 utocoo utocoo 233 11月 22 12:19 file.c
-rw-rw-r-- 1 utocoo utocoo 64 11月 22 12:21 Makefile
在文件基础认识部分,已经提到过,文件是由进程打开的,那么新建一个文件也是由进程完成,进程是如何知道在哪条路径下新建一个文件呢。
在源代码中打印出进程的PID,运行后,再在/proc路径下找到对应进程的所在目录。
while(1)
{printf("PID:%d\n",getpid());sleep(2);
}
PID:2930
PID:2930
PID:2930
PID:2930
PID:2930
PID:2930
PID:2930
当前路径在进程的属性中其实已经保存好了,是cwd这条信息。因此新建一个文件要被存放到哪里也是确定的。但是进程的工作路径是可以修改的,虽然进程的前身是一个可执行程序,可执行程序的路径是确定,但是当可执行程序被操作系统管理起来后变成进程,进程的工作路径是可以通过chdir指令修改的,那么修改路径后,再新建一个文件,这个文件的所在路径不再是修改前的路径了,而是修改后的路径。
这就表明,所谓的当前路径,其实是进程在运行的时候的工作路径,这个路径是由进程自己记录的,就是那条cwd信息。
三、相关系统调用
系统默认打开三个流,stdin,stdout,stderr,这三个流对应的外设分别为键盘、显示器、显示器。而Linux管理外设,是以文件的方式,即必然存在系统调用system call。因此,C语言的fopen、fclose、fwrite等函数本质是调用了system call。
下面就来认识Linux下文件相关的system call。
1.open
- pathname就是路径,传参方法和C语言的fopen的参数差不多。
- flags类型为int,传参的可选项如下所示
这些值都是C语言定义的宏,目的是为了实现,只定义一个函数,却可以同时“传两个参数”。比如
#include <stdio.h> #define ONE 1 #define TWO (1<<1) #define THREE (1<<2) #define FOUR (1<<3) #define FIVE (1<<4)void Print(int flags) {if(flags & ONE)printf("1\n");if(flags & TWO)printf("2\n");if(flags & THREE)printf("3\n");if(flags & FOUR)printf("4\n");if(flags & FIVE)printf("5\n"); } int main() {Print(ONE);printf("-----------------\n");Print(TWO);printf("-----------------\n");Print(ONE|TWO);printf("-----------------\n");Print(ONE|FOUR|FIVE);return 0; }
如果使用两个形参的open接口,一般是操作已经存在了的文件,比如bbb.txt文件必须存在,否则会报错。
int main()
{int fd = open("bbb.txt",O_WRONLY);if(fd == -1){perror("open\n");return 1;}close(fd);return 0;
}
用open接口实现fopen的"w"方式,文件如果不存在,则新建。而新建一个文件会有权限的初始化,一般普通用户新建一个文件的权限是0666(-rw-rw-rw-),而普通用户的权限掩码umask为0002,实际权限等于初始化权限减去权限掩码,即(-rw-rw-r--)
mode即初始化权限码,一般传0666,只有flags带O_CREAT时,mode传参才有效。
一般新建一个文件,在open的第二个参数上,应该传新建、可写、写入时清零,等同于fopen的"w"方式。
int main()
{int fd = open("bbb.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);if(fd == -1){perror("open\n");return 1;}const char* msg = "this is open to w\n";write(fd,msg,strlen(msg));close(fd);return 0;
}
原来不存在的文件bbb.txt被创建了出来,并且o的权限少了w,符合预期。
2.文件描述符
再来理解open的返回值——文件描述符(int fd)——Linux用整型值描述被打开的文件。
这些整型值其实是数组下标,我们知道系统默认打开三个流,其实是三个文件,stdin、stdout、stderr,它们的下标对应为0、1、2,如果先后有序的打开1.txt、2.txt、3.txt,则它们的下标也是有序的为3、4、5。
这段话似乎让你很懵,不过我马上就要阐述具体的内容。
在此之前,要明确,操作文件只能由操作系统来做,因此有C语言的fopen封装open接口,有C语言定义的FILE指针的流封装文件描述符fd。
实际上,FILE类型是结构体类型,也是封装了文件描述符int fd。
对int fd的理解。
文件描述符的本质,就是数组下标。
- OS管理进程,这一板块叫做进程管理,有PCB,Linux下被定义为task_struct。
- OS管理文件,这一板块叫做文件管理,在之前介绍了,文件区分为内存中的文件和磁盘中的文件,被加载到内存中的文件,OS要对它们做管理,就必然做“面向对象”和“数据结构”的工作,“面向对象”就是定义结构体,“数据结构”就是把对象存储到链表或者其他数据结构里面。Linux下把这个结构体类型定义为file,结构体内容大致有属性、方法集、缓冲区、mode(权限码)、flag、pos以及指向下一个结点的next等。
- 进程管理和文件管理是两个独立的板块,但是又有关联。进程可以打开多个文件,那么一个进程打开了哪些文件,该进程必然要做记录。于是Linux下,task_struct结构体中有一个结构体指针,指向的结构体类型为files_struct,而这个结构体中,有一个数组,数组的每个元素类型为结构体指针,指针指向的结构体类型为file,这个数组被称为文件描述符表。
一个进程打开文件后,进程在这个数组中保存指向这个文件的指针,默认这个数组的前三个位置已经被stdin、stdout、stderr这三个文件占用了。
而数组下标,就是文件描述符,为什么close、write等这些接口都用int类型的文件描述符来操作文件,原因很简单,数组下标式访问,仅仅是O(1)复杂度。
3.一切皆文件
硬件一层,由于各种原因,设备的操作方法各不相同,因此每台计算机都需要装载相应的驱动。而对于每台设备的操作函数,它们的函数类型相同,函数内容各不相同。
file结构体定义了方法集,本质就是函数指针。
- 每一台设备被视为一个结构体,方法集指向了该设备的操作方法。
- 当系统调用read读取某个外设的内容,实际上就是函数回调的形式,用函数指针调用外设的读函数。
4.再次理解重定向
文件描述符的分配规则:一定会把最小的数组下标利用起来,如果存在没有被利用的较小下标,则会分配给最新打开的文件,比如打开b文件前,将已经打开的a文件关闭,则打开b文件后,a文件的较小fd会分配给b文件。
上面这段话,其实就是重定向的实现原理。
输出重定向:本该输出到屏幕的语句却输出到了bbb.txt。
int main()
{close(1);int fd = open("bbb.txt",O_WRONLY);printf("这段话本该输出到屏幕\n");return 0;
}
原因就是在执行完close(1)语句后,当前进程的文件描述符表中数组下标为1的位置不再是指向屏幕文件的指针,而又打开了bbb.txt文件,则1号下标的指针指向了bbb.txt文件,printf底层封装的write传参的fd值还是1,因此,这句字符串被写进了1位置指向的bbb.txt文件的缓冲区。
所以,重定向的本质,就是文件指针在文件描述表中的下标发生了变化。
有一个专门用来拷贝文件描述符的系统调用——dup
想把打印到屏幕的内容重定向到bbb.txt,可以用dup2来实现。
大致意思是用oldfd的值覆盖到newfd。
int main()
{int fd = open("bbb.txt",O_WRONLY);dup2(fd,1);printf("----\n");return 0;
}
相关文章:
Linux:文件管理(一)——文件描述符fd
目录 一、文件基础认识 二、C语言操作文件的接口 1.> 和 >> 2.理解“当前路径” 三、相关系统调用 1.open 2.文件描述符 3.一切皆文件 4.再次理解重定向 一、文件基础认识 文件 内容 属性。换句话说,如果在电脑上新建了一个空白文档࿰…...
【C++初阶】第3课—类和对象(类的默认成员函数)
文章目录 1. 类的默认成员函数2. 构造函数3. 拷贝构造函数3.1 传值传参3.2 传值返回3.3 深拷贝和浅拷贝3.4 总结 4. 析构函数5. 赋值运算符重载5.1 运算符重载5.2 赋值运算符重载5.3 日期类的实现 6. 取地址运算符重载6.1 const 成员函数6.2 取地址运算符重载 1. 类的默认成员函…...
uni-app初学笔记:文件路径与作用
components:可复用的组件pages:页面(可见/不可见)static:静态资源,存放图片视频等 (相当于vue项目的 assets)mainjs:Vue初始化入口文件App.vue:应用配置,用来配置App全局样式以及监听pages.json :配置页面路…...
小程序-使用 iconfont 图标库报错:Failed to load font
官方默认可以忽略此错误,在清除缓存后首次刷新会显示此错误,重新渲染错误消失 解决方法: 在 iconfont 图标库选择项目设置 选中 Base64 保存,重新点击链接 -> 复制代码到项目中 操作步骤:...
【计网】自定义协议与序列化(一) —— Socket封装于服务器端改写
🌎 应用层自定义协议与序列化 文章目录: Tcp协议Socket编程 应用层简介 序列化和反序列化 重新理解read/write/recv/send及tcp的全双工 Socket封装 服务器端改写 🚀应用层简介 我们程序员写的一个个解决…...
速度革命:esbuild如何改变前端构建游戏 (1)
什么是 esbuild? esbuild 是一款基于 Go 语言开发的 JavaScript 构建打包工具,以其卓越的性能著称。相比传统的构建工具(如 Webpack),esbuild 在打包速度上有着显著的优势,能够将打包速度提升 10 到 100 倍…...
大语言模型---什么是注意力机制?LlaMA 中注意力机制的数学定义
摘要 注意力机制(Attention Mechanism)是一种在深度学习和人工智能中广泛使用的技术,旨在使模型在处理信息时能够重点关注重要的部分,从而提升任务的效率和精度。它最初应用于自然语言处理(NLP)࿰…...
LSA详情与特殊区域
LSA是构成LSDB的重要原材料,在OSPF中发挥很大作用。 报文 通用头部 LS age:LSA寿命,0-3600s Options:可选项 LS type:LSA类型,三要素之一 Link State ID:LSAID 三要素之一 Advertising Ro…...
Python爬虫能处理动态加载的内容吗?
Python爬虫确实可以处理动态加载的内容。动态加载的内容通常是通过JavaScript在客户端执行,这意味着当网页首次加载时,服务器返回的HTML可能并不包含最终用户看到的内容。相反,JavaScript代码会在页面加载后从服务器请求额外的数据࿰…...
Spring Boot Web应用开发:数据访问
数据访问是Web应用的关键部分,Spring Boot简化了这一流程,特别是通过集成Java Persistence API (JPA) 来实现数据持久化。以下是如何在Spring Boot中配置数据源、使用JPA进行数据持久化以及创建访问数据的REST接口。 配置数据源 在Spring Boot中&#…...
【Linux】进程控制-----进程创建与进程终止
目录 前言: 一、进程创建: 1、fork函数 2、创建多个进程: 3、写时拷贝: 二、进程终止: 进程退出码: 退出方式: 编辑 进程异常退出: 缓冲区: 前言࿱…...
【软考速通笔记】系统架构设计师③——信息安全技术基础知识
文章目录 一、前言二、信息安全基础知识2.1 信息安全的基本要求2.2 信息安全的范围2.3 网络安全表现2.4 安全措施包括 三、信息安全系统的组成框架3.1 技术体系:3.2 组织机构体系:3.3 管理体系 四、信息加解密技术4.1 对称密钥加密算法4.2 非对称密钥加密…...
AI安全:从现实关切到未来展望
近年来,人工智能技术飞速发展,从简单的图像识别到生成对话,从自动驾驶到医疗诊断,AI技术正深刻改变着我们的生活。然而,伴随着这些进步,AI的安全性和可控性问题也日益凸显。这不仅涉及技术层面的挑战&#…...
YOLO格式数据集介绍
yolo数据集 yolo数据集标注格式主要是 yolov5 项目需要用到。 标签使用txt文本进行保存。yolo的目录如下所示: dataset ├─images │ ├─train │ │ ├─ flip_mirror_himg0026393.jpg │ │ ├─ flip_mirror_himg0026394.jpg │ │ ├─ flip_…...
Doris 数据集成 LakeSoul
Doris 数据集成 LakeSoul 作为一种全新的开放式的数据管理架构,湖仓一体(Data Lakehouse)融合了数据仓库的高性能、实时性以及数据湖的低成本、灵活性等优势,帮助用户更加便捷地满足各种数据处理分析的需求,在企业的大数据体系中已经得到越来越多的应用。 在过去多个版本…...
Navicat 预览变更sql
需求 用了Flyway(数据库迁移工具)后,需要记录变更sql,所以要知道变更sql。 查看方式 Navicat提供了预览变更sql功能,右击表---->设计表,比如修改字段后,点击SQL预览标签页, 顺…...
深入理解下oracle 11g block组成
深层次说,oracle数据库的最少组成单位应该是块,一般默认情况下,oracle数据库的块大小是8kb,其中存储着我们平常所需的数据。我们在使用过程中,难免会疑问道:“oracle数据块中到底是怎样组成的,平…...
Qt Graphics View 绘图架构
Qt Graphics View 绘图架构 "QWGraphicsView.h" 头文件代码如下: #pragma once#include <QGraphicsView>class QWGraphicsView : public QGraphicsView {Q_OBJECTpublic:QWGraphicsView(QWidget *parent);~QWGraphicsView();protected:void mouseM…...
大数据-234 离线数仓 - 异构数据源 DataX 将数据 从 HDFS 到 MySQL
点一下关注吧!!!非常感谢!!持续更新!!! Java篇开始了! 目前开始更新 MyBatis,一起深入浅出! 目前已经更新到了: Hadoop࿰…...
零基础学安全--shell脚本学习(1)脚本创建执行及变量使用
目录 学习连接 什么是shell shell的分类 查看当前系统支持shell 学习前提 开始学习 第一种执行脚本方法 编辑 第二种执行脚本方法 第三种执行脚本方法 变量声明和定义 编辑 查看变量 删除变量 学习连接 声明! 学习视频来自B站up主 **泷羽sec** 有兴趣…...
C#对INI配置文件进行读写操作方法
#region 读写ini配置文件/// <summary>/// 对INI文件进行读写/// </summary>class INIHelper{/// <summary>/// 从INI文件中读取数据/// </summary>/// <param name"filePath">INI文件的全路径</param>/// <param name"…...
华为鸿蒙内核成为HarmonyOS NEXT流畅安全新基座
HDC2024华为重磅发布全自研操作系统内核—鸿蒙内核,鸿蒙内核替换Linux内核成为HarmonyOS NEXT稳定流畅新基座。鸿蒙内核具备更弹性、更流畅、更安全三大特征,性能超越Linux内核10.7%。 鸿蒙内核更弹性:元OS架构,性能安全双收益 万…...
请求响应(学习笔记)
请求响应 文章目录 请求响应请求Postman简单参数实体参数数组集合参数数组参数集合参数 日期参数JSON参数路径参数 响应响应数据统一响应结果 分层解耦三层架构分层解耦IOC & DI 入门IOC详解DI详解 请求响应: 请求(HttpServeltRequest):获取请求数据…...
JavaScript核心语法(5)
这篇文章讲一下ES6中的核心语法:扩展运算符和模块化。 目录 1.扩展运算符 数组中的扩展运算符 基本用法 合并数组 对象中的扩展运算符 基本用法 合并对象 与解构赋值结合使用 数组解构中的剩余元素 对象解构中的剩余属性 2.模块化 基本概念 1.扩展运算符…...
2024年第15届蓝桥杯C/C++组蓝桥杯JAVA实现
目录 第一题握手,这个直接从49累加到7即可,没啥难度,后面7个不握手就好了,没啥讲的,(然后第二个题填空好难,嘻嘻不会) 第三题.好数编辑 第四题0R格式 宝石组合 数字接龙 最后一题:拔河 第…...
MongoDB 和 Redis 是两种不同类型的数据库比较
MongoDB 和 Redis 是两种不同类型的数据库,设计目标和应用场景各有侧重,因此性能对比需要结合具体需求场景进行评估。 1. MongoDB 性能特点 类型: 文档型数据库(NoSQL)。适合场景: 复杂查询:支持丰富的查询语法和索引…...
CLIP-Adapter: Better Vision-Language Models with Feature Adapters 论文解读
abstract 大规模对比视觉-语言预训练在视觉表示学习方面取得了显著进展。与传统的通过固定一组离散标签训练的视觉系统不同,(Radford et al., 2021) 引入了一种新范式,该范式在开放词汇环境中直接学习将图像与原始文本对齐。在下游任务中,通…...
Spring Boot 开发环境搭建详解
下面安装spring boot的详细步骤,涵盖了从安装 JDK 和 Maven 到创建和运行一个 Spring Boot 项目的全过程。 文章目录 1. 安装 JDK步骤 1.1:下载 JDK步骤 1.2:安装 JDK步骤 1.3:配置环境变量 2. 安装 Maven步骤 2.1:下载…...
网络安全中的数据科学如何重新定义安全实践?
组织每天处理大量数据,这些数据由各个团队和部门管理。这使得全面了解潜在威胁变得非常困难,常常导致疏忽。以前,公司依靠 FUD 方法(恐惧、不确定性和怀疑)来识别潜在攻击。然而,将数据科学集成到网络安全中…...
安装数据库客户端工具
如果没有勾选下面的,可以运行下面的两个命令 红框为自带数据库 新建数据库 右键运行mysql文件,找到数据库,并刷新...
最新版在线 网/百度seo运营工作内容
这是在网上找到的一张流程图,写的比较好,大家可以先看图,然后看详细阅读下面的各个步骤。执行流程:1.连接验证及解析客户端与MySQL Server建立连接,发送语句给MySQL Server,接收到后会针对这条语句创建一个…...
wordpress html代码/百度图片识别在线识图
electronJS 是一个跨平台软件开发工具,使用 JavaScript, HTML 和 CSS 构建跨平台的桌面应用。由于使用了HTML 所以开发的界面更加丰富,美观和快捷。缺点是哪怕是一个Hello the world,也有几百M,程序很庞大。个人觉得electronJS 适…...
做网站的费用入账/免费b站网站推广
链接:https://pan.baidu.com/s/1zqhbQELzIJn_z6JDz8gKDA 提取码:52pj...
怎么样自己做企业网站/2020国内十大小说网站排名
Item M15:了解异常处理的系统开销 转载请注明出处<http://blog.csdn.net/qianqin_2014/article/details/51329961>为了在运行时处理异常,程序要记录大量的信息:无论执行到什么地方,程序都必须能够识别出如果在此处抛出异常的话…...
杭州做兼职网站/百度怎么推广产品
with打开文件的用法,打开运行完后,不管有没有错,都会自动关闭 with open("a.txt","r") as f: xf.read() print(x) with open("a.txt","w") as f: f.write("456") raise的作…...
网站想建设子站/可以推广赚钱的软件
熟悉C的童鞋都知道,为了避免“野指针”(即指针在首次使用之前没有进行初始化)的出现,我们声明一个指针后最好马上对其进行初始化操作。如果暂时不明确该指针指向哪个变量,则需要赋予NULL值。除了NULL之外,C…...