2014年12月30日 星期二

日期相差天數計算公式


對於一日期計算出一相對應的一整數N,再計算出兩整數相差即為相差天數。
方法如下:


    N=1461 * f(年) 
÷ 4 + 153 * g(月) ÷ 5 +日
    其中:
                   f(年)      = 年 - 1         
如果月<=2
                                 =年                其他情況

                    g(月)     =月+13         如果月<=2

                                  =月+1            其他情況
(對於1900/3/1以後上式都成立)


ex :  2004/2/1~2005/9/20
∵N1=1461 * 2003  ÷ 4 +153 * 15 ÷ 5 + 1
         =731595 + 459 + 1
         =732055

    N2=1461 * 2005 ÷ 4 +153 * 10 ÷ 5 +20
         = 732326 + 306 +20
         =732652


∴ N2 - N1 =  597 = 相差天數



C++ 判斷式   if (month<=2){
            month+=13;
            year-=1;}
        else{
            month+=1;
        }

用Execl測試過結果相同,但超過2100年後就開始有誤差了。

2014年12月25日 星期四

C++ 多态性的概念

多态性(polymorphism)是面向对象程序设计的一个重要特征。如果一种语言只支持类而不支持多态,是不能被称为面向对象语言的,只能说是基于对象的,如Ada、VB就属此类。C++支持多态性,在C++程序设计中能够实现多态性。利用多态性可以设计和实现一个易于扩展的系统。

顾名思义,多态的意思是一个事物有多种形态。多态性的英文单词polymorphism来源于希腊词根poly(意为“很多”)和morph(意为“形态”)。在C ++程序设计中,多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性的:向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。

其实,我们已经多次接触过多态性的现象,例如函数的重载、运算符重载都是多态现象。只是那时没有用到多态性这一专门术语而已。例如,使用运算符“+”使两个数值相加,就是发送一个消息,它要调用operator +函数。实际上,整型、单精度型、双精度型的加法操作过程是互不相同的,是由不同内容的函数实现的。显然,它们以不同的行为或方法来响应同一消息。

在现实生活中可以看到许多多态性的例子。如学校校长向社会发布一个消息:9月1日新学年开学。不同的对象会作出不同的响应:学生要准备好课本准时到校上课;家长要筹集学费;教师要备好课;后勤部门要准备好教室、宿舍和食堂……由于事先对各种人的任务已作了规定,因此,在得到同一个消息时,各种人都知道自己应当怎么做,这就是 多态性。可以设想,如果不利用多态性,那么校长就要分别给学生、家长、教师、后勤部门等许多不同的对象分别发通知,分别具体规定每一种人接到通知后应该怎么做。显然这是一件十分复杂而细致的工作。一人包揽一切,吃力还不讨好。现在,利用了多态性机制,校长在发布消息时,不必一一具体考虑不同类型人员是怎样执行的。至于各类人员在接到消息后应气做什么,并不是临时决定的,而是学校的工作机制事先安排决定好的。校长只需不断发布各种消息,各种人员就会按预定方案有条不紊地工作。

同样,在C++程序设计中,在不同的类中定义了其响应消息的方法,那么使用这些类 时,不必考虑它们是什么类型,只要发布消息即可。正如在使用运算符“ ”时不必考虑相加的数值是整型、单精度型还是双精度型,直接使用“+”,不论哪类数值都能实现相加。可以说这是以不变应万变的方法,不论对象千变万化,用户都是用同一形式的信息去调用它们,使它们根据事先的安排作出反应。

从系统实现的角度看,多态性分为两类:静态多态性和动态多态性。以前学过的函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时系统就能决定调用的是哪个函数,因此静态多态性又称编译时的多态性。静态多态性是通过函数的重载实现的(运算符重载实质上也是函数重载)。动态多态性是在程序运行过程中才动态地确定操作所针对的对象。它又称运行时的多态性。动态多态性是通过虚函数(Virtual fiinction)实现的。

