页面伪装异步加载中...
关闭/显示侧边栏
返回首页 mail me! 订阅rss Follow me

Archive for C/C++ Programming

关于那个经典的指针冒泡法排序。

这是这学期C语言考试的最后一道程序设计题的题目,对一组数进行从小到大排序输出,要求操作数组使用指针。此题15分。

用久了PHP,还真对数组排序的算法变的生疏起来,还好记得原理,冒泡法排序难倒一些初学C语言的人,因为数组的操作比起前面的基本运算符操作复杂了不少,尤其还要使用指针这东西。冒泡法的原理很简单,就是从第一个开始,每相邻两个数开始比较,如果前面的数大于后面的数,则交换两个数的位置(针对从小到大排序),然后开始第二个和第三个进行比较,全部比较完毕后,这个时候会有个最大值放在最后,然后继续对N-1个数进行同样的操作,直到两次循环完毕。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
main()
{
 int a[10];
 int i,j,temp;
 int *p=a;
 printf("input:");
 for(i=0;i<10;i++)
  scanf("%d",p+i);
 for(i=1;i<10;i++)
  for(j=0;j<10-i;j++)
   if(*(p+j)>*(p+j+1))
   {temp=*(p+j);*(p+j)=*(p+j+1);*(p+j+1)=temp;}
 for(i=0;i<10;i++)
  printf("%4d",*(p+i));
 printf("\n");
}

VC实现CPU速度自测

简单说下原理:
在两个固定的时刻测出当前CPU的时钟计数,用这个计数除以间隔的时间就得到相应的频率值了。
需要说明的是为了获得当前CPU的内侧时钟值,要采用内嵌汇编的方式得到,这就要将当前的测试进程的优先级设定的较高,故采用了实时进程优先级:REALTIME_PRIORITY_CLASS,该优先级别高,并且有这种权限的进程中的所有线程要比其他进程中的所有线程的级别都高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
用VC实现CPU速度自测
 
#include <windows.h>
#include <iostream>
using namespace std;
//测试速度的子程序
float MeasureSpeed(void);
int main(void)
{
    cout << "您的CPU的运行速度是: " << MeasureSpeed() << "MHz" << endl;
    system("pause");
    return 0;
}
float MeasureSpeed()
{
unsigned long int       ticks;          //先是存放计时次数,后存放固定时间间隔值
unsigned long int       stock0, stock1; //存放两固定时刻的CPU内置时钟值,值的含意为计数
unsigned long int       cycles;         //存放内置时钟值之差,好固定时段的计数值 
unsigned long int       freq[5] = {0,0,0,0,0}; //存放频率,为了提高精度,采用了相邻的测的5个频率的平均值
unsigned long int       nums = 0;       //循环次数
unsigned long int       total = 0;      //存放频率之和
    LARGE_INTEGER       t0,t1;
    LARGE_INTEGER       countfreq;
    //返回高精度的计数频率,即每秒多少次;
    if (!QueryPerformanceFrequency( &countfreq ) )
    {
        return 0.0f;
    }
    //返回特定进程的优先级;
    DWORD priority_class = GetPriorityClass(GetCurrentProcess());
    //返回特定线程的优先级;
    int   thread_priority = GetThreadPriority(GetCurrentThread());
    //将当前进程设成实时进程;
    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
	//设定线程优先级;
  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    do
    {
        nums++;
        freq[4] = freq[3];
        freq[3] = freq[2];
        freq[2] = freq[1];
        freq[1] = freq[0];
	//返回高精度计数的值;
        QueryPerformanceCounter(&t0);
        t1.LowPart = t0.LowPart;
        t1.HighPart = t0.HighPart;
	//这句中的50和后面相同语句中的1000是一个经验值,起的作用是控制时间间隔,可以
	//调节这两个值来实现最佳时间间隔。
 while ( (unsigned long int)t1.LowPart - (unsigned long int)t0.LowPart<10)
        {
            QueryPerformanceCounter(&t1);
        }
        _asm
        {
rdtsc  //启动读取CPU的内置时钟,其返回值是个64位的整数,高32到EDX,低32到EAX里
 mov stock0, EAX //高位部份在短暂时间内是不会有变化的,故无需读出对比
	}
 t0.LowPart = t1.LowPart;        // 重置初始时刻
  t0.HighPart = t1.HighPart;
 while ((unsigned long int)t1.LowPart-(unsigned long int)t0.LowPart<1000 )
        {
            QueryPerformanceCounter(&t1);
        }
        _asm
        {
            rdtsc
            mov  stock1, EAX
	}
        cycles = stock1 - stock0;
        ticks = (unsigned long int) t1.LowPart - (unsigned long int) t0.LowPart;
        ticks = ticks * 1000000;
        ticks = ticks / countfreq.LowPart;
   if ( ticks % countfreq.LowPart > countfreq.LowPart/2 )
        {
            ticks++;            // 使数据收敛
        }
freq[0] = cycles / ticks;    // 求出频率,单位:MHz
        if ( cycles%ticks > ticks/2 )
        {
           freq[0]++;             // 使数据收敛
        }
   total = (freq[0] + freq[1] + freq[2] + freq[3] + freq[4]);
    } while ((nums < 5 ) || (nums < 100) && ( (abs(5 * freq[0] - total) < 5)
             || (abs(5 * freq[1]-total) < 5) || (abs(5 * freq[2] - total) < 5)
			 || (abs(5 * freq[3]-total) < 5) || (abs(5 * freq[4] - total) < 5)
			 ));
//条件循环,以确保循环不少于5次,在大于5次后确保达到一定的精度后退出
    if ( total/5  !=  ( total + 1 )/5 )
    {
        total ++;               // 使数据收敛
    }
    // 恢复进程及线程的优先级别;
    SetPriorityClass(GetCurrentProcess(), priority_class);
    SetThreadPriority(GetCurrentThread(), thread_priority);
    return float(total) / 5.0f;
}

