time函数和difftime函数,time函数的参数返回和返回值有区别?
《数据结构与算法分析,c语言原书第二版》中 第二章 的2.7.1题:
需要生成前N个自然数的随机置换。例如:【4,3,1,5,2】和【3,1,4,2,5】就是合法的置换。但是【5,4,1,2,1】却不是。因为数1出现两次而数3却没有。下面是一种算法:
如下填入A[0]到A[N-1]的数组A;为了填入A[i],生成随机数直到它不同于生成的A[0],A[1],...A[i-1]时,再将其填入A[i]。
对于这个算法,我自己写的代码(linux-centos下):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include "log.h"
#define N 10000
int main(int argc, char **argv)
{
logInit(argv[0], __FILE__, __LINE__);
int a[N] = {0};
time_t ts, te, ts1, ts2;
time(&ts);
// ts1 = time(NULL);...........a
first(N, a);
// sleep(3);..................b
time(&te);
// ts2 = time(NULL);.................c
int i = 0;
char tmp[N*3] = {0};
for (i = 0; i < N; ++i) {
sprintf(tmp, "%s %d", tmp, a[i]);
}
logPrint("%s", tmp);
logPrint("first所用时间:%f秒", difftime(te, ts));
// logPrint("first所用时间:%f秒", difftime(ts2, ts1));
return 0;
}
int first(int n, int *a)
{
if (n < 0) {
return -1;
}
int i = 0, j = 0, iFlag = 0;
a[0] = RandInt(0, n-1);
for (i = 1; i < n; ++i) {
while (1) {
iFlag = 0;
a[i] = RandInt(0, n-1);
for (j = 0; j < i; ++j) {
if (a[j] == a[i]) {
iFlag = 1;
break;
}
}
if (iFlag == 1) {
continue;
} else {
break;
}
}
}
return 0;
}
/**************
* 输入:
* a 产生随机数的范围下限
* b 产生随机数的范围上限
* 输出:
* 返回值: 返回产生的随机数
***************/
int RandInt(int a, int b)
{
if (a > b) {
logPrint("范围有问题,下限:[%d] 上限:[%d]", a, b);
return -1;
}
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
srand(tv.tv_usec);//必须以微秒做种子,如果以秒做种子,程序运行太快,每次产生的随机数都一样
return a + (int)((float)(b+1-a) * rand()/(RAND_MAX+1.0));//注意"int","float"不能省去
}
logPrint是日志函数。
我的问题是,上面那两个time()函数,我用的是用参数返回得到当前时间,这样我下面用difftime得到时间差是个非常大的值(实际只有10几秒),而如果换成用time返回值得到当前时间,也就是我注释的a,c,那么下面difftime就得到正确的时间;然后更奇怪的是,我把first函数换成sleep,两种方法得到的时间差又是一样的,,,,不解! c语言 算法 difftime() time()
[解决办法]
这个问题相当于有变量(ts,te)的值被意外(越界)更改了,所以可以对它下写断点,当有(意外)更改这个变量的值的时候,就可以知道哪些代码更改了它。
至于ts1,ts2的值不变,不过刚好是因为它们在内存中的位置,无法被越界的代码改到,所以是对的。
所以根本原因就是保证数组的操作不越界。