Crane
Table_bottom

Search
Loading
Table_bottom

分类
Table_bottom

随机文章
Table_bottom

标签云
Table_bottom

最新评论
Table_bottom

链接
Table_bottom

功能
Table_bottom

测试堆的最大申请数量

看到说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,所以到不了那么大吧!

 

 

 

 

求三个参数中最大两个的平方和

看到一题,实现一个函数,求三个函数中最大的两个参数的平方和。

很自然的,想到这样的方法:

int sum_square_largest(int x, int y, int z){

    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;
    }
}
但是可以看到中间的判断都是相似的,由此可就得一更简洁的方法,使用递归。
int sum_square_largest(int x, int y, int z){

    if (x <= y && x <= z){
        return y * y + z * z;
    }

    return sum_square_largest(y, z, x);
}
由于这里是尾递归,gcc优化会识别出这个,然后自动调整堆栈,不会出现函数开销在堆栈上花费很多时间资源的情况。

 
 

 

 

 

 

超级快速关机方法

最近不知什么问题,发现有时关机时停在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<stdio.h>
#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语言有点变态

直接看这个程序

 

#include<stdio.h>
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;
}

看着很神奇,至少有些我从来没那样写过,但是这些全部是合法的,可以编译通过。

 

比较程序的效率

今天老师给了个这样的题:

  1. 编写程序,测试两条循环语句的执行时间。分析为何执行时间不同。
  2.  
  3. int A[ROWS][COLS];
  4. for(row=0; row<ROWS;row++)
  5.     for(col=0;col<COLS;col++)
  6.        A[row][col]=0;
  7. for(col=0;col<COLS;col++)
  8.     for(row=0; row<ROWS; row++)
  9.        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,所以程序可以这样写:

 

  1. #include<stdio.h>
  2. #include<time.h>
  3. #include<stdlib.h>
  4. #define ROWS 10000
  5. #define COLS 10000
  6. int a[ROWS][COLS];
  7. main()
  8. {
  9.         clock_t start,finish;
  10.         double elapsed1,elapsed2;
  11.         int row,col;
  12.         start=clock();
  13.         for(row=0;row<ROWS;row++)
  14.         for(col=0;col<COLS;col++)
  15.         a[row][col]=0;
  16.         finish=clock();
  17.         elapsed1=(double)(finish-start)/CLOCKS_PER_SEC;
  18.         start=clock();
  19.         for(col=0;col<COLS;col++)
  20.         for(row=0;row<ROWS;row++)
  21.         a[row][col]=0;
  22.         finish=clock();
  23.         elapsed2=(double)(finish-start)/CLOCKS_PER_SEC;
  24.         printf("the first loop cost %f seconds.\n",elapsed1);
  25.         printf("the second loop cost %f seconds.\n",elapsed2);
  26.         system("pause");
  27.         return 0;
  28. }

输出:

the first loop cost 1.381000 seconds.
the second loop cost 6.880000 seconds.

这样哪个循环运行更快,一下子就看出来。