計算payload長度c語言,C語言0長度數組(可變數組/柔性數組)詳解

1 零長度數組概念

眾所周知, GNU/GCC 在標準的 C/C++ 基礎上做了有實用性的擴展, 零長度數組(Arrays of Length Zero) 就是其中一個知名的擴展.

多數情況下, 其應用在變長數組中, 其定義如下struct Packet{ int state; int len; char cData[0]; //這里的0長結構體就為變長結構體提供了非常好的支持};1

2

3

4

5

6

首先對 0長度數組, 也叫柔性數組 做一個解釋 :用途 : 長度為0的數組的主要用途是為了滿足需要變長度的結構體

用法 : 在一個結構體的最后, 申明一個長度為0的數組, 就可以使得這個結構體是可變長的. 對于編譯器來說, 此時長度為0的數組并不占用空間, 因為數組名本身不占空間, 它只是一個偏移量, 數組名這個符號本身代表了一個不可修改的地址常量(注意 : 數組名永遠都不會是指針!), 但對于這個數組的大小, 我們可以進行動態分配

注意 :如果結構體是通過calloc、malloc或 者new等動態分配方式生成,在不需要時要釋放相應的空間。

優點 :比起在結構體中聲明一個指針變量、再進行動態分 配的辦法,這種方法效率要高。因為在訪問數組內容時,不需要間接訪問,避免了兩次訪存。

缺點 :在結構體中,數組為0的數組必須在最后聲明,使 用上有一定限制。

對于編譯器而言, 數組名僅僅是一個符號, 它不會占用任何空間, 它在結構體中, 只是代表了一個偏移量, 代表一個不可修改的地址常量!

2 0長度數組的用途

我們設想這樣一個場景, 我們在網絡通信過程中使用的數據緩沖區, 緩沖區包括一個len字段和data字段, 分別標識數據的長度和傳輸的數據, 我們常見的有幾種設計思路定長數據緩沖區, 設置一個足夠大小 MAX_LENGTH 的數據緩沖區

設置一個指向實際數據的指針, 每次使用時, 按照數據的長度動態的開辟數據緩沖區的空間.

我們從實際場景中應用的設計來考慮他們的優劣. 主要考慮的有, 緩沖區空間的開辟, 釋放和訪問.

2.1 定長包(開辟空間, 釋放, 訪問)

比如我要發送 1024 字節的數據, 如果用定長包, 假設定長包的長度 MAX_LENGTH 為 2048, 就會浪費 1024 個字節的空間, 也會造成不必要的流量浪費.數據結構定義// 定長緩沖區struct max_buffer{ int len; char data[MAX_LENGTH];};1

2

3

4

5

6數據結構大小

考慮對齊, 那么數據結構的大小 >= sizeof(int) + sizeof(char) * MAX_LENGTH

由于考慮到數據的溢出, 變長數據包中的 data 數組長度一般會設置得足夠長足以容納最大的數據, 因此 max_buffer 中的 data 數組很多情況下都沒有填滿數據, 因此造成了浪費數據包的構造

假如我們要發送 CURR_LENGTH = 1024 個字節, 我們如何構造這個數據包呢:

一般來說, 我們會返回一個指向緩沖區數據結構 max_buffer 的指針./// 開辟 if ((mbuffer = (struct max_buffer *)malloc(sizeof(struct max_buffer))) != NULL) { mbuffer->len = CURR_LENGTH; memcpy(mbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", mbuffer->len, mbuffer->data); }1

2

3

4

5

6

7

8

9訪問

這段內存要分兩部分使用

前部分 4 個字節 p->len, 作為包頭(就是多出來的那部分),這個包頭是用來描述緊接著包頭后面的數據部分的長度,這里是 1024, 所以前四個字節賦值為 1024 (既然我們要構造不定長數據包,那么這個包到底有多長呢,因此,我們就必須通過一個變量來表明這個數據包的長度,這就是len的作用),

而緊接其后的內存是真正的數據部分, 通過 p->data, 最后, 進行一個 memcpy() 內存拷貝, 把要發送的數據填入到這段內存當中釋放

那么當使用完畢釋放數據的空間的時候, 直接釋放就可以了/// 銷毀 free(mbuffer); mbuffer = NULL;1

2

3小結使用定長數組, 作為數據緩沖區, 為了避免造成緩沖區溢出, 數組的大小一般設為足夠的空間 MAX_LENGTH, 而實際使用過程中, 達到 MAX_LENGTH 長度的數據很少, 那么多數情況下, 緩沖區的大部分空間都是浪費掉的.

但是使用過程很簡單, 數據空間的開辟和釋放簡單, 無需程序員考慮額外的操作

2.2 指針數據包(開辟空間, 釋放, 訪問)

如果你將上面的長度為 MAX_LENGTH 的定長數組換為指針, 每次使用時動態的開辟 CURR_LENGTH 大小的空間, 那么就避免造成 MAX_LENGTH - CURR_LENGTH 空間的浪費, 只浪費了一個指針域的空間.數據包定義struct point_buffer{ int len; char *data;};1

2

3

4

5數據結構大小

考慮對齊, 那么數據結構的大小 >= sizeof(int) + sizeof(char *)空間分配

但是也造成了使用在分配內存時,需采用兩步// ===================== // 指針數組 占用-開辟-銷毀 // ===================== /// 占用 printf("the length of struct test3:%d\n",sizeof(struct point_buffer)); /// 開辟 if ((pbuffer = (struct point_buffer *)malloc(sizeof(struct point_buffer))) != NULL) { pbuffer->len = CURR_LENGTH; if ((pbuffer->data = (char *)malloc(sizeof(char) * CURR_LENGTH)) != NULL) { memcpy(pbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", pbuffer->len, pbuffer->data); } }1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17首先, 需為結構體分配一塊內存空間;

其次再為結構體中的成員變量分配內存空間.

這樣兩次分配的內存是不連續的, 需要分別對其進行管理. 當使用長度為的數組時, 則是采用一次分配的原則, 一次性將所需的內存全部分配給它.釋放

相反, 釋放時也是一樣的./// 銷毀 free(pbuffer->data); free(pbuffer); pbuffer = NULL;1

2

3

4小結使用指針結果作為緩沖區, 只多使用了一個指針大小的空間, 無需使用 MAX_LENGTH 長度的數組, 不會造成空間的大量浪費.

但那是開辟空間時, 需要額外開辟數據域的空間, 施放時候也需要顯示釋放數據域的空間, 但是實際使用過程中, 往往在函數中開辟空間, 然后返回給使用者指向 struct point_buffer 的指針, 這時候我們并不能假定使用者了解我們開辟的細節, 并按照約定的操作釋放空間, 因此使用起來多有不便, 甚至造成內存泄漏

2.3 變長數據緩沖區(開辟空間, 釋放, 訪問)

定長數組使用方便, 但是卻浪費空間, 指針形式只多使用了一個指針的空間, 不會造成大量空間分浪費, 但是使用起來需要多次分配, 多次釋放, 那么有沒有一種實現方式能夠既不浪費空間, 又使用方便的呢?

GNU C 的0長度數組, 也叫變長數組, 柔性數組就是這樣一個擴展. 對于0長數組的這個特點,很容易構造出變成結構體,如緩沖區,數據包等等:數據結構定義// 0長度數組struct zero_buffer{ int len; char data[0];};1

2

3

4

5

6數據結構大小

這樣的變長數組常用于網絡通信中構造不定長數據包, 不會浪費空間浪費網絡流量, 因為char data[0]; 只是個數組名, 是不占用存儲空間的,

即 sizeof(struct zero_buffer) = sizeof(int)開辟空間

那么我們使用的時候, 只需要開辟一次空間即可/// 開辟 if ((zbuffer = (struct zero_buffer *)malloc(sizeof(struct zero_buffer) + sizeof(char) * CURR_LENGTH)) != NULL) { zbuffer->len = CURR_LENGTH; memcpy(zbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", zbuffer->len, zbuffer->data); }1

2

3

4

5

6

7

8

9釋放空間

釋放空間也是一樣的, 一次釋放即可/// 銷毀 free(zbuffer); zbuffer = NULL;1

2

3

2.4 總結// zero_length_array.c#include #include #define MAX_LENGTH 1024#define CURR_LENGTH 512// 0長度數組struct zero_buffer{ int len; char data[0];}__attribute((packed));// 定長數組struct max_buffer{ int len; char data[MAX_LENGTH];}__attribute((packed));// 指針數組struct point_buffer{ int len; char *data;}__attribute((packed));int main(void){ struct zero_buffer *zbuffer = NULL; struct max_buffer *mbuffer = NULL; struct point_buffer *pbuffer = NULL; // ===================== // 0長度數組 占用-開辟-銷毀 // ===================== /// 占用 printf("the length of struct test1:%d\n",sizeof(struct zero_buffer)); /// 開辟 if ((zbuffer = (struct zero_buffer *)malloc(sizeof(struct zero_buffer) + sizeof(char) * CURR_LENGTH)) != NULL) { zbuffer->len = CURR_LENGTH; memcpy(zbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", zbuffer->len, zbuffer->data); } /// 銷毀 free(zbuffer); zbuffer = NULL; // ===================== // 定長數組 占用-開辟-銷毀 // ===================== /// 占用 printf("the length of struct test2:%d\n",sizeof(struct max_buffer)); /// 開辟 if ((mbuffer = (struct max_buffer *)malloc(sizeof(struct max_buffer))) != NULL) { mbuffer->len = CURR_LENGTH; memcpy(mbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", mbuffer->len, mbuffer->data); } /// 銷毀 free(mbuffer); mbuffer = NULL; // ===================== // 指針數組 占用-開辟-銷毀 // ===================== /// 占用 printf("the length of struct test3:%d\n",sizeof(struct point_buffer)); /// 開辟 if ((pbuffer = (struct point_buffer *)malloc(sizeof(struct point_buffer))) != NULL) { pbuffer->len = CURR_LENGTH; if ((pbuffer->data = (char *)malloc(sizeof(char) * CURR_LENGTH)) != NULL) { memcpy(pbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", pbuffer->len, pbuffer->data); } } /// 銷毀 free(pbuffer->data); free(pbuffer); pbuffer = NULL; return EXIT_SUCCESS;}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

116589981_2_20171119104117384長度為0的數組并不占有內存空間, 而指針方式需要占用內存空間.

對于長度為0數組, 在申請內存空間時, 采用一次性分配的原則進行; 對于包含指針的結構體, 才申請空間時需分別進行, 釋放時也需分別釋放.

對于長度為的數組的訪問可采用數組方式進行

3 GNU Document中 變長數組的支持

在 C90 之前, 并不支持0長度的數組, 0長度數組是 GNU C 的一個擴展, 因此早期的編譯器中是無法通過編譯的

對于 GNU C 增加的擴展, GCC 提供了編譯選項來明確的標識出他們

1、-pedantic 選項,那么使用了擴展語法的地方將產生相應的警告信息

2、-Wall 使用它能夠使GCC產生盡可能多的警告信息

3、-Werror, 它要求GCC將所有的警告當成錯誤進行處理// 1.c#include #include int main(void){ char a[0]; printf("%ld", sizeof(a)); return EXIT_SUCCESS;}1

2

3

4

5

6

7

8

9

10

11

我們來編譯gcc 1.c -Wall # 顯示所有警告#none warning and errorgcc 1.c -Wall -pedantic # 對GNU C的擴展顯示警告1.c: In function ‘main’:1.c:7: warning: ISO C forbids zero-size array ‘a’gcc 1.c -Werror -Wall -pedantic # 顯示所有警告同時GNU C的擴展顯示警告, 將警告用error顯示cc1: warnings being treated as errors1.c: In function ‘main’:1.c:7: error: ISO C forbids zero-size array ‘a’1

2

3

4

5

6

7

8

9

10

11

12

116589981_3_20171119104117712

0長度數組其實就是靈活的運用的數組指向的是其后面的連續的內存空間struct buffer{ int len; char data[0];};1

2

3

4

5

在早期沒引入0長度數組的時候, 大家是通過定長數組和指針的方式來解決的, 但是定長數組定義了一個足夠大的緩沖區, 這樣使用方便, 但是每次都造成空間的浪費

指針的方式, 要求程序員在釋放空間是必須進行多次的free操作, 而我們在使用的過程中往往在函數中返回了指向緩沖區的指針, 我們并不能保證每個人都理解并遵從我們的釋放方式

所以 GNU 就對其進行了0長度數組的擴展. 當使用data[0]的時候, 也就是0長度數組的時候,0長度數組作為數組名, 并不占用存儲空間.

在C99之后,也加了類似的擴展,只不過用的是 char payload[]這種形式(所以如果你在編譯的時候確實需要用到-pedantic參數,那么你可以將char payload[0]類型改成char payload[], 這樣就可以編譯通過了,當然你的編譯器必須支持C99標準的,如果太古老的編譯器,那可能不支持了)// 2.c payload#include #include struct payload{ int len; char data[];};int main(void){ struct payload pay; printf("%ld", sizeof(pay)); return EXIT_SUCCESS;}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

使用 -pedantic 編譯后, 不出現警告, 說明這種語法是 C 標準的gcc 2.c -pedantic -std=c991

116589981_4_20171119104117915

所以結構體的末尾, 就是指向了其后面的內存數據。因此我們可以很好的將該類型的結構體作為數據報文的頭格式,并且最后一個成員變量,也就剛好是數據內容了.

GNU手冊還提供了另外兩個結構體來說明,更容易看懂意思:struct f1 { int x; int y[];} f1 = { 1, { 2, 3, 4 } };struct f2 { struct f1 f1; int data[3];} f2 = { { 1 }, { 5, 6, 7 } };1

2

3

4

5

6

7

8

9

我把f2里面的2,3,4改成了5,6,7以示區分。如果你把數據打出來。即如下的信息:f1.x = 1f1.y[0] = 2f1.y[1] = 3f1.y[2] = 41

2

3

4

也就是f1.y指向的是{2,3,4}這塊內存中的數據。所以我們就可以輕易的得到,f2.f1.y指向的數據也就是正好f2.data的內容了。打印出來的數據:f2.f1.x = 1f2.f1.y[0] = 5f2.f1.y[1] = 6f2.f1.y[2] = 71

2

3

4

如果你不是很確認其是否占用空間. 你可以用sizeof來計算一下。就可以知道sizeof(struct f1)=4,也就是int y[]其實是不占用空間的。但是這個0長度的數組,必須放在結構體的末尾。如果你沒有把它放在末尾的話。編譯的時候,會有如下的錯誤:main.c:37:9: error: flexible array member not at end of struct int y[]; ^1

2

3

到這邊,你可能會有疑問,如果將struct f1中的int y[]替換成int *y,又會是如何?這就涉及到數組和指針的問題了. 有時候吧,這兩個是一樣的,有時候又有區別。

首先要說明的是,支持0長度數組的擴展,重點在數組,也就是不能用int *y指針來替換。sizeof的長度就不一樣了。把struct f1改成這樣:struct f3 { int x; int *y;};1

2

3

4

在32/64位下, int均是4個字節, sizeof(struct f1)=4,而sizeof(struct f3)=16

因為 int *y 是指針, 指針在64位下, 是64位的, sizeof(struct f3) = 16, 如果在32位環境的話, sizeof(struct f3) 則是 8 了, sizeof(struct f1) 不變. 所以 int *y 是不能替代 int y[] 的.

代碼如下// 3.c#include #include struct f1 { int x; int y[];} f1 = { 1, { 2, 3, 4 } };struct f2 { struct f1 f1; int data[3];} f2 = { { 1 }, { 5, 6, 7 } };struct f3{ int x; int *y;};int main(void){ printf("sizeof(f1) = %d\n", sizeof(struct f1)); printf("sizeof(f2) = %d\n", sizeof(struct f2)); printf("szieof(f3) = %d\n\n", sizeof(struct f3)); printf("f1.x = %d\n", f1.x); printf("f1.y[0] = %d\n", f1.y[0]); printf("f1.y[1] = %d\n", f1.y[1]); printf("f1.y[2] = %d\n", f1.y[2]); printf("f2.f1.x = %d\n", f1.x); printf("f2.f1.y[0] = %d\n", f2.f1.y[0]); printf("f2.f1.y[1] = %d\n", f2.f1.y[1]); printf("f2.f1.y[2] = %d\n", f2.f1.y[2]); return EXIT_SUCCESS;}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

116589981_5_2017111910411825

4 0長度數組的其他特征

4.1 為什么0長度數組不占用存儲空間

0長度數組與指針實現有什么區別呢, 為什么0長度數組不占用存儲空間呢?

其實本質上涉及到的是一個C語言里面的數組和指針的區別問題. char a[1]里面的a和char *b的b相同嗎?

《 Programming Abstractions in C》(Roberts, E. S.,機械工業出版社,2004.6)82頁里面說“arr is defined to be identical to &arr[0]”.

也就是說,char a[1]里面的a實際是一個常量,等于&a[0]。而char *b是有一個實實在在的指針變量b存在。 所以,a=b是不允許的,而b=a是允許的。 兩種變量都支持下標式的訪問,那么對于a[0]和b[0]本質上是否有區別?我們可以通過一個例子來說明。

參見如下兩個程序 gdb_zero_length_array.c 和 gdb_zero_length_array.c// gdb_zero_length_array.c#include #include struct str{ int len; char s[0];};struct foo{ struct str *a;};int main(void){ struct foo f = { NULL }; printf("sizeof(struct str) = %d\n", sizeof(struct str)); printf("before f.a->s.\n"); if(f.a->s) { printf("before printf f.a->s.\n"); printf(f.a->s); printf("before printf f.a->s.\n"); } return EXIT_SUCCESS;}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

116589981_6_20171119104118212// gdb_pzero_length_array.c#include #include struct str{ int len; char *s;};struct foo{ struct str *a;};int main(void){ struct foo f = { NULL }; printf("sizeof(struct str) = %d\n", sizeof(struct str)); printf("before f.a->s.\n"); if (f.a->s) { printf("before printf f.a->s.\n"); printf(f.a->s); printf("before printf f.a->s.\n"); } return EXIT_SUCCESS;}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/533781.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/533781.shtml
英文地址,請注明出處:http://en.pswp.cn/news/533781.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

iphone主屏幕動態壁紙_iPhone8怎么設置動態壁紙?iPhone8動態壁紙設置教程

iPhone8怎么設置動態壁紙?朋友們平時想把一些拍攝的動態圖片設置iPhone8壁紙,該怎么設置呢?估計有 不少朋友還不知道如何設置, 在這里我就來為大家介紹一下iPhone8設置動態壁紙的教程,一起來看一看吧!iPhone8動態壁紙設置教程首先打開iPhon…

python封裝介紹_談python3的封裝

這章給大家介紹,如何封裝一個簡單的python庫首先創建一個以下型式的文件結構rootFile/setup.pyexample_package/__init__.pyexample_module.pyexample_package2/__init__.pyexample_module.py其中的兩個__init__.py可以是一個空文件,但是它是導入package…

go語言調用c 的頭文件 so,golang 學習(10): 使用go語言調用c語言的so動態庫-Go語言中文社區...

一、前言最近在學習go,因為需要調用c語言打包成的so動態庫里面的方法,避免自己再去造輪子,所以想直接使用golang調用so,但是參考了其他博客大佬寫的,我每一步原封不動的寫下來,結果都是一堆錯誤&#xff0c…

log nginx 客戶端請求大小_Nginx日志分析和參數詳解

本文檔主要介紹Nginx設置日志參數的作用,以及Nginx日志常用分析命令基本大綱:1.Nginx日志記錄格式的介紹2.Nginx日志參數詳解3.Web服務流量名詞介紹4.Nginx日志常用分析命令示范一:Nginx日志記錄格式的介紹log_format用來設置日志的記錄格式&…

python函數的封裝調用_Python封裝一個函數來打印到變量

如果我有一個包含大量打印語句的函數: 即. def funA(): print "Hi" print "There" print "Friend" print "!" 我想做的是這樣的事情 def main(): ##funA() does not print to screen here a getPrint(funA()) ##where get…

android 開機動畫 漸變,[Parallax Animation]實現知乎 Android 客戶端啟動頁視差滾動效果...

前言Parallax Scrolling (視差滾動),是一種常見的動畫效果。視差一詞來源于天文學,但在日常生活中也有它的身影。在疾馳的動車上看風景時,會發現越是離得近的,相對運動速度越快,而遠處的山川河流只是緩慢的移動著&…

js訪問對方手機文件夾_求JS大神幫我寫個利用JS來實現手機端和PC端訪問自動選擇樣式文件代碼...

展開全部現在比較流行的辦法是 一個網站2套代碼,一套是手機一套pc,在網站首頁開e68a84e8a2ad3231313335323631343130323136353331333363353735頭寫上一段識別各瀏覽器的判斷方法,根據結果引入不同的樣式詳細判斷如下:var browser{…

python可以做計量分析嗎_技術分享 - python數據分析(2)——數據特征分析(上)...

1 分布分析 分布分析能揭示數據的分布特征和分布類型。對于定量數據,欲了解其分布形式是對稱的還是非對稱的,發現某些特大或特小的可疑值,可通過繪制頻率分布表、繪制頻率分布直方圖、繪制莖葉圖進行直觀地分析;對于定性分類數據&…

android lrc 歌詞顯示,Android歌詞 AndroidLrc歌詞

[ti:Android][ar:川畑要][al:0][by:黃病病][00:00.00][00:01.69]Android[00:07.51]歌手:川畑要[00:10.96]作詞:Kaname Kawabata[00:12.64]作曲:UTAKaname Kawabata[00:14.06]BY:黃病病[00:15.80][00:15.66]一際目を引くまるでandroid[00:23.1…

web前端開發技術期末考試_Web前端開發技術期末試題1

絕密★啟用前Web前端開發技術期一、單項選擇題(本大題共25小題,每小題1分,共25分)1.網頁制作工具按照其工作方式可分為( )A.HTML語言和非HTML語言兩大類B.DHTML方式和JavaScript方式兩大類C.標注型網頁制作工具和所見即所得型網頁制作工具兩大類D.基于Wi…

matlab的7.3版本是什么_樂建工程寶V6.3版本升級說明公告

尊敬的樂建工程寶客戶:您好!為了給客戶提供更加優質的產品和服務,我司已于2019年11月20日開始樂建工程寶V6.3版本升級服務。目前,Android系統各應用市場已基本審核完畢,iOS系統已上傳AppStore,目前蘋果官方…

魅族android 版本 6.0下載,flyme6.0內測版

由魅族開發的全新安卓系統flyme6.0系統固件已經到來,相對于Flyme 5系統有了眾多改變和提升,全新的智能服務系統,多達400于項全新功能,同時讓操作界面更加簡潔,易于操作,而系統運行速度也將有所提升&#xf…

origin設置不同區域的顏色_[測試狗]Origin入門教程(二十四):效率翻倍小技巧——修改默認字體...

在使用Origin的時候,對于每次繪圖都需要更改字體覺得很麻煩,因為Origin默認的字體為Arial,但是我們常用的字體一般為Times New Roman,在下拉框的很底部,每次更改都很浪費時間。那為什么不把他設置成默認字體呢&#xf…

cgi web 調用多次啟動_全面了解CGI、FastCGI、PHPFPM

一、拋個磚1、Web Server傳遞數據的方法正式說CGI之前,先來了解一下Web Server傳遞數據的另外一種方法:PHP Module加載方式。相信都會想起Apache吧,初學php時,在windows上安裝完php和Apache之后,為了讓Apache能夠解析p…

android群英傳神兵利器pdf,《Android群英傳:神兵利器》勘誤

1勘誤一晃,我的新書《Android群英傳:神兵利器》上市好多天了,有不少朋友已經拿到書了。本來以為,這次我看了不下十遍,再加上編輯們的校對,應該不會有很多勘誤了吧~ 可事實證明,我還是太年輕啊!大…

datatype未定義是什么意思_TypeError:無法讀取未定義的屬性'then'

loginService.islogged()上面的函數返回一個像“失敗”的字符串 . 但是,當我嘗試運行然后對它運行時,它將返回錯誤TypeError: Cannot read property then of undefined并且光標在 connected 之后和 .then 之前指示 .以下是完整功能:var conne…

python運行命令_對python中執行DOS命令的3種方法總結

1. 使用os.system("cmd") 特點是執行的時候程序會打出cmd在Linux上執行的信息。 import os os.system("ls") 2. 使用Popen模塊產生新的process 現在大部分人都喜歡使用Popen。Popen方法不會打印出cmd在linux上執行的信息。的確,Popen非常強大&a…

android studio 不生成buildconfig,Android Studio Update 0.4.0找不到buildConfig()

將Android Studio升級到版本0.4.0后,出現了一個新錯誤:我通過gradle-wrapper.properties升級到gradle 1.9distributionUrlhttp\://services.gradle.org/distributions/gradle-1.9-all.zip并升級了build.gradle中的gradle版本dependencies {classpath com…

譚民機器人_機器人視覺伺服研究進展-中科院自動化所-譚民.

文章編號:100220446(2004 0320277206機器人視覺伺服研究進展Ξ王麟琨,徐德,譚民(中國科學院自動化研究所復雜系統與智能科學實驗室,北京100080摘要:,針對當前機器人視覺伺服所面臨的主要問題, .關鍵詞:機器人;視覺伺服;綜述中圖分類號::Survey of R esearch on Robotic Visual …

mysql 按月和年累加_廣西柳州市市場監管局公布市2020年11月(第一批)電梯按需維保試點名單...

中國質量新聞網訊 根據《柳州市改進電梯維護保養模式試點工作方案》,近日,廣西柳州市市場監管局公布柳州市首批按需維保試點電梯名單,冠亞藍灣國際小區和南慶安置小區共46臺電梯成為首批試點電梯,標志著柳州市全面啟動了按需維保改…