测试堆的最大申请数量
看到说linux下的虚拟地址空间分给进程本身的是3GB(高址的1GB是内核空间,也就是0xc000000以上地址),所以有这样一个程序来测试用malloc最多能申请多少内存?
#include<stdio.h> #include unsigned max=0; int main(void) { int i,count; unsigned size[]={1024*1024,1024,1}; for(i=0;i<3;i++){ for(count=1;;count++){ void *p=malloc(max+count*size[i]); if(p){ max+=count*size[i]; free(p); } else{ break; } } } printf("The max memory i can alloc is %u\n",max); return 0; }
在我的linux机器上跑了后发现只有1.1G左右的空间,想一下应该是内存768M+swap400多M,所以到不了那么大吧!
求三个参数中最大两个的平方和
看到一题,实现一个函数,求三个函数中最大的两个参数的平方和。
很自然的,想到这样的方法:
if(y > x && z > x){
return y * y + z * z;
}
if(x > y && z > y){
return x * x + z * z;
}
if(x > z && y > z){
return x * x + y * y;
}
}
if (x <= y && x <= z){
return y * y + z * z;
}
return sum_square_largest(y, z, x);
}
超级快速关机方法
最近不知什么问题,发现有时关机时停在windows正在关机那里时间比较长,而且是偶尔快偶尔慢,吃不准是什么原因,于是就想着有什么好的快速关机的方法。
首先想到的就是那个经典的操作技巧,打开任务管理器,在关机菜单中按住ctrl的同时点关闭,片刻间,机子就关了。
算算这个所费的时间,打开任务管理器(不管是任务栏右键打开还是快捷键),再选菜单,点关闭,得10秒左右吧!
程序员的话就会多想一点,这个玩意用程序怎么实现呢?那个开始菜单关机函数和任务栏的肯定不是一样的,开始菜单的比较优雅一点,提醒保存数据,通知程序退出,然后关机,而任务管理器的就相对粗暴一点,什么也不做,直接就关机,不过速度绝对一流,呵呵,我喜欢,就要这个速度。
查了下资料,一般用的是ExitWindowsEx这个函数,可能也会用InitiateSystemShutdownEx,这里交待下ExitWindowsEx的用法,查MSDN,可以看到函数原型如下:
BOOL ExitWindowsEx(
UINT uFlags, // shutdown operation
DWORD dwReason // shutdown reason
);
其中uFlags有这些选项:
EWX_LOGOFF 注销
EWX_POWEROFF 关闭系统并关闭电源
EWX_REBOOT 关机重启
EWX_SHUTDOWN 关机并指出现在可以安全关机了
还有
EWX_FORCE
EWX_FORCEIFHUNG
强制关机,可能会丢失数据。
dwReason很多,主要这么几个
SHTDN_REASON_MAJOR_APPLICATION Application issue.
SHTDN_REASON_MAJOR_HARDWARE Hardware issue.
SHTDN_REASON_MAJOR_OPERATINGSYSTEM Operating system issue.
SHTDN_REASON_MAJOR_OTHER Other issue.
SHTDN_REASON_MAJOR_POWER Power failure.
SHTDN_REASON_MAJOR_SOFTWARE Software issue.
SHTDN_REASON_MAJOR_SYSTEM System failure.
但这不是这篇文章的重点,这里要说的武器不是公开的,在MSDN中查不到,这是微软的秘密武器,ZwShutdownSystem函数,藏在ntdll.dll中。
利用ZwShutdownSystem(2)关闭电源,这个函数要求有SE_SHUTDOWN_PRIVILEGE权限,因此要先用RtlAdjustPrivilege函数来设置SE_SHUTDOWN_PRIVILEGE,SE_SHUTDOWN_PRIVILEGE的值为0x13,ZwShutdownSystem函数不通知应用程序和服务程序,就直接关闭系统了,关机速度非常快,但是如果有程序没有保存数据的话,是不会有任何提示的。
完整的程序可以这样写:
#include<windows.h>
#define SE_SHUTDOWN_PRIVILEGE 0x13
int main()
{
int nRet;
int en;
HINSTANCE hs=NULL;
typedef int (*SHUTDOWN)(int);
SHUTDOWN ZwShutdownSystem;
typedef int (*RTL_ADJUST_PRIVILEGE)(int,int,int,int *);
RTL_ADJUST_PRIVILEGE RtlAdjustPrivilege;
hs=LoadLibrary("ntdll.dll");
if(hs==NULL)
{
MessageBox(NULL,"Cannot load DLL file!","error",MB_OK);
}
ZwShutdownSystem=(SHUTDOWN)GetProcAddress(hs,"ZwShutdownSystem");
RtlAdjustPrivilege=(RTL_ADJUST_PRIVILEGE)GetProcAddress(hs,"RtlAdjustPrivilege");
nRet=RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,TRUE,TRUE,&en);
if(nRet==0x0C000007C)
nRet = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,TRUE,FALSE,&en);
nRet=ZwShutdownSystem(2);
FreeLibrary(hs);
return 0;
}
编译运行,一个黑框一闪,机子就关了,像台式机拔电源一样快速。再多想一下,给它创建一个快捷方式,换个图标,然后设置为最小化运行,就看不到黑框了,再加个快捷键,这样的话,按个键,哗一下机子就黑了,光速关机啊!
弱弱的想一下,两个方法是不是本质上是一样的呢?
C语言有点变态
直接看这个程序
int f(int x)
{
printf("%d\n",x);
}
int main(void)
{
int (*pf)(int);
pf=f; //正常用法
pf(5);
(**pf)(5); //这是什么
(****************f)(5); //这个变态啊
pf=&f; //这个也没问题
pf(6);
pf=*****f; //这是干什么
pf(7);
system("pause");
return 0;
}
看着很神奇,至少有些我从来没那样写过,但是这些全部是合法的,可以编译通过。
比较程序的效率
今天老师给了个这样的题:
编写程序,测试两条循环语句的执行时间。分析为何执行时间不同。 int A[ROWS][COLS]; for(row=0; row<ROWS;row++) for(col=0;col<COLS;col++) A[row][col]=0; for(col=0;col<COLS;col++) for(row=0; row<ROWS; row++) A[row][col]=0;
于是就需要在程序中计算某一段执行的时间,找了一下,发现C/C++中的计时函数是clock(),而与其相关的数据类型是clock_t。查得clock函数定义如下:
clock_t clock( void );
这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数。其中clock_t是用来保存时间的数据类型,在time.h文件中,我们可以找到对 它的定义:
#ifndef _CLOCK_T_DEFINED
typedef long clock_t;
#define _CLOCK_T_DEFINED
#endif
很明显,clock_t是一个长整形数。在time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:
#define CLOCKS_PER_SEC ((clock_t)1000)
所以我们需要使用clock()算出程序执行期间的tick总数,再除以这个CLOCKS_PER_SEC,所以程序可以这样写:
-
#include<stdio.h>
-
#include<time.h>
-
#include<stdlib.h>
-
#define ROWS 10000
-
#define COLS 10000
-
int a[ROWS][COLS];
-
main()
-
{
-
clock_t start,finish;
-
double elapsed1,elapsed2;
-
int row,col;
-
start=clock();
-
for(row=0;row<ROWS;row++)
-
for(col=0;col<COLS;col++)
-
a[row][col]=0;
-
finish=clock();
-
elapsed1=(double)(finish-start)/CLOCKS_PER_SEC;
-
start=clock();
-
for(col=0;col<COLS;col++)
-
for(row=0;row<ROWS;row++)
-
a[row][col]=0;
-
finish=clock();
-
elapsed2=(double)(finish-start)/CLOCKS_PER_SEC;
-
system("pause");
-
return 0;
-
}
输出:
the first loop cost 1.381000 seconds.
the second loop cost 6.880000 seconds.
这样哪个循环运行更快,一下子就看出来。