国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

C標準庫源碼解剖(1):類型相關的定義

2024-07-10 13:27:13
字體:
來源:轉載
供稿:網友

說明:整個C標準庫解剖系列環境為Ubuntu 8.04,編譯器為gcc 4.2.4,由于linux系統中只有C標準庫的頭文件(在/usr/include下),函數庫被編譯成了程序庫,沒有源代碼,因此對源代碼的解剖用的是glibc 2.9,可從GNU的官方站點上下載。
    類型相關定義包括limits.h、float.h、stddef.h、stdbool.h、stdarg.h、iso646.h、stdint.h共7個頭文件。除了stdint.h外,其余6個文件在gcc編譯器的/usr/lib/gcc/i486-linux-gnu/4.2.4/include目錄下。stdint.h在/usr/include中,是C99中引入的,提供了擴展整數的基本定義,放到后面再解剖吧。
    1、limits.h: 定義了整數類型的范圍。/usr/include下也有limits.h,它會自己先定義各個整數類型范圍,這樣當不用gcc來構建你的程序時就可以使用這些值。如果使用gcc編譯器來構建你的程序,則會使用gcc編譯器自己的limits.h(前面的定義都會#undef掉)。由于這個limits.h會用到gcc內置的limits.h,因此我們解剖/usr/include下的limits.h。

 

[cpp] view plaincopy
  1. /* ISO C99 Standard: 7.10/5.2.4.2.1  整數類型的大小  <limits.h> */  
  2. #ifndef _LIBC_LIMITS_H_  
  3. #define _LIBC_LIMITS_H_ 1  
  4. #include <features.h> /* 選項的宏,如ISOC99選項、POSIX選項、XOPEN選項等 */  
  5. #define MB_LEN_MAX  16  /* 支持區域設置的多字節字符寬度為16位 */  
  6. /* 不使用GNU CC時就必須定義下面所有符號,否則使用gcc編譯器中的定義(看下面) */  
  7. #if !defined __GNUC__ || __GNUC__ < 2   
  8. # ifndef _LIMITS_H  
  9. #  define _LIMITS_H 1  
  10. #include <bits/wordsize.h> /* 定義了表示字的位數的__WORDSIZE宏,64位平臺上值為64,32位平臺上值為32 */  
  11. #  define CHAR_BIT  8 /* char類型的寬度為8位 */  
  12. #  define SCHAR_MIN (-128)  /* signed char的最小值為-2^7,補碼表示為10000000,沒有對應的正數,其反數還是自己 */  
  13. #  define SCHAR_MAX 127     /* signed char的最大值為2^7-1=01111111 */  
  14. #  define UCHAR_MAX 255  /* unsigend char的最大值為2^8-1=11111111(最小值為0) */  
  15. #  ifdef __CHAR_UNSIGNED__  /* 根據預定義宏來確定是讓char=unsigned char還是char=signed char */  
  16. #   define CHAR_MIN 0  
  17. #   define CHAR_MAX UCHAR_MAX  
  18. #  else  
  19. #   define CHAR_MIN SCHAR_MIN   /* gcc中使用了這個,即char=signed char */  
  20. #   define CHAR_MAX SCHAR_MAX  
  21. #  endif  
  22. #  define SHRT_MIN  (-32768) /* signed short int的最小值為-2^15 */  
  23. #  define SHRT_MAX  32767    /* signed short int的最小值為2^15-1 */  
  24. #  define USHRT_MAX 65535  /* unsigned short int的最大值為2^16-1(最小值為0) */  
  25. #  define INT_MIN   (-INT_MAX - 1) /* int的最小值為-2^31 */  
  26. #  define INT_MAX   2147483647  /* int的最大值為2^31-1 */  
  27. #  define UINT_MAX  4294967295U  /* unsigned int的最大值為2^32-1(最小值為0) */  
  28. #  if __WORDSIZE == 64  /* 64位的x86平臺,這個宏在<bits/wordsize.h>中 */  
  29. #   define LONG_MAX 9223372036854775807L  /* signed long int最大值為2^63-1 */  
  30. #  else             /* 32位的x86平臺 */  
  31. #   define LONG_MAX 2147483647L  /* signed long int最大值為2^31-1 */  
  32. #  endif  
  33. #  define LONG_MIN  (-LONG_MAX - 1L)  /* signed long int最小值為-2^31 */  
  34. #  if __WORDSIZE == 64    
  35. #   define ULONG_MAX    18446744073709551615UL /* 64平臺:unsigend long int最大值為2^64-1 */  
  36. #  else  
  37. #   define ULONG_MAX    4294967295UL /* 32位平臺:unsigned long int最大值為2^32-1 */  
  38. #  endif  
  39. #  ifdef __USE_ISOC99  /* <feature.h>中宏:long long類型為C99標準引入的 */  
  40. #   define LLONG_MAX    9223372036854775807LL  /* signed long long int最大值為2^63-1 */  
  41. #   define LLONG_MIN    (-LLONG_MAX - 1LL)  /* signed long long int最小值為-2^63 */  
  42. #   define ULLONG_MAX   18446744073709551615ULL /* unsigned long long int最大值為2^64-1 */  
  43. #  endif /* ISO C99 */  
  44. # endif /* limits.h  */  
  45. #endif  /* GCC 2.  */  
  46. #endif  /* !_LIBC_LIMITS_H_ */  
  47. /* 獲取編譯器的limits.h,其中定義幾乎所有的ISO常量 */  
  48. #if defined __GNUC__ && !defined _GCC_LIMITS_H_  /* _GCC_LIMITS_H_是GCC的文件定義  */  
  49. # include_next <limits.h>  
  50. #endif  
  51. /* 一些gcc版本的<limits.h>沒有定義LLONG_MIN、LLONG_MAX和ULLONG_MAX,則這里需要進行定義 */  
  52. #if defined __USE_ISOC99 && defined __GNUC__  
  53. # ifndef LLONG_MIN  
  54. #  define LLONG_MIN (-LLONG_MAX-1)  
  55. # endif  
  56. # ifndef LLONG_MAX  
  57. #  define LLONG_MAX __LONG_LONG_MAX__  
  58. # endif  
  59. # ifndef ULLONG_MAX  
  60. #  define ULLONG_MAX    (LLONG_MAX * 2ULL + 1)  
  61. # endif  
  62. #endif  
  63. #ifdef  __USE_POSIX  
  64. /* POSIX添加東西到<limits.h>中 */  
  65. # include <bits/posix1_lim.h>  
  66. #endif  
  67. #ifdef  __USE_POSIX2  
  68. # include <bits/posix2_lim.h>  
  69. #endif  
  70. #ifdef  __USE_XOPEN  
  71. # include <bits/xopen_lim.h>  
  72. #endif  

 

    解釋:
    (1)/usr/include/limits.h的實現中,char=unsigned char占8位,short占16位,int占32位,long在64位平臺上占64位,在32位平臺上占32位,C99標準引入的long long占64位。它們都有singed和unsigned兩種,默認都是帶符號整數(signed)。帶符號整數在當前大多數體系結構上一般都用二進制補碼表示(當然C標準也支持用其他一些編碼表示),即正數用直接編碼,符號位為0;負數表示為對應正數各位取反然后加1,符號位為1。帶符號整數范圍為-2**(n-1)~2**(n-1)-1,其中最小負數-2**(n-1)=100...0沒有對應正數,其反數還是自己。無符號整數用直接二進制編碼,范圍為0~2**n-1。如果使用gcc的limits.h,則每個宏的值依賴于gcc編譯器內置的定義,一般跟這里的值一致。
    (2)UCHAR_MAX必須等于2**CHAR_BIT-1,且對帶符號整數一般有MIN=-MAX-1。
    (3)feature.h文件中定義了一些表示編譯選項的宏,如ISOC99選項、POSIX選項、XOPEN選項等。bits/wordsize.h定義了表示字的位數的__WORDSIZE宏,64位平臺上值為64,32位平臺上值為32。它們都在/usr/include下。
    (4)如果要新遵循C99標準,則有些gcc版本的<limits.h>可能沒有定義LLONG_MIN、LLONG_MAX和ULLONG_MAX,則這里需要進行定義。如果使用POSIX標準,則還要添加一些POSIX中的東西。
    2、float.h: 定義了浮點數類型的特征。

 

[cpp] view plaincopy
  1. /* ISO C Standard: 5.2.4.2.2  浮點數類型的特征  <float.h> */  
  2. #ifndef _FLOAT_H___  
  3. #define _FLOAT_H___  
  4. /* 實數浮點數表示: 
  5.    x=s*(b**e)*[f1*b**(-1)+f2*b**(-2)+...+fp*b**(-p)], emin<=e<=emax,(**表示求冪) 
  6.    s  是符號(+1或-1) 
  7.    b  是進制基數(通常為2、8、16) 
  8.    e  是指數值,取值范圍在emin與emax之間 
  9.    p  是b進制的有效位數 
  10.    fk  是有效數字,0<=fk<b 
  11.  */  
  12.    
  13. /* b:指數表示法的基數 */  
  14. #undef FLT_RADIX  
  15. #define FLT_RADIX   __FLT_RADIX__  /* 進制基數b,一般為2,適用于所有三種浮點類型 */  
  16. /* p:是b進制的有效位數  */  
  17. #undef FLT_MANT_DIG  
  18. #undef DBL_MANT_DIG  
  19. #undef LDBL_MANT_DIG  
  20. #define FLT_MANT_DIG    __FLT_MANT_DIG__   /* float的b進制有效位數p */  
  21. #define DBL_MANT_DIG    __DBL_MANT_DIG__   /* double的b進制有效位數p */  
  22. #define LDBL_MANT_DIG   __LDBL_MANT_DIG__  /* long double的b進制有效位數p */  
  23. /* q:精度小數位數。使任何有q個小數位的浮點數能被舍入成有p個b進制位數的浮點數,并且不需要改變這q個小數位 
  24.     就可以重新轉換回來。q的值為: 
  25.     p * log10(b)            如果b是10的冪 
  26.     floor((p - 1) * log10(b))   否則 
  27. */  
  28. #undef FLT_DIG  
  29. #undef DBL_DIG  
  30. #undef LDBL_DIG  
  31. #define FLT_DIG     __FLT_DIG__  /* float的精度小數位數,通常為6 */  
  32. #define DBL_DIG     __DBL_DIG__  /* double的精度小數位數,通常為10 */  
  33. #define LDBL_DIG    __LDBL_DIG__  /* long double的精度小數位數,通常為10 */  
  34. /* emin:最小負整數x,使b**(x-1)在規格化浮點數類型取值范圍內 */  
  35. #undef FLT_MIN_EXP  
  36. #undef DBL_MIN_EXP  
  37. #undef LDBL_MIN_EXP  
  38. #define FLT_MIN_EXP __FLT_MIN_EXP__  /* float的emin */  
  39. #define DBL_MIN_EXP __DBL_MIN_EXP__   /* double的emin */  
  40. #define LDBL_MIN_EXP    __LDBL_MIN_EXP__   /* long double的emin */  
  41. /* ceil(log10(b)*(emin-1)):最小負整數x,使10**(x-1)在 
  42.     規格化浮點數類型取值范圍內,通常值為-37 
  43. */  
  44. #undef FLT_MIN_10_EXP  
  45. #undef DBL_MIN_10_EXP  
  46. #undef LDBL_MIN_10_EXP  
  47. #define FLT_MIN_10_EXP  __FLT_MIN_10_EXP__  
  48. #define DBL_MIN_10_EXP  __DBL_MIN_10_EXP__  
  49. #define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__  
  50. /* emax:最大整數x,使b**(x-1)在可表示的有限浮點數取值范圍內 */  
  51. #undef FLT_MAX_EXP  
  52. #undef DBL_MAX_EXP  
  53. #undef LDBL_MAX_EXP  
  54. #define FLT_MAX_EXP __FLT_MAX_EXP__  /* float的emax */  
  55. #define DBL_MAX_EXP __DBL_MAX_EXP__  /* double的emax */  
  56. #define LDBL_MAX_EXP    __LDBL_MAX_EXP__  /* long double的emax */  
  57. /* floor(log10((1 - b**-p) * b**emax)):最大整數x,使10**x在可 
  58.     表示的有限浮點數取值范圍內,通常值為37 
  59. */  
  60. #undef FLT_MAX_10_EXP  
  61. #undef DBL_MAX_10_EXP  
  62. #undef LDBL_MAX_10_EXP  
  63. #define FLT_MAX_10_EXP  __FLT_MAX_10_EXP__  
  64. #define DBL_MAX_10_EXP  __DBL_MAX_10_EXP__  
  65. #define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__  
  66. /* (1-b**-p)*b**emax:可表示的最大有限浮點數, 通常值為10**37 */  
  67. #undef FLT_MAX  
  68. #undef DBL_MAX  
  69. #undef LDBL_MAX  
  70. #define FLT_MAX     __FLT_MAX__  
  71. #define DBL_MAX     __DBL_MAX__  
  72. #define LDBL_MAX    __LDBL_MAX__  
  73. /* b**(1-p):最小的x(x>0.0),使1.0+x>1.0,宏定義為允許的最大值,如對 
  74.    float為10**-5,對double和long double為10**-9  */  
  75. #undef FLT_EPSILON  
  76. #undef DBL_EPSILON  
  77. #undef LDBL_EPSILON  
  78. #define FLT_EPSILON __FLT_EPSILON__  
  79. #define DBL_EPSILON __DBL_EPSILON__  
  80. #define LDBL_EPSILON    __LDBL_EPSILON__  
  81. /* b**(emin - 1):最小規格化正數,通常值為10**-37  */  
  82. #undef FLT_MIN  
  83. #undef DBL_MIN  
  84. #undef LDBL_MIN  
  85. #define FLT_MIN     __FLT_MIN__  
  86. #define DBL_MIN     __DBL_MIN__  
  87. #define LDBL_MIN    __LDBL_MIN__  
  88. /* 舍入方式:0:向0舍入;1:最近舍入;2:向正無窮大舍入;3:向負無窮d大舍入;-1:不確定, 
  89.     適用于所有3種浮點類型 */  
  90. #undef FLT_ROUNDS  
  91. #define FLT_ROUNDS 1 /* 使用最近舍入方式 */  
  92. #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L  
  93. /* 浮點表達式求值方法(C99中引入): 
  94.    -1  不確定 
  95.     0  求值時仍保持原類型的精度與取值范圍 
  96.     1  求值時float類型與double類型統一用double類型;long double類型保持不變 
  97.     2  求值時全部用long double類型 
  98. */  
  99. #undef FLT_EVAL_METHOD  
  100. #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__  
  101. /* n(C99中引入):小數位數,使任何有pmax個b進制數位的最寬浮點數類型能被舍入 
  102.     成有n個小數位的浮點數,并且無需改變這個值就可以重新轉換回來。n的值為: 
  103.     pmax * log10(b)         如果b是10的冪 
  104.     ceil(1 + pmax * log10(b))   否則 
  105. */  
  106. #undef DECIMAL_DIG  
  107. #define DECIMAL_DIG __DECIMAL_DIG__  /* 通常的值為10 */  
  108. #endif /* C99 */  
  109. #endif /* _FLOAT_H___ */  

 

    解釋:
    (1)浮點數的形式為x=s*(b**e)*[f1*b**(-1)+f2*b**(-2)+...+fp*b**(-p)], emin<=e<=emax(**表示求冪)。s是符號位,b是進制基數,e是指數值,p是b進制的有效位數,0<=fk<b。
    (2)IEEE的浮點數表示法:單精度float型有1位符號位S,8位指數E,23位尾數M。轉換成數值V=(-1)**S*1.M*2**(E-127)。例如16.5=00010000.1=1.00001*2**4(成為規格化數),則符號位為0,指數位為4+127=131=10000011(因為指數可以為負,8位有符號數的范圍為-128~127,為了統一用無符號數表示,要加上127),尾數為00001000000000000000000,拼接起來即得到16.5的內存表示01000001100001000000000000000000。
    (3)常用的宏有FLT_DIG/DBL_DIG/LDBL_DIG、FLT_MIN/DBL_MIN/LDBL_MIN、FLT_MAX/DBL_MAX/LDBL_MAX。
    3、stddef.h: 定義了ptrdiff_t、size_t、wchar_t、wint_t類型和offsetof。有一大堆兼容不同平臺的條件編譯宏,這對我們沒什么用,略去。

 

[cpp] view plaincopy
  1. /* ISO C Standard: 7.17  一些通用定義  <stddef.h> */  
  2. typedef __PTRDIFF_TYPE__ ptrdiff_t;  /* 定義帶符號整數類型ptrdiff_t,這里__PTRDIFF_TYPE__ 
  3.                                                   依賴于平臺,通常為long類型 */  
  4. #if !(defined (__GNUG__) && defined (size_t))  
  5. typedef __SIZE_TYPE__ size_t/* 定義無符號整型size_t,__SIZE_TYPE__ 
  6.                                          依賴于平臺,通常為unsigned int或unsigned long類型 */  
  7. #ifdef __BEOS__  
  8. typedef long ssize_t;  /* 只用于BeOS系統中 */  
  9. #endif   
  10. #endif  
  11. typedef _BSD_RUNE_T_ rune_t; /* 只用于老的BSD系統 */  
  12. #ifndef _RUNE_T_DECLARED  
  13. typedef __rune_t rune_t;  /* 只用于FreeBSD系統中 */  
  14. #define _RUNE_T_DECLARED  
  15. #endif  
  16. #ifndef __WCHAR_TYPE__  
  17. #define __WCHAR_TYPE__ int  
  18. #endif  
  19. #ifndef __cplusplus  /* C中才要定義wchar_t,C++中wchar_t為內置類型 */  
  20. typedef __WCHAR_TYPE__ wchar_t/* 寬字符類型wchar_t也在stddef.h中定義,這里為int類型 */  
  21. #endif  
  22. #ifndef __WINT_TYPE__  
  23. #define __WINT_TYPE__ unsigned int  
  24. #endif  
  25. typedef __WINT_TYPE__ wint_t;   /* 用于無符號的寬字符類型中 */  
  26. #ifndef __cplusplus  
  27. #define NULL ((void *)0)  /* C中定義NULL指針常量為(void*)0 */  
  28. #else    
  29. #define NULL 0   /* C++中定義NULL指針常量為0 */  
  30. #endif  
  31. #ifdef _STDDEF_H  
  32. /* 結構成員的地址偏移字節數,TYPE結構類型,MEMBER為其某個成員 */  
  33. #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)  
  34. #endif  

 

    ptrdiff_t是兩個指針相減所得的帶符號整型,一般用long類型表示。size_t是sizeof運算得到的無符號整型,一般用unsigned int或unsigned long表示。寬字符類型wchar_t也在stddef.h中定義,這里為int類型。wint_t用于無符號的寬字符類型中,這里為unsigned int類型。offsetof宏用于計算結構成員的地址偏移字節數。       
    4、stdbool.h: 是C99中增加的,定義了布爾類型bool,及其兩個常量false=0、true=1。__bool_true_false_are_defined=1是標識布爾類型定義是否完成的信號。這些定義與C++中的一致,因此標準C++并不需要另外再支持stdbool.h,但GCC提供了這個擴展,使得在C++中可以支持<stdbool.h>。

 

[cpp] view plaincopy
  1. /* ISO C Standard:  7.16  布爾類型及其值  <stdbool.h> 
  2.  */  
  3. #ifndef _STDBOOL_H  
  4. #define _STDBOOL_H  
  5. #ifndef __cplusplus    
  6. #define bool    _Bool  /* C中 */  
  7. #define true    1  
  8. #define false   0  
  9. #else /* C++中 */  
  10. /* 在C++中支持<stdbool.h>是GCC的一個擴展 */  
  11. #define _Bool   bool  
  12. #define bool    bool  
  13. #define false   false  
  14. #define true    true  
  15. #endif /* __cplusplus */  
  16. /* 標識布爾類型定義是否完成的信號  */  
  17. #define __bool_true_false_are_defined   1  
  18. #endif  /* stdbool.h */  

 

    5、stdarg.h: 訪問可變參數表的類型和函數(用宏實現)。當你需要編寫有可變參數表的函數時,比如myfunc(int *a,...),你就可以用stdarg.h中的各個函數來遍歷“...”中的各個實參,以完成該函數的功能。略去沒有用的一大堆用于兼容不同平臺的條件編譯宏,如下:
   

[cpp] view plaincopy
  1. /* ISO C Standard:  7.15  可變參數表  <stdarg.h> */  
  2. #ifndef __GNUC_VA_LIST  
  3. #define __GNUC_VA_LIST  
  4. typedef __builtin_va_list __gnuc_va_list; /* 定義__gnuc_va_list.  */  
  5. #endif  
  6. #ifdef _STDARG_H  
  7. /* var_start(v,l):初始化用于遍歷參數表的狀態變量v */  
  8. #define va_start(v,l)   __builtin_va_start(v,l)  
  9. /* 結束參數表的遍歷,對v和參數表做必要的整理操作 */  
  10. #define va_end(v)   __builtin_va_end(v)  
  11. /* 返回v當前指向的參數值 */  
  12. #define va_arg(v,l) __builtin_va_arg(v,l)  
  13. #if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L  
  14. /* 本函數C99中引入:將s復制到d中,生成指向當前參數的第二個指針 */  
  15. #define va_copy(d,s)    __builtin_va_copy(d,s)  
  16. #endif  
  17. #define __va_copy(d,s)  __builtin_va_copy(d,s)  
  18. typedef __gnuc_va_list va_list/* 定義va_list類型,用這種類型來定義遍歷可變 
  19.                                             參數表的狀態變量 */  
  20.                                               
  21. #endif /* _STDARG_H */                                              

    解釋:
    (1)va_list類型:用這種類型來定義遍歷可變參數列表的狀態變量ap。
    (2)va_start(ap,lt):讓ap的內部指針指向第一個可變參數。需要用lt來指定可變參數表前面的最后一個固定參數。遍歷開始必須先調用這個函數。
    (3)var_arg(ap,type):獲取當前ap內部指針指向的參數值,然后把指針移動下一個參數,下一個參數的類型要用type指定。
    (4)va_end(ap):完成對可變參數表的遍歷,會對ap和參數表作必要的整理工作。遍歷結束時必須要調用這個函數。
    (5)va_copy(dest,src):c99中引入,將src復制到dest中,dest和src均為va_list型狀態變量。這樣就生成指向當前參數的第二個狀態變量,然后可以獨立的使用src和dest來遍歷可變參數表。dest中也要像src中一樣調用va_end。
    6、iso646.h: 為邏輯運算符定義一些方便使用的宏,是C89增補1中增加的。

 

 

[cpp] view plaincopy
  1. /* ISO C Standard:  7.9  一些運算符宏  <iso646.h> */  
  2. #ifndef _ISO646_H  
  3. #define _ISO646_H  
  4. #ifndef __cplusplus  
  5. #define and &&  
  6. #define and_eq  &=  
  7. #define bitand  &  
  8. #define bitor   |  
  9. #define compl   ~  
  10. #define not !  
  11. #define not_eq  !=  
  12. #define or  ||  
  13. #define or_eq   |=  
  14. #define xor ^  
  15. #define xor_eq  ^=  
  16. #endif  
  17. #endif  

 

    之所以要為&&、|、!、^等這些運算符定義一個宏,是因為在ISO 646的字符集中要使用這些特殊的符號可能不方便,而用等價的宏名and、bitor、not、xor就比較方便了,在C++中這些宏名是關鍵字。C89增補1還提供了一些能在ISO 646中方便使用的字符來拼寫{、}之類的符號。如<%、%>、<:、:>、%:、%:%分別等價于字符{、}、[、]、#、##。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 金塔县| 大余县| 梁山县| 贡嘎县| 灵璧县| 遵化市| 虞城县| 顺平县| 泰州市| 新密市| 正安县| 商水县| 新安县| 河津市| 华亭县| 宿迁市| 临西县| 南岸区| 赞皇县| 子长县| 娄底市| 永靖县| 博罗县| 昔阳县| 永登县| 汝州市| 龙泉市| 威远县| 北票市| 蕲春县| 五大连池市| 衡南县| 融水| 交城县| 原平市| 荃湾区| 恩平市| 张家界市| 三明市| 桓仁| 静乐县|