有关静态多态性的应用,即函数的重载(请查看:C++函数重载)和运算符重载(请查看:C++运算符重载),已经介绍过了,这里主要介绍动态多态性和虚函数。要研究的问题是:当一个基类被继承为不同的派生类时,各派生类可以使用与基类成员相同的成员名,如果在运行时用同一个成员名调用类对象的成员,会调用哪个对象的成员?也就是说,通过继承而产生了相关的不同的派生类,与基类成员同名的成员在不同的派生类中有不同的含义。也可以说,多态性是“一个接口,多种 方法”。

2014年12月22日 星期一

C++ 中const的用法詳解

原創作者: 晁智平                      如轉貼請保留此行
const是用於保護程序的健壯性,減少程序隱患。
const的用法比較複雜,總結起來又分為以下兩種:
1:在定義變量時使用: 
   a: const int a=100; 最簡單的用法,說明變量a是一個常變量;
   b: int const b=100; 與a功能相同;
   c: const int *a=&b; 指向常數的指針,即指針本身的值是可以
      改變的,但指向的內容是不能改變的;
   d: int const *a=&b; 與c功能相同;
   e: int * const a = &b; 常指針,即指針本身的值是不可改變的,
      但指向的內容是可改變的;
   f: const int * const a = &b;指向常數的常指針,即指針本身與
      指向的內容都是不可改變的;
   g: const int &a=100; 常數引用,即不能改變引用的值;
  
   總結: 在使用const定義變量時,一定要進行初始化操作,在操作
   符(*,&)左邊的修飾的是指向的內容,在右邊的是本身。
  
2:在函數用使用:
   a: void func(const int a); 做為參數使用,說明函數體內是不
      能修改該參數的;對不參數定義時不同的形式,可參見定義變量
      時使用方式;
   b: const int func(); 做為返回值使用,說明函數的返回值是不
      能被修改的,在取得返回值時應用const int a = func();對不
      參數定義時不同的形式,可參見定義變量時使用方式;
   c: int func() const; 常函數,說明函數是不能修改類中成員的
      值的,只能用於類的成員函數中;
     
   總結:在函數中使用const,情況與定義變量的情況大致相同。

2014年12月19日 星期五

C++ cin & cout

输入和输出并不是C++语言中的正式组成成分。C和C++本身都没有为输入和输出提供专门的语句结构。输入输出不是由C++本身定义的,而是在编译系统提供的I/O库中定义的。

C++的输出和输入是用“流”(stream)的方式实现的。图3.2和图3.3表示C++通过流进行输入输出的过程。
有关流对象cin、cout和流运算符的定义等信s息是存放在C++的输入输出流库中的,因此如果在程序中使用cin、cout和流运算符,就必须使用预处理命令把头文件stream包含到本文件中:
    #include <iostream>
尽管cin和cout不是C++本身提供的语句,但是在不致混淆的情况下,为了叙述方便,常常把由cin和流提取运算符“>>”实现输入的语句称为输入语句或cin语句,把由cout和流插入运算符“<<”实现输出的语句称为输出语句或cout语句。根据C++的语法,凡是能实现某种操作而且最后以分号结束的都是语句。

输入流与输出流的基本操作

cout语句的一般格式为:
    cout<<表达式1<<表达式2<<……<<表达式n;

cin语句的一般格式为:
    cin>>变量1>>变量2>>……>>变量n;

在定义流对象时,系统会在内存中开辟一段缓冲区,用来暂存输入输出流的数据。在执行cout语句时,先把插入的数据顺序存放在输出缓冲区中,直到输出缓冲区满或遇到cout语句中的endl(或'\n',ends,flush)为止,此时将缓冲区中已有的数据一起输出,并清空缓冲区。输出流中的数据在系统默认的设备(一般为显示器)输出。

一个cout语句可以分写成若干行。如
    cout<<"This is a simple C++ program."<<endl;
可以写成
    cout<<"This is "  //注意行末尾无分号
    <<"a C++ "
    <<"program."
    <<endl; //语句最后有分号
