距离上次布置任务已经两个周了,虽然这是自己的业余学习,还是为自己的工作时间安排表示有待提高。。
废话不多说,直接上干货。
这次老师布置的任务要求是,Makefile写多线程、多文件调用、用上数学函数、用上Makefile的宏定义,恩就这四点。
画个框架图吧:
说明的不是很清楚哈,下面做个详细解释:
总的来说,我做了这么个东西:
有两个文件(test.txt , Qk.txt),两个文件里分别存了一些数据;
在getNum.c程序里,我用了两个数组存这两个文件的数据,然后,比较两个数组第i个数值的大小,输出较大的那个数据;
而这个i值,是由main.c传来的(相当于用户的需求),最后结果也是由main.c输出的;
myQk.c的作用是,对其中一个数组进行快速排序,并返回排序后的数组,由于TXT文件里有一些负数,所以我使用了math.h的abs取绝对值函数;
openFile.c的作用就是打开指定文件,向指定数组里存入数据(其实这里可以优化一下,直接用abs取值后存入数组,但是我不会。。);
newMain.c是我后加的,因为最开始没做多线程,后来为了简单,就又加了这么个c文件,作用就是使用两个线程去分别计算不同i值的数据。
不知道说没说清楚,大体上就这么个东西了。
最后make完,文件里的文件有这么多:
代码的话,为了以后自己回顾,在这里也传上,不过一些调试注释代码也懒得删了。。
1. newMain.c的代码:
#include
#include
#include
#include "main.h"
int main(){
struct cs mycs1 , mycs2;
mycs1.pa = "test.txt";
mycs1.l = 1;
mycs2.pa = "test.txt";
mycs2.l = 0;
pthread_t t1,t2;
pthread_create(&t1,NULL,oldMain,(void *)&mycs1);
pthread_create(&t2,NULL,oldMain,(void *)&mycs2);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}
2. main.c的代码:
#include"main.h"
void *oldMain(void *data)
{
struct cs *theCs ;
theCs = (struct cs*)data;
int a = 0;
a = getTheMax(theCs->pa, theCs->l); //这里有个问题,我如果想把path传两次应该怎么传?
//a = getTheMax(1);
printf("%dn", a);
//return 0;
}
3. getNum.c的代码:
#include "getNum.h"
#include "openFile.h"
#include "myQk.h"
int getTheMax(const char *path, int a){
int v[100]={0};
int num = 0;
//char *path = "test.txt";
num = readFile(path, v);
int compe = 0;
compe = getMyNum(a);
if(v[a] > compe)
return v[a];
else
return compe;
}
4. myQk.c的代码:
#include "myQk.h"
#include "openFile.h"
void Quick(int *a, int low, int high){
if(low >= high)
{
return;
}
int first = low;
int last = high;
//此处为后加的
if(a[first] < 0)
a[first] = abs(a[first]);
if(a[last] < 0)
a[last] = abs(a[last]);
int key = a[first];/*用字表的第一个记录作为枢轴*/
while(first < last)
{
while(first < last && a[last] >= key)
{
--last;
//后加的
if(a[last] < 0)
a[last] = abs(a[last]);
}
a[first] = a[last];/*将比第一个小的移到低端*/
while(first < last && a[first] <= key)
{
++first;
//此处为后加的
if(a[first] < 0)
a[first] = abs(a[first]);
}
a[last] = a[first];
/*将比第一个大的移到高端*/
}
a[first] = key;/*枢轴记录到位*/
Quick(a, low, first-1);
Quick(a, first+1, high);
}
int getMyNum(int myNum){
char *path = "Qk.txt";
int arr[100] = {0};
int count = 0;
count = readFile(path, arr);
/*
int i = 0;
for(;i
printf("%dn",arr[i]);
*/
Quick(arr, 0, count-1); //细节!这里count要减一!!!
return arr[myNum];
}
5. openFile.c的代码:
#include "openFile.h"
int readFile(const char *filename, int *v){
//int v[100];//开一个足够大的数组。
int i = 0;
FILE *fp;//文件指针
fp = fopen(filename, "r");//以文本方式打开文件。
if(fp == NULL) //打开文件出错。
return -1;
while(fscanf(fp, "%d", &v[i]) != EOF) //读取数据到数组,直到文件结尾(返回EOF)
i++;
fclose(fp);//关闭文件
return i;
}
6. main.h的代码:
#ifndef __MAIN_H__
#define __MAIN_H__
#include
#include
#include "getNum.h"
struct cs{
char *pa;
int l;
} ;
void *oldMain(void *data);
#endif
7. getNum.h的代码:
#ifndef __GETNUM_H__
#define __GETNUM_H__
# include
int getTheMax(const char *path, int a);
#endif
8. myQk.h的代码:
#ifndef __MYQK_H__
#define __MYQK_H__
# include
#include
void Quick(int *a, int low, int high);
int getMyNum(int myNum);
#endif
9. openFile.h的代码:
#ifndef __OPENFILE_H__
#define __OPENFILE_H__
# include
int readFile(const char *filename, int *v);
#endif
10. Makefile的mymake代码:
all: myapp
CC = gcc
myapp: newMain.o main.o getNum.o myQk.o openFile.o
$(CC) -lpthread -o myapp newMain.o main.o getNum.o myQk.o openFile.o
newMain.o: newMain.c main.h
$(CC) -c newMain.c
main.o: main.c main.h getNum.h
$(CC) -c main.c
getNum.o: getNum.c getNum.h openFile.h myQk.h
$(CC) -c getNum.c
myQk.o: myQk.c myQk.h openFile.h
$(CC) -c myQk.c
openFile.o: openFile.c openFile.h
$(CC) -c openFile.c
这里要注意的就是,多线程Makefile的时候,要加上-lpthread 不然会报错XXX缺少thread函数等等。
最后使用 make -f mymake 就可以编译生成可执行文件了。
新手,欢迎各位大神批评指正。两个TXT文件的内容就不在这里放了,随便编些阿拉伯数字就可以。
最后运行结果图:
给自己设定个小任务,把C语言文件读写那块搞懂一些,这块代码找了老半天。。。