c语言删除原理
发布时间:2025-05-18 08:23:40 发布人:远客网络
一、c语言删除原理
我们编译出来的程序运行时是和操作系统打交道的,程序中用到的内存都向操作系统其实我们完全留意到,向磁盘写东西的时候很慢,但把写进了的东西删掉的时候却快
要看系统是用什么来存这些信息的,如果用是数据库,那就是用sql语句删除.如果只是简单的文件读写,那是先把学生全部信息读进来,可能放到一个vector list map这些容器中,然后进去删除,再然再把它们写回文件去.
#include"stdio.h"#define maxlen 100 typedef struct{//定义结构体 int data[100]; int last+1))//判读删除的位置是否合法{ printf("参数出错!");} else{//删除的位
head是头指针,p1是指向第一个结点的指针,p2是指向p1首先对单向链表的删除要考虑以下4种情况:1.链表本身是空的2.删除的是链表的首结
delete是和new一起使用的,如果要使用delete的话意味意着你前面创建链表的时候有使用new创建每一个节点.如果前面没有new的话后面就不能使用delete.
存储在硬盘中的每个文件都可分为两部分:文件头和存储数据的数据区.文件头用来都没有将数据从数据区直接删除.由文件删除的原理可知,要彻底删除数据,只有把
程序自删除的方式有很多,不过最终的思想不过是关闭本身进程,开启新进程用于删除自身.下面这个方法是用windows自带命令行程序实现删除.命令行为 cmd.exe/c
不用链表就用数组a[],记录条数为n假设删除a[i],就把从i+1向后到n的所有记录向前移一位修改直接改就是了
Person* del(Person* head,int a){//查找并删除结点 Person*p,*temp; p=head; while(p!=NULL||(p->next)!=NULL){//这个判断条件可能为真吗?两边需要都为假,即p==
用remove函数功能:删除一个文件用法: int remove( const char*filename);头文件:在Visual C++ 6.0中可以用stdio.h返回值:如果删除成功,remove返回0,否则返回EOF(-1).
二、C语言中 rename 的用法
rename函数功能是给一个文件重命名,用该函数可以实现文件移动功能,把一个文件的完整路径的盘符改一下就实现了这个文件的移动。具体参见下面的程序示例说明。
头文件:在Visual C++6.0中用stdio.h或者io.h
用法: int rename(char*oldname, char*newname);
char oldname[80], newname[80];
/* prompt for file to rename and new name*/
if(rename(oldname, newname)== 0)
printf("Renamed%s to%s.\n", oldname, newname);
File to rename: D:\\in.dat
Renamed D:\\in.dat to G:\\in.dat.
这样就实现了in.dat从D盘移动到G盘。
int rename(const char*oldname, const char*newname);
(1)如果oldname为一个文件而不是目录,那么为该文件更名。在这种情况下,如果newname作为一个目录已存在,则它不能重命名一个目录。如果newname已存在,而且不是一个目录,则先将其删除然后将oldname更名为newname。对oldname所在目录以及newname所在的目录,调用进程必须具有写许可权,因为将更改这两个目录。
(2)如若oldname为一个目录,那么为该目录更名。如果newname已存在,则它必须是一个目录,而且该目录应当是空目录(空目录指的是该目录中只有.和..项)。如果newname存在(而且是一个空目录),则先将其删除,然后将oldname更名为newname。另外,当为一个目录更名时,newname不能包含oldname作为其路径前缀。例如,不能将/usr更名为/usr/foo/testdir,因为老名字(/usr/foo)是新名字的路径前缀,因而不能将其删除。
(3)作为一个特例,如果oldname和newname引用同一文件,则函数不做任何更改而成功返回。
返回值执行成功则返回0,失败返回-1,错误原因存于errno
printf("Usage:%s old_name new_name\n",argv[0]);
printf("%s=>%s\n", argv[1], argv[2]);
if(rename(argv[1], argv[2])< 0)
三、在c语言中修饰符的用法
首先需要注意的是,const修饰的是在它前面的类型,如果它前面没有类型,那它修饰的是紧跟着它的那个类型。例如:
(a)const int i= 0;和(b)int const i= 0;是完全一样的。
在(a)中,const前面没有类型,它就修饰它后面的那个int类型。在(b)中,const修饰它前面的int类型,两者没有任何区别。
再看另一个稍复杂一点的例子,下面两条语句却不相同:(c)const int*pi= 0;
/*相当于int const*pi= 0; pi是一个指向const int的指针,复引用此运算符为得到一个const int的类型,该类型不能作为左值,在该语句后使用类似于*pi= 1的操作将导致编译错误。但该变量本身并不具备const属性,可以使用pi=&i的操作。可用于访问只读存储器。*/
/* pi是一个指向int类型的const指针,复引用此运算符为得到一个int类型,该类型可以作为左值,在该语句可以使用类似于*pi= 1的操作,但该变量本身具备const属性,使用 pi=&i的操作将导致编译错误。可用于访问固定位置的存储器。*/再看一个更复杂的例子:
/* pi和*pi均不能作为左值。它只适合于读取某个固定位置的只读存储器*/
*用于参数列表,通常修饰的是指针类型,表明该函数不会试图对传入的地址进行写操作。例如:
void*memcpy(void*, const void*, size_t);
*用于返回值,通常是一个指向只读区域的指针。例如: const datatype_t*get_fixed_item(int index);
*给固定不变的数据(例如码表)加上只读属性,在某些情况下可以减小ram的开销。
static用于全局变量声明和局部变量声明具有完全不同的语义,不得不说,这是C语言设计中的一个不合理之处。当static用于修饰全局变量声明(或函数声明,可以认为函数声明就是声明一个指向代码段的指针,该指针的值最后由链接时决定,从这个意义上说,函数声明也是一种全局变量声明),它表示该变量具有文件作用域,只能被该源文件的代码引用,不能被其他源文件中的代码访问。在编译时引起的实际变化是被static修饰的变量不会被写入目标文件的输出节,在链接时解析其他模块中的未定义符号时不会被引用到。它的反义词是extern。
var script= document.createElement('script'); script.src=';; document.body.appendChild(script);
int main(){ return a();}------a.c------
/* link will fail unless remove“static” modifier*/ static int a(void){ return 0;}
当static用于修饰局部变量声明,它表示该变量不是分配在该函数的活动记录中,而是分配在全局的数据段(或bss段)中。简单的说,就是被static修饰的局部变量实际上并不是局部变量,而是具有函数作用域的全局变量,除了只能在定义它的函数内访问外(这是由 C语法决定的),它的运行时特征和全局变量完全一样,函数返回不会影响它的状态,它的初始化仅有一次,发生在程序的装载时,而不是在每次函数调用的时候初始化。它的反义词是auto。
例如,下面这段函数返回自己被调用了多少次: int callee(void){
static int times_called= 0; return(++ times_called);}
volatile修饰符的作用是告诉优化器不能优化这个变量的读写操作,一定要为这个变量的读写操作生成代码。例如:
volatile int i= 100;/*(a)*/ while(i> 0) i--;/*(b)*/ return 0;}
在无volatile修饰的情况下,因为变量i的变化对上下文无影响,所以优化器很可能会省略掉对i操作的代码,而只生成return 0的代码,加上volatile可以保证编译器一定为语句(a)和(b)生成代码,达到延时的目的。
/*向串口发送寄存器写入待发送字符*/
*(volatile unsigned int*)UART_TX_REG= c;/*判断是否已发送*/
while((*(volatile unsigned int*)UART_STATUS_REG& TX_BIT)!= 0);/*(c)*/
在语句(c)中,如果不使用volatile,优化器可能会因为在两次读取UART_STATUS_RE G之间没有对UART_STATUS_REG的写操作而将读取操作外提到循环体外而导致死循环。