6.15

来源:互联网 发布:淘宝毛绒玩具熊 编辑:程序博客网 时间:2024/05/16 05:59

13.

关于C语言编程中经常使用的“NULL”的问题》。。。。。

其实定义NULL的方法有好几种,常见的有:
#define NULL 0
#define NULL (char *)0
#define NULL (void *)0
在我们使用的绝大多数计算系统上,例如PC,上述定义是能够工作的。然而,世界上还有很多其它种类的计算机,其CPU也不是Intel的。在某些系统上,指针和整数的大小和内部表示并不一致,甚至不同类型的指针的大小都不一致。为了避免这种可移植性问题,0L是一种最为安全的、最妥帖的定义方式。0L的含义是: “值为0的整数常量表达式”。这与C语言给出的空指针定义完全一致。因此,建议采用0L作为空指针常量NULL的值。
  其实 NULL定义值,和操作系统的的平台有关, 将一个指针定义为 NULL, 其用意是为了保护操作系统,因为通过指针可以访问任何一块地址, 但是,有些数据是不许一般用户访问的,比如操作系统的核心数据。 当我们通过一个空(NULL)的指针去方位数据时,系统会提示非法, 那么系统又是如何知道的呢??
  以windows2000系统为例, 该系统规定系统中每个进程的起始地址(0x00000000)开始的某个地址范围内是存放系统数据的,用户进程无法访问, 所以当用户用空指针(0)访问时,其实访问的就是0x00000000地址的系统数据,由于该地址数据是受系统保护的,所以系统会提示错误(指针访问非法)。
  这也就是说NULL值不一定要定义成0,起始只要定义在系统的保护范围的地址空间内,比如定义成(0x00000001, 0x00000002)都会起到相同的作用,但是为了考虑到移植性,普遍定义为0 。


应当将指针变量用“==”或“!=”与NULL比较。
指针变量的零值是“空”(记为NULL)。尽管NULL的值与0相同,但是两者意义不同。假设指针变量的名字为p,它与零值比较的标准if语句如下:
if (p == NULL)// p与NULL显式比较,强调p是指针变量
if (p != NULL)
不要写成
if (p == 0) // 容易让人误解p是整型变量
if (p != 0)   
或者
if (p)// 容易让人误解p是布尔变量
if (!p)

在C中,通常用 NULL 来表示一个值为 0 的指针常量(null指针)。为了表示其指针类型的特征,一般是这样定义的:

#define NULL (void*)0;

因为在C中 void 指针和其它类型的指针是可以默认转换的。不能定义为

#define NULL (char*)0;

这样会给使用上带来麻烦,因为 char 型指针和其它类型不能默认转换。这种形式的定义是在 void 还没有引入到C语言中来的时候使用的形式,一种古老的形式。

#define NULL (void*)0;这种定义在C++中会带来不便,因为 void 指针不能默认转换为其它类型的指针。因此,对于C++中的null指针人们更倾向于直接用 0 来表示,而不是用 NULL,因为使用 NULL 有时还需要显式的类型转换。

 


14.

如何在c语言中获取程序运行时间?精度到毫秒


#include <time.h>
#include <stdio.h>
#include <dos.h>

int main(void)
{
clock_t start, end;
start = clock();

delay(2000);

end = clock();

printf("The time was: %f/n", (end - start) / CLK_TCK);


getch();
}

 如果是MFC可以用CTime类,如果不是就用如下介绍的方法了

很多情況下我們必須取得系統時間(像是交作業...),
但是系統時間要如何取得呢?

TurboC 提供了 time(); (被定義在 <time.h> 中) 這個函式供我們取得系統時間,
當我們執行了 time(NULL); 時, 該函式便會傳回一個 time_t 型態(被定義在 <time.h> 中)
的數字, 單位是"秒", 所以我們應該先用 time_t 宣告一個變數, 來接收 time() 的傳回值:

  time_t T;        // 宣告變數 T 為 time_t 型態 //
  T = time(NULL);  // 變數 T 等於 time(NULL) 的傳回值 //

