shell C语言编程

文章目录

    • 1、编译优化
      • makefiel
    • 2、文件基本操作编程
      • 使用Linux系统调用编写一个完成文件拷贝的C程序。比较拷贝得到的文件与源文件的大小和内容(命令diff,cmp)。
      • 编写C程序完成:创建一个新文件,输入一段数据,然后随机移动指针接着插入一段数据。完成后,查看该文件的大小和内容。怎样获取当前文件的读写指针位置?
    • 3、编写拷贝命令,实现文件或目录的复制
    • 4、gdb 调试工具

1、编译优化

//代码

#include 
int main(void)
{
   
double counter;
double result;
double temp;
for (counter = 0; counter < 2000.0 * 2000.0 * 2000.0 / 20.0 + 2020;
counter += (5 -1) / 4) {
   
temp = counter / 1979;
result = counter;
}
printf(Result is %lf\\n, result);
return 0;
}

gdb调试:

优化后
shell C语言编程_第1张图片

未优化

shell C语言编程_第2张图片

优化分析:

  • 代码分析

shell C语言编程_第3张图片

  • 执行分析
    shell C语言编程_第4张图片

  • 大小分析

请添加图片描述

区别:-O优化会改变文件大小,会更小一点。优化后的代码执行时间会更短;优化后的代码会把数据全部存入xmm寄存器,计算时直接从寄存器读取数据;未优化的代码会把一些数据放在栈中来读取。栈中读取和寄存器读取,显然寄存器会更快。

makefiel

一个工程中的源文件不计数,其按类型功能模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

2、文件基本操作编程

使用Linux系统调用编写一个完成文件拷贝的C程序。比较拷贝得到的文件与源文件的大小和内容(命令diff,cmp)。

代码

#include 
#include 
#include 
#include

int main(){
int f1,f1_l,f2;	//f1:文件a.txt的句柄;f2:文件b.txt的句柄;f1_l:a.txt文件内容的长度。
char buf[1024]={};//这个用于暂时存储被复制的文件内容

//打开源文件,读取文件内容
f1=open("a.txt",O_RDWR);
f1_l=read(f1,buf,1024);

//这里打开目标文件,如果没有就创建一个,且权限为777,然后将内容复制到目标文件
f2=open("b.txt",O_RDWR | O_CREAT,0777);
write(f2,buf,f1_l);

close(f1);
close(f2);

}

执行结果:

shell C语言编程_第5张图片

​ 用ls去查看,发现文件大小没有不同,只是两者权限不同。权限设置的是777,但是由于用户的默认权限掩码,

请添加图片描述

0022,所以创建出来的权限就是0777-0022=0755。

​ 用diff去比较,

请添加图片描述

diff会针对文本内容逐行进行对比,如果有不同就会显示出这有差别的两行,这里看到文本内容上并没有什么差别。

shell C语言编程_第6张图片

​ 用cmp去对比,

请添加图片描述

cmp会逐个字符去比较,会告诉有差异的字符的位置,第几行第几个字符。不加参数的情况下它只会显示出第一个有差异的位置。-l参数会帮助显示出所有有差异的位置。这里也没有不同。

shell C语言编程_第7张图片

编写C程序完成:创建一个新文件,输入一段数据,然后随机移动指针接着插入一段数据。完成后,查看该文件的大小和内容。怎样获取当前文件的读写指针位置?

代码

#include 
#include 
#include 
#include 
#include 

int main(){
   
    int fd,loc;
    char name[10]="\0";
    char context[1024]="\0";
    char tip[]="mkanewdir!";//插入字符串内容

    //创建一个新文件
    printf("文件名:");
    gets(name);
    fd=creat(name,0777);

    //输入一段内容写入新文件中
    printf("内容:");
    gets(context);
    write(fd,context,sizeof(context));

    //插入字符串
    lseek(fd,2,SEEK_SET);
    write(fd,tip,strlen(context)+8);
    

    //读取文件指针位置
    loc=lseek(fd,0,SEEK_CUR);
    printf("当前文件读写指针的位置:%d。",loc);
    close(fd);
}

获取字符串长度的话就是lseek,SEEK_CUR锁定到当前位置,偏移量为0,就可以得到当前位置了。这里有尝试用tell函数,但是编译时显示没有定义这样一个函数。不知道是我的gcc太老了还是啥。

shell C语言编程_第8张图片

请添加图片描述

这里文件的大小就是总的字符串长度。

3、编写拷贝命令,实现文件或目录的复制

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

long int dir_list[100][100][100];
long int dir_dst[100][100][100];
int loc=0,i=0,count=0,off=0;
int alow,sum=0;