上面的程序,可以做一定修改,循环中的控制语句也可以作适当的调整,来提高测试精度。调试环境VC6.0/XP

给一个C语言数组排序

这是上次帮226的人做专周的一个子函数,里面有个排序的函数,自认为对于入门还不错。

因为这是一个程序管理系统,这个排序是用来排名次的一个小功能,只是其中的一个子函数,故在这里先说下函数前提。

首先是数据,数据是写到一个文件中的,输出大概就是这么个形式。

 数据结构图

然后将这个数据赋值到一个 float score[10][8] 的数组中。

在main() 函数中:

   首先赋值   int   n=10; //n为学生人数。

下面是排序函数的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void fun3(float score[][8],int n)    //排序函数
{
	int i,j,k;
	float temp[10][3],x[3];        //定义了一个临时二维数组和一个一维数组
	for (i=0;i&lt;n;i++)
	{
		temp[i][0]=score[i][0];    //将学号赋给临时二维数组的0列
		temp[i][1]=score[i][6];    //将总分赋给临时二维数组的1列
	}
	for (i=0;i&lt;n;i++)              /*条件也可为:i&lt;n-1*/
	{
		k=i;
		for (j=i+1;j&lt;n;j++)
			if (temp[j][1]&gt;temp[k][1])
				k=j;
			if (i!=k)                /*此语句不要也可*/
			{
				x[0]=temp[k][0];     //以下就是交换学号和总分
				x[1]=temp[k][1];
				x[2]=temp[k][2];     /*些语句不要也可*/
				temp[k][0]=temp[i][0];
				temp[k][1]=temp[i][1];
				temp[k][2]=temp[i][2];
				temp[i][0]=x[0];
				temp[i][1]=x[1];
				temp[i][2]=x[2];    /*些语句不要也可*/
			}
	}
	j=1;
	temp[0][2]=j;
	for (i=1;i&lt;n;i++)
		if (temp[i][1]==temp[i-1][1])
			temp[i][2]=j;
		else
		{
			j++;temp[i][2]=j;
		}
	printf("按总分排列的名次\n");
	printf("原学号    总分    名次\n");
	for (i=0;i&lt;n;i++)
		printf("%4g%10g%7g\n",temp[i][0],temp[i][1],temp[i][2]);
}

嗯,排序函数就是这样,数组的排序,有很多种方式,这只是一种。

Page 1 of 11