於是變數 T 便接收到了一個單位為"秒"的超大整數, 而這個整數所代表的意義就是:
  從西元 1970年 1月 1日 0點 0分 0秒 到目前所經過的秒數,
哇! 這不就是我們所要的系統時間嗎....
但是如果不能換成我們所熟悉的<年/月/日 時:分:秒>表示法就沒意義了.


<如何將系統時間轉成一般表示法>

好不容易取得的系統時間居然長這副德性, 數學好的同學可能會想要排除萬難,
利用精湛的除法, 解決閏年的問題, 一個個將年/月/日/時/分/秒算出來...
不過這樣一來考試題目可能得帶回家寫,
TurboC 又提供了一個 localtime(); (被定義在 <time.h> 中) 這個函式就有分割
time_t 型態資料的功能, 根據 on-line Help 的介紹大致如下:

  struct tm *  localtime( time_t * );
  -----------  ---------  --------
從這裡可以看出 localtime 需要知道一個 time_t 型態的資料的位址,
然後傳回一個 struct tm 結構的資料的位址.

這下問題來了, 要告訴 localtime() time_t 變數的位址很簡單, 方法如下:
  time_t T;          // 宣告一個 time_t 型態的變數 T //
  T = time(NULL);    // T = 系統時間 //
  localtime(&T);     // 將 T 的位址 &T 丟給 localtime() //

這樣就好了, 但是 struct tm 到底是什麼呢? 
                (struct 就是結構, 用法類似 class 但無 Member function )
在 on-line Help 中看到 tm 的介紹如下:
  <TIME.H>           // 被 <time.h> 定義 //
  struct tm {
    int tm_sec;      /* 秒 (0--59) */
    int tm_min;      /* 分 (0--59) */
    int tm_hour;     /* 時 (0--23) */
    int tm_mday;     /* 日 of month (1--31) */
    int tm_mon;      /* 月 (0--11 記得自己 + 1) */
    int tm_year;     /* 年 (要把這個值 +1900 才是西元年紀喔) */
    int tm_wday;     /* 日 of Week (0--6; Sunday = 0) */
    int tm_yday;     /* 日 of year (0--365) */
    int tm_isdst;    /* 0 if daylight savings time is not in effect) */
  };
看到這個就大概可以知道, localtime() 先將我們給的 time_t 資料換算成
年/月/日/時/分/秒, 然後依照結構 tm 的順序放在記憶體中,
並將該記憶體位址傳回.
原來如此, 那我們不就只要宣告一個 tm 型態的指標, 然後將該指標指向
localtime() 的傳回值, 然後再讀取該指標的內容就好啦^^ 馬上試試:

#i nclude<time.h>
#i nclude<iostream.h>

void main(void)
{
  int year, mon, day;  // 要用來存日期的 //
  int hour, min, sec;  // 要用來存時間的 //
  time_t T;            // 要用來存系統時間的 //
  struct tm *TimeP;   // 要用來指到 localtime() 傳回的位址的 //

  T = time(NULL);      // 將系統時間存到 T //
 
  TimeP = localtime( &T );  // TimeP 指到 localtime 算好的資料所在位址 //

  // 接下來就來看 TimeP 所指到的地方放了什麼 ^^ //

  year = ( TimeP->tm_year ) + 1900;
  mon  = ( TimeP->tm_mon ) + 1;
  day  = ( TimeP->tm_mday );

  hour = ( TimeP->tm_hour );
  min  = ( TimeP->tm_min );
  sec  = ( TimeP->tm_sec );

  cout << year << "/" << mon << "/" << day << endl;
  cout << hour << ":" << min << ":" << sec << endl;
}

結果果然 localtime() 已經幫我們把 T 的資料換算好了(感動~~),
而我們從 TimeP 指出去的各成員也都傳回正確的數據, 連日期都沒問題^^