int ls();
void copy_file();
void copy_dir();
void samename(mode_t mode);
void counter();
int main(int num,char* name[])
{
   
	struct stat fl_str,fl_dst;
	struct statfs size;
	
	sprintf(dir_list[0][0],name[1]);//参数存如数组中
	sprintf(dir_dst[0][0],name[2]);

	stat(dir_list[0][0],&fl_str);
	stat(dir_dst[0][0],&fl_dst);

	

	samename(fl_str.st_mode);//同名判断
	statfs(dir_dst[0][0],&size);
	alow=4*size.f_bavail;
	switch(num)
	{
   
		case 3://文件复制
			if(S_ISREG(fl_str.st_mode)&&((fl_str.st_size/1000)<alow))
			{
   
				copy_file();
			}
			else
				printf("磁盘大小不足,复制中止!");
			break;
		case 4://目录复制
			if(S_ISDIR(fl_str.st_mode)&&!strcmp(name[3],"-r"))
			{
   
				ls();
			}
			else
				printf("复制目录格式有误!复制中止!\n格式:源路径 目标路径 -r");
			break;
	}
	
}

int ls()//遍历目录,递归复制
{
   
	char dst[100];
  	DIR* dir_ptr[100];
	struct dirent* direntp;    
	struct stat type;

	while(off<2)
	{
   
		while((dir_ptr[loc] = opendir(dir_list[loc][0]))!=NULL)
		{
   
			while((direntp = readdir(dir_ptr[loc])) != NULL)
			{
   
				if(!strcmp(direntp->d_name,"..")||!strcmp(direntp->d_name,"."))
				{
   
					continue;
				}
				sprintf(dir_list[loc][++i],"%s/%s",dir_list[loc][0],direntp->d_name);
				sprintf(dir_dst[loc][i],"%s/%s",dir_dst[loc][0],direntp->d_name);
				stat(dir_list[loc][i], &type);
				if(S_ISREG(type.st_mode))
				{
   
					if(off==0)
						sum+=type.st_size;
					else
						copy_file();
				}
				else if(S_ISDIR(type.st_mode))
				{
   
					
					++count;
					strcpy(dir_list[count][0],dir_list[loc][i]);
					strcpy(dir_dst[count][0],dir_dst[loc][i]);
					if(off==0)
						sum+=type.st_size;
					else
						copy_dir();
				}
			}
			if(count>=loc)
			{
   
				loc++;
				i=0;
			}
		}
		switch(off)
		{
   
			case 0:
				if((sum/1000)>alow)
				{
   
					perror("ERROR:磁盘容量不足,停止复制!\n");
					_exit(2);
				}
				else
					printf("复制成功!\n目录大小:%2dkb,可使用剩余磁盘容量:%2dkb。\n",sum/1000,alow-sum/1000);
				break;
			case 1:break;	
		}
		off++;
		loc=0,i=0,count=0;
	}
}

void copy_file()//复制文件
{
   

	int fl_str,fl_dst,len;
	char context[10240];

	fl_str=open(dir_list[loc][i],O_RDONLY);
	len=read(fl_str,context,10240);
	
	fl_dst=open(dir_dst[loc][i],O_RDWR|O_CREAT,0644);
	write(fl_dst,context,len);
	close(fl_str);
	close(fl_dst);
}

void copy_dir()//复制目录
{
   
	mkdir(dir_dst[loc][i],0777);
}

void samename(mode_t mode)//同名判断
{
   

	if(access(dir_dst[0][0],F_OK)==0)
	{
   
		perror("ERROR:有同名文件存在,停止复制!\n");
		_exit(2);
	}
	else if(S_ISREG(mode))
	{
   
		creat(dir_dst[0][0],0644);
	}
	else if(S_ISDIR(mode))
	{
   
		copy_dir();
	}
}
//这个代码网上转载
#include 
#include 
#include 
#include 
#include 
#include 

int is_dir(char *path);                         //判断是否是目录  是返回1 否则返回0
int copy_file(char *srcPath, char *destPath);   //复制文件  成功返回0 否则返回 -1
int copy_folder(char *srcPath, char *destPath); //复制文件夹  成功返回0 否则返回 -1

int main(int argc, char *argv[]) // argv[1] 源文件  argv[2] 目标文件
{
   
    if (argc != 3)
    {
   
        printf("Usage srcfile destfile\n");
        return -1;
    }
    char *srcPath = argv[1];
    char *destPath = argv[

你可能感兴趣的:(linux,c语言,算法)