也可写成多个cout语句,即
    cout<<"This is "; //语句末尾有分号
    cout <<"a C++ ";
    cout <<"program.";
    cout<<endl;
以上3种情况的输出均为
This is a simple C++ program.

注意,不能用一个插入运算符“<<”插入多个输出项,如:
    cout<<a,b,c; //错误,不能一次插入多项
    cout<<a+b+c; //正确,这是一个表达式,作为一项

在用cout输出时,用户不必通知计算机按何种类型输出,系统会自动判别输出数据的类型,使输出的数据按相应的类型输出。如已定义a为int型,b为float型,c为char型,则
    cout<<a<<' '<<b<<' '<<c<<endl;
会以下面的形式输出:
    4 345.789 a

与cout类似,一个cin语句可以分写成若干行。如
    cin>>a>>b>>c>>d;
可以写成
    cin>>a //注意行末尾无分号
    >>b //这样写可能看起来清晰些
    >>c
    >>d;
也可以写成
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;
以上3种情况均可以从键盘输入:
1  2  3  4 ↙

也可以分多行输入数据:
1↙
2  3↙
4↙

在用cin输入时,系统也会根据变量的类型从输入流中提取相应长度的字节。如有
   char c1, c2;
   int a;
   float b;
   cin>>c1>>c2>>a>>b;
如果输入
1234 56.78↙

注意: 34后面应该有空格以便和56.78分隔开。也可以按下面格式输入:
1 2 34 56.78↙ (在1和2之间有空格)

不能用cin语句把空格字符和回车换行符作为字符输入给字符变量,它们将被跳过。如果想将空格字符或回车换行符(或任何其他键盘上的字符)输入给字符变量,可以使用getchar函数。

在组织输入流数据时,要仔细分析cin语句中变量的类型,按照相应的格式输入,否则容易出错。

在输入流与输出流中使用控制符

上面介绍的是使用cout和cin时的默认格式。但有时人们在输入输出时有一些特殊的要求,如在输出实数时规定字段宽度,只保留两位小数,数据向左或向右对齐等。C++提供了在输入输出流中使用的控制符(有的书中称为操纵符),见表3.1。

表 3.1 输入输出流的控制符
控制符作 用
dec设置数值的基数为10
hex设置数值的基数为16
oct设置数值的基数为8
setfill(c)设置填充字符c,c可以是字符常量或字符变量
setprecision(n)设置浮点数的精度为n位。在以一般十进制小数形式输出时,n代表有效数字。在以fixed(固定小数位数)形式和 scientific(指数)形式输出时,n为小数位数
setw(n)设置字段宽度为n位
setiosflags( ios::fixed)设置浮点数以固定的小数位数显示
setiosftags( ios::scientific)设置浮点数以科学记数法(即指数形式)显示
setiosflags( ios::left)输出数据左对齐
setiosflags( ios::right)输出数据右对齐
setiosflags( ios::skipws)忽略前导的空格
setiosflags( ios::uppercase)数据以十六进制形式输出时字母以大写表示
setiosflags( ios::lowercase)数据以十六进制形式输出时宇母以小写表示
setiosflags(ios::showpos)输出正数时给出“+”号

需要注意的是: 如果使用了控制符,在程序单位的开头除了要加iostream头文件外,还要加iomanip头文件。

举例, 输出双精度数:
    double a=123.456789012345;  // 对a赋初值

1) cout<<a;  输出: 123.456
2) cout<<setprecision(9)<<a;  输出: 123.456789
3) cout<<setprecision(6);  恢复默认格式(精度为6)
4) cout<< setiosflags(ios∷fixed);  输出: 123.456789
5) cout<<setiosflags(ios∷fixed)<<setprecision(8)<<a;  输出: 123.45678901
6) cout<<setiosflags(ios∷scientific)<<a;  输出: 1.234568e+02
7) cout<<setiosflags(ios∷scientific)<<setprecision(4)<<a;  输出: 1.2346e02

下面是整数输出的例子:
    int b=123456;  // 对b赋初值
1) cout<<b;  输出: 123456
2) cout<<hex<<b;   输出: 1e240
3) cout<<setiosflags(ios∷uppercase)<<b;  输出: 1E240
4) cout<<setw(10)<<b<<','<<b;   输出:  123456,123456
5) cout<<setfill('*')<<setw(10)<<b;  输出: **** 123456
6) cout<<setiosflags(ios∷showpos)<<b;  输出: +123456

如果在多个cout语句中使用相同的setw(n),并使用setiosflags(ios::right),可以实现各行数据右对齐,如果指定相同的精度,可以实现上下小数点对齐。

2014年12月18日 星期四

C语言 sprintf与sscanf函数

1、前言
    我们经常涉及到数字与字符串之间的转换,例如将32位无符号整数的ip地址转换为点分十进制的ip地址字符串,或者反过来。从给定的字符串中提取相关内容,例如给定一个地址:http://www.bokeyuan.cn:2345,我们要从地址中提出协议,主机地址和端口号。之前对字符串和数字之间的关系不是很熟悉,工作中经常涉及到这个,如是好好总结一下。C语言提供了一些列的格式化输入输出函数,最基本的是面向控制台标准输出和输入的printf和scanf,其实还有面向字符串的sprint和sscanf,面向文件的流的fprintf和fscanf。今天着重总结一下sprintf和sscanf系列函数,这两个函数类似于scanf和printf ,不同点是从字符串*buffer用于输入输出。
2、sprintf函数
  sprintf函数原型为 int sprintf(char *str, const char *format, ...)作用是格式化字符串,具体功能如下所示:
(1)将数字变量转换为字符串。
(2)得到整型变量的16进制和8进制字符串。
(3)连接多个字符串。
举例如下所示:
复制代码
 1     char str[256] = { 0 };
 2     int data = 1024;
 3     //将data转换为字符串
 4     sprintf(str,"%d",data);
 5     //获取data的十六进制
 6     sprintf(str,"0x%X",data);
 7     //获取data的八进制
 8     sprintf(str,"0%o",data);
 9     const char *s1 = "Hello";
10     const char *s2 = "World";
11     //连接字符串s1和s2
12     sprintf(str,"%s %s",s1,s2);
复制代码
3、sscanf函数
    sscanf函数原型为int sscanf(const char *str, const char *format, ...)将参数str的字符串根据参数format字符串来转换并格式化数据,转换后的结果存于对应的参数内。具体功能如下:
(1)根据格式从字符串中提取数据。如从字符串中取出整数、浮点数和字符串等。
(2)取指定长度的字符串
(3)取到指定字符为止的字符串
(4)取仅包含指定字符集的字符串
(5)取到指定字符集为止的字符串
sscanf可以支持格式字符%[]:
(1)-: 表示范围,如:%[1-9]表示只读取1-9这几个数字 %[a-z]表示只读取a-z小写字母,类似地 %[A-Z]只读取大写字母
(2)^: 表示不取,如:%[^1]表示读取除'1'以外的所有字符 %[^/]表示除/以外的所有字符
(3),: 范围可以用","相连接 如%[1-9,a-z]表示同时取1-9数字和a-z小写字母 
(4)原则:从第一个在指定范围内的数字开始读取,到第一个不在范围内的数字结束%s 可以看成%[] 的一个特例 %[^ ](注意^后面有一个空格!)
解析网址的例子如下所示:
复制代码
 1     const char *s = "http://www.baidu.com:1234";
 2     char protocol[32] = { 0 };
 3     char host[128] = { 0 };
 4     char port[8] = { 0 };
 5     sscanf(s,"%[^:]://%[^:]:%[1-9]",protocol,host,port);
 6 
 7     printf("protocol: %s\n",protocol);
 8     printf("host: %s\n",host);
 9     printf("port: %s\n",port);
10     
复制代码
4、snprintf函数
  snprintf函数是sprintf函数的更加安全版本,考虑到字符串的字节数,防止了字符串溢出。函数形式为:int snprintf(char *restrict buf, size_t n, const char * restrict  format, ...);。最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为n 的话,将不会溢出。

2014年12月14日 星期日

C 語言 static 與 extern

在C中,談到可視範圍(scope)可分為許多層次,也可以談到很複雜,在這邊先談談「全域變數」(Global variable)、「區域變數」(Local variable)與「區塊變數」(Block variable)。

全域變數是指直接宣告在(主)函式之外的變數,這個變數在整個程式之中都「看」得它的存在,而可以呼叫使用,例如:

const double PI = 3.14159; 

doule area(double r) { 
    return r * r * PI; 
}

int main(void) { 
    // ..... 
    return 0; 

在這個例子中,PI這個變數可以被主函式main()與副函式area()來使用,通常全域變數是用來定義一些常數,初學者不應為了方便而將所有的變數都 設定為全域變數,否則將來一定會發生變數名稱管理上的問題,全域變數的生命週期始於程式開始之時,終止於程式結束之時。

區域變數是指宣告在函式之內的變數,或是宣告在參數列之前的變數,它的可視範圍只在宣告它的函式區塊之中,其它的函式不可以使用該變數,例如在上例的主函 式中,您不可以直接對area()函式中的變數r作出存取的動作,區域變數的生命週期開始於函式被呼叫之後,終止於函式執行完畢之時。

區塊變數是指宣告在某個陳述區塊之中的變數,例如while迴圈區塊中,或是for迴圈區塊,例如下面的變數i在迴圈結束之後,就會自動消失:

while(...) {
    int i = 0;
    // ....
}

當一可視範圍大的變數與可視範圍小的變數發生同名狀況時,可視範圍小的變數會暫時覆蓋可視範圍大的變數,稱之為「變數覆蓋」,例如: 

int num = 10;
int i;
for(i = 0; i < 100; i++)  {
    int num = 20;
    // ...
}
printf("%d", num);

這個程式最後顯示的 num 值仍是10,當執行迴圈時,迴圈內的 num 變數作用將覆蓋迴圈外的 num 變數;同樣的作用發生於全域變數與區域變數發生同名的時候。

再來介紹static變數,當變數有宣告時加上static限定時,一但變數生成,它就會一直存在記憶體之中,即使函式執行完畢,變數也不會消失,例如: 

#include <stdio.h>

void count(void);

int main(void) {
    int i;
    for(i = 0; i < 10; i++) {
        count();     
    }

    return 0;
}

void count(void) { 
    static int c = 1; 
    printf("%d\n", c); 
    c++; 
}

執行結果:
1
2
3
4
5
6
7
8
9
10


雖然變數c是在count()函式中宣告的,但是函式結束後,變數仍然存在,它會直到程式執行結束時才消失,雖然變數一直存在,但由於它是被宣告在函式之 中,所以函式之外仍無法存取static變數。

您可以宣告全域static變數,其在程式執行期間一直存在,但在一個原始程式文件中宣告全域static變數,還表示其可以存取的範圍僅限於該原始程式文件之中,您也可以將函式宣告為static:

static void some() {
    ...
}

一個static函式表示,其可以呼叫的範圍限於該原始碼文件之中,如果您有一些函式僅想在該原始程式文件之中使用,則可以宣告為static,這也可以避免與其他人寫的函式名稱衝突的問題。
extern可以聲明變數會在其它的位置被定義,這個位置可能是在同一份文件之中,或是在其它文件之中,例如: 

  • some.c
double someVar = 1000;
// 其它定義 ...

  • main.c
#include <stdio.h>

int main(void) {
    extern double someVar;
    
    printf("%f\n", someVar);
    
    return 0;
}

在main.c中實際上並沒有宣告someVar,extern指出someVar是在其它位置被定義,編譯器會試圖在其它位置或文件中找出 someVar的定義,結果在some.c中找到,因而會顯示結果為1000,要注意的是,extern聲明someVar在其它位置被定義,如果您 在使用extern時同時指定其值,則視為在該位置定義變數,結果就引發重覆定義錯誤,例如:

#include <stdio.h>

int main(void) {
    extern double someVar = 100; 
// error, `someVar' has both `extern' and initializer    
    ...
    return 0;
}

您必須先聲明extern找到變數,再重新指定其值,這麼使用才是正確的:

#include <stdio.h>

int main(void) {
    extern double someVar;
    
someVar = 100;
    ...
    return 0;
}

2014年12月11日 星期四

C 語言 字串處理

C 語言標準函數庫分類導覽 - 字串處理 string.h

標頭檔 string.h 宣告許多字串處理相關的函數,包括拷貝、相接、搜尋、測試相等、計算長度等。


以 str 起頭的函數作為處理字串之用,另有以 mem 起頭的函數,這些函數則可以進行記憶體區塊的操作。
 size_t 作為 sizeof 運算子的回傳型態,實際上可能為 unsigned int 或 unsigned long 。



以下函數可以拷貝字串
函數名稱功能函數原型
strcpy將字串 s2 拷貝到 s1char *strcpy(char *s1, const char *s2);
strncpy將字串 s2 最多 n 個字元拷貝到 s1char *strncpy(char *s1, const char *s2, size_t n);




以下函數可以將字串相接

函數名稱功能函數原型
strcat將字串 s2 接到 s1 的尾端char *strcat(char *s1, const char *s2);
strncat將字串 s2 最多 n 個字元接到 s1 的尾端char *strncat(char *s1, const char *s2, size_t);




以下函數測試兩個字串是否相等

函數名稱功能函數原型
strcmp比較 s1 與 s2 兩個字串是否相等int strcmp(const char *s1, const char *s2);
strncmp比較 s1 與 s2 兩個字串前 n 個字元是否相等int strncmp(const char *s1, const char *s2, size_t n);




以下函數作為字串的搜尋處理之用

函數名稱功能函數原型
strchr回傳在字串 s 中,字元 c 第一次出現位置的指標char *strchr(const char *s, int c);
strcspn計算經過幾個字元會在字串 s1 中遇到屬於 s2 中的字元size_t strcspn(const char *s1, const char *s2);
strspn計算經過幾個字元會在字串 s1 中遇到不屬於 s2 中的字元size_t strspn(const char *s1, const char *s2);
strpbrk回傳在字串 s2 中的任何字元在 s1 第一次出現位置的指標char *strpbrk(const char *s1, const char *s2);
strrchr回傳在字串 s 中,字元 c 最後一次出現位置的指標char *strrchr(const char *s, int c);
strstr回傳在字串 s2 在 s1 第一次出現位置的指標char *strstr(const char *s1, const char *s2);
strtok以字串 s2 的內容切割 s1char *strtok(char *s1, const char *s2);




以下函數計算字串的長度

函數名稱功能函數原型
strlen計算字串的長度size_t strlen(const char *s);




以下函數為進行記憶體區塊操作之用

函數名稱功能函數原型
memcpy從 s2 所指向的資料複製 n 個字元到 s1void *memcpy(void *s1, const void *s2, size_t n);
memmove從 s2 所指向的資料複製 n 個字元到 s1void *memmove(void *s1, const void *s2, size_t n);
memcmp比較 s1 與 s2 前 n 個字元的資料int memcmp(const void *s1, const void *s2, size_t n);
memchr找出字元 c 在 s 前 n 個字元第一次出現的位置void *memchr(const void *s, int c, size_t n);
memset將 s 中前 n 個字元全部設定為 cvoid *memset(void *s, int c, size_t n);

DNS資源紀錄(Resource Record)介紹

DNS server內的每一個網域名稱都有自己的檔案,這個檔案一般會稱為區域檔案 (zone file),例如之前所提到的”named.ca”或”named.local” 檔案…等等。區域檔案是由多個記錄組成的,每一個記錄稱為資源記錄(Resource Record,簡稱RR)。當在設定DNS名稱解析、反向解析及其他的管理目的時,您需要使用不同類型的RR,底下將介紹常用的RR類型及表示法。



類型

SOA

Start Of Authority,這種 record 放在 zone file 一開始的地方,每一個記錄檔只能有一個 SOA,而且一定是檔案中第一個“記錄”,它描述這個 zone 負責的 name server,version number…等資料,以及當 slave server 要備份這個 zone 時的一些參數。 緊接在 SOA 後面指定了這個區域的授權主機和管理者的信箱,這裡分別是 "school.edu.tw" 和" root.school.edu.tw",也就是school.edu.tw主機和 root 的信箱。這裡要注意的是我們以"root.school.edu.tw"代表"root@school.edu.tw"
e.g.
@ IN SOA school.edu.tw. root.school.edu.tw. (
1999051401 ; Serial
300 ; Retry
3600 ; Refresh 3600000 ; Expire
3600 ) ; Minimum
在兩個括號中間的選項表示SOA的設定內容,底下會有更詳細的說明。

NS

name server,用來指定操作的DNS伺服器主機名稱,需注意的是不可以IP位址表示。
e.g.
IN NS dns.twnic.net.tw.

A

address,將DNS網域名稱對應到IPv4的32位元位址。
e.g.
server IN A 140.123.102.10

AAAA

可將DNS網域名稱對應到IPv6的128位元位址。
e.g.
twnic.net.tw. 86400 IN AAAA 3ffe: :bbb:93:5

PTR

pointer,定義某個 IP 對應的 domain name,即將 IP 位址轉換成主機的FQDN。
e.g.
20 IN PTR mail.twnic.net.tw.

CNAME

canonical name,可為同一部主機設定許多別名,例如 mix.twnic.net.tw的別名可為 www.twnic.net.tw和 ftp.twnic.net.tw,因此所設定的別名都會連至同一部伺服器。
e.g.
www IN CNAME mix

MX

mail exchanger,設定區域中擔任郵件伺服器的主機,所有要送往那部機器的 mail 都要經過 mail exchanger 轉送。而數字則是該主機郵件傳遞時的優先次序,此值越低表示有越高的郵件處理優先權。
e.g.
server IN MX 10 mail.twnic.net.tw.

SOA設定內容說明

SOA record,以之前例子來看,其中 @ 這個符號是縮寫,代表 named.conf 中這個 zone file 所對應的 zone。 SOA 後面的兩個參數是指這個 zone file 是在哪部主機 (school.edu.tw)定義的,以及這個 zone file 的負責人 (注意是寫成 root.school.edu.tw),然後是用括號括起來的 5 個參數, 分別由底下說明。

Serial

代表這個 zone file 的版本,每當 zone file 內容有變動,name server 管理者就應該增加這個號碼,因為 slave 會將這個號碼與其 copy 的那份比對以便決定是否要再 copy 一次 (即進行 zone transfer)。

Refresh

slave server 每隔這段時間(秒),就會檢查 master server 上的 serial number。不過這裡會發生一個問題就是,在 master server 在 update data 完成到 slave server 來檢查時再 update 可能還有 好一段時間,因此這段期間 master/slave DNS server間 zone files 就可能出現不一致。所以在Bind較新的版本中便加入"notify"功能,使用者在 "named.conf" 設定中在需要的 zone 中加入"notify"的設定,則 master server在 update 完成某個 zone file 的 data 後便會主動發個訊息(NOTIFY),藉以通知該其它的 slave servers,因此如果 slave servers 也有支援這個"notify"功能時,接下來 slave servers 馬上就可以做 zone transfer 來update data。
e.g.
zone "twnic.com.tw" {
type master;
notify yes;
file "twnic.hosts";
also-notify { 192.168.10.1; }; //指定slave server的IP位址
};

Retry

當 slave server 無法和 master 進行 serial check時,要每隔幾秒 retry 一次。

Expire

當時間超過 Expire 所定的秒數而 slave server 都無法和 master 取得連絡,那麼 slave 會刪除自己的這份 copy。

Minimum

代表這個 zone file 中所有 record 的內定的 TTL 值,也就是其它的 DNS server cache 這筆 record 時,最長不應該超過這個時間。