中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

dw自己做網(wǎng)站需要什么高端企業(yè)網(wǎng)站模板

dw自己做網(wǎng)站需要什么,高端企業(yè)網(wǎng)站模板,網(wǎng)站怎么自己做推廣,個(gè)人網(wǎng)站如何備案文章目錄 1. 結(jié)構(gòu)體類(lèi)型的聲明1. 1 結(jié)構(gòu)體聲明1. 2 結(jié)構(gòu)體變量的創(chuàng)建和初始化1. 3 結(jié)構(gòu)體的特殊聲明1. 3 結(jié)構(gòu)體的自引用 2. 結(jié)構(gòu)體內(nèi)存對(duì)齊2. 1 對(duì)齊規(guī)則2. 2 為什么存在內(nèi)存對(duì)齊2. 3 修改默認(rèn)對(duì)齊數(shù) 3. 結(jié)構(gòu)體傳參4. 結(jié)構(gòu)體實(shí)現(xiàn)位段4. 1 什么是位段4. 2 位段成員的內(nèi)存分配4.…

文章目錄

  • 1. 結(jié)構(gòu)體類(lèi)型的聲明
    • 1. 1 結(jié)構(gòu)體聲明
    • 1. 2 結(jié)構(gòu)體變量的創(chuàng)建和初始化
    • 1. 3 結(jié)構(gòu)體的特殊聲明
    • 1. 3 結(jié)構(gòu)體的自引用
  • 2. 結(jié)構(gòu)體內(nèi)存對(duì)齊
    • 2. 1 對(duì)齊規(guī)則
    • 2. 2 為什么存在內(nèi)存對(duì)齊
    • 2. 3 修改默認(rèn)對(duì)齊數(shù)
  • 3. 結(jié)構(gòu)體傳參
  • 4. 結(jié)構(gòu)體實(shí)現(xiàn)位段
    • 4. 1 什么是位段
    • 4. 2 位段成員的內(nèi)存分配
    • 4. 3 位段的跨平臺(tái)問(wèn)題
    • 4. 4 位段的使用
    • 4. 5 位段使用的注意事項(xiàng)


1. 結(jié)構(gòu)體類(lèi)型的聲明

1. 1 結(jié)構(gòu)體聲明

格式如下:

struct tag
{member - list;//結(jié)構(gòu)成員,可以不止一個(gè)
}variable - list;//在這里可以直接創(chuàng)建結(jié)構(gòu)體變量,可以用逗號(hào)隔開(kāi)來(lái)創(chuàng)建多個(gè),不能初始化

例如描述一個(gè)學(xué)生:

struct student	//這個(gè)結(jié)構(gòu)體的名稱(chēng)
{	//以下是結(jié)構(gòu)成員char name[20];	//姓名char sex[5];	//性別int age;		//年齡char id[10];	//學(xué)號(hào)
}A, B;				//聲明結(jié)構(gòu)體時(shí)創(chuàng)建了學(xué)生A和B,注意分號(hào)不能丟

進(jìn)行聲明時(shí),還可以使用 typedef 進(jìn)行重命名:

typedef struct student
{char name[20];char sex[5];int age;char id[10];
}ST;//之后創(chuàng)建結(jié)構(gòu)體變量時(shí),就可以將 ST 作為類(lèi)型使用了,注意這樣就無(wú)法在聲明結(jié)構(gòu)體時(shí)創(chuàng)建變量了

1. 2 結(jié)構(gòu)體變量的創(chuàng)建和初始化

除了在聲明時(shí)創(chuàng)建變量,還可以像創(chuàng)建int等其他變量一樣創(chuàng)建并初始化結(jié)構(gòu)體變量。

#include<stdio.h>struct student
{char name[20];char sex[5];int age;char id[10];
}A, B;void Print(struct student S)
{printf("%s %s %d %s\n", S.name, S.sex, S.age, S.id);
}int main()
{	//按照定義順序初始化struct student s1 = { "張三","man",15,"122111" };Print(s1);//按照指定順序初始化struct student s2 = { .age = 18,.id = "454541",.name = "fhvyxyci",.sex = "man" };Print(s2);return 0;
}

1. 3 結(jié)構(gòu)體的特殊聲明

//匿名結(jié)構(gòu)體變量
struct
{int a;char b;float c;
}x;struct
{int a;char b;float c;
}a[20], * p;

上面的兩個(gè)結(jié)構(gòu)在聲明的時(shí)候省略掉了結(jié)構(gòu)體標(biāo)簽。

那么問(wèn)題來(lái)了:

//在上面代碼的基礎(chǔ)上,下面的代碼合法嗎?
p = &x;

編譯器會(huì)把上面的兩個(gè)聲明當(dāng)成完全不同的兩個(gè)類(lèi)型,所以是非法的。
匿名的結(jié)構(gòu)體類(lèi)型,如果沒(méi)有對(duì)結(jié)構(gòu)體類(lèi)型(使用 typedef )重命名的話(huà),基本上只能使用一次。

1. 3 結(jié)構(gòu)體的自引用

1. 在結(jié)構(gòu)中包含一個(gè)類(lèi)型為該結(jié)構(gòu)本身的成員是否可以呢?
比如,定義一個(gè)鏈表(一種數(shù)據(jù)結(jié)構(gòu))的節(jié)點(diǎn):

struct Node
{int data;struct Node next;
};

上述代碼正確嗎?如果正確,那sizeof(struct Node)是多少?
仔細(xì)分析,其實(shí)是不行的,因?yàn)橐粋€(gè)結(jié)構(gòu)體中再包含一個(gè)同類(lèi)型的結(jié)構(gòu)體變量,這樣結(jié)構(gòu)體變量的
小就會(huì)無(wú)窮的大
,是不合理的。
正確的自引用方式:

struct Node
{int data;struct Node* next;//這里放上一個(gè)指針,就合理多了
};

2. 在結(jié)構(gòu)體自引用使用的過(guò)程中,夾雜了 typedef 對(duì)匿名結(jié)構(gòu)體類(lèi)型重命名,也容易引入問(wèn)題,
看下面的代碼,可行嗎?

typedef struct
{int data;Node* next;
}Node;

答案是不行的,因?yàn)?code>Node是對(duì)前面的匿名結(jié)構(gòu)體類(lèi)型的重命名產(chǎn)生的,但是在匿名結(jié)構(gòu)體內(nèi)部提前使用Node類(lèi)型來(lái)創(chuàng)建成員變量,這是不行的。
解決方案:定義結(jié)構(gòu)體不要使用匿名結(jié)構(gòu)體

typedef struct Node
{int data;struct Node* next;//這里要使用沒(méi)有重命名的名字
}Node;

2. 結(jié)構(gòu)體內(nèi)存對(duì)齊

2. 1 對(duì)齊規(guī)則

  1. 結(jié)構(gòu)體的第一個(gè)成員對(duì)齊到和結(jié)構(gòu)體變量起始位置偏移量為0的地址處
  2. 其他成員變量要對(duì)產(chǎn)到某個(gè)數(shù)字(對(duì)齊數(shù))的整數(shù)倍的地址處。
    對(duì)齊數(shù) = 編譯器默認(rèn)的一個(gè)對(duì)齊數(shù)該成員變量大小的最大值的較小值
    VS 中默認(rèn)的值為 8
    Linux中 gcc 沒(méi)有默認(rèn)對(duì)齊數(shù),對(duì)齊數(shù)就是成員自身的大小
  3. 結(jié)構(gòu)體總大小為最大對(duì)齊數(shù)(結(jié)構(gòu)體中每個(gè)成員變量都有一個(gè)對(duì)齊數(shù),所有對(duì)齊數(shù)中最大的)的整數(shù)倍。
  4. 如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體成員對(duì)齊到自己的對(duì)齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對(duì)齊數(shù)(含嵌套結(jié)構(gòu)體中成員的對(duì)齊數(shù))的整數(shù)倍。

來(lái)做幾個(gè)練習(xí)鞏固一下:
練習(xí)一:

#include<stdio.h>
struct S1
{char c1;int i;char c2;
};
int main()
{printf("%zd\n", sizeof(struct S1));return 0;
}

首先 c1:根據(jù)對(duì)齊規(guī)則1,c11個(gè)字節(jié),和結(jié)構(gòu)體處于同一個(gè)地址。
然后 i :根據(jù)對(duì)齊規(guī)則2,i需要對(duì)齊到相對(duì)結(jié)構(gòu)體地址的偏移量為4的位置,所以i的起始地址相對(duì)結(jié)構(gòu)體是4,目前結(jié)構(gòu)體大小為8
然后c2:占一個(gè)字節(jié),結(jié)構(gòu)體大小直接+1(任何偏移量都是1的倍數(shù),所以不需要額外偏移)。
最后,根據(jù)對(duì)齊規(guī)則3, 對(duì)齊數(shù) = 編譯器默認(rèn)的一個(gè)對(duì)齊數(shù) (以VS為例,8)與 該成員變量大小的最大值的較小值,這里顯然對(duì)齊數(shù)是4,因此9的下一個(gè)對(duì)齊數(shù)的倍數(shù)是12,所以結(jié)構(gòu)體的大小是12

圖解:
圖解

輸出結(jié)果:
輸出結(jié)果

代碼二:

#include<stdio.h>struct S2
{char c1;char c2;int i;
};int main()
{printf("%zd\n", sizeof(struct S2));return 0;
}

c1不比多說(shuō),來(lái)看c2char類(lèi)型的大小是1,任何偏移量都一定是1的倍數(shù),所以到了c2,結(jié)構(gòu)體的大小是2。
接著看iint變量的大小是4,2后面的最小的4的倍數(shù)是4,所以此時(shí)結(jié)構(gòu)體的大小是8。
最后對(duì)齊數(shù)也是4,所以結(jié)構(gòu)體的大小就是8。

圖解:
圖解
輸出結(jié)果:
輸出結(jié)果
代碼三:

#include<stdio.h>struct S3
{double d;char c;int i;
};int main()
{printf("%zd\n", sizeof(struct S3));return 0;
}

首先ddouble 類(lèi)型為8個(gè)字節(jié)。
然后c:結(jié)構(gòu)體大小+1。
然后i:9后面第一個(gè)4的倍數(shù)是12,所以從12開(kāi)始向后+4。
最后對(duì)齊數(shù):對(duì)齊數(shù) = 編譯器默認(rèn)的一個(gè)對(duì)齊數(shù) (8)與 該成員變量最大值的較小值(8),所以對(duì)齊數(shù)是8,最終大小就是16。

圖解:
圖解
運(yùn)行結(jié)果:
運(yùn)行結(jié)果
;練習(xí)四:

//結(jié)構(gòu)體嵌套問(wèn)題
#include<stdio.h>
struct S3
{double d;char c;int i;
};struct S4
{char c1;struct S3 s3;double d;
};int main()
{printf("%zd\n", sizeof(struct S4));return 0;
}

c1不再贅述,來(lái)看這個(gè) s3:
s3的對(duì)齊數(shù)是8,所以s3的偏移量為8,上面我們已經(jīng)算出了S3的大小是16,所以現(xiàn)在S4的大小是24。
因?yàn)?strong>24是8的倍數(shù),所以d就再向后找8個(gè)地址,是32
S4的偏移量是S4中所有除了S3以外的元素和S3的所有成員的大小中的最大值與默認(rèn)對(duì)齊數(shù)8之間的較小值,是8,所以S4的大小是32。

圖解:
圖解
輸出結(jié)果:
輸出結(jié)果

2. 2 為什么存在內(nèi)存對(duì)齊

  1. 平臺(tái)原因(移植原因)
    不是所有的硬件平臺(tái)都能訪(fǎng)問(wèn)任意地址上的任意數(shù)據(jù)的,某些硬件平臺(tái)只能在某些地址處取某些特定類(lèi)型的數(shù)據(jù),否則拋出硬件異常。
  2. 性能原因:
    數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊。原因在于,為了訪(fǎng)問(wèn)未對(duì)齊的內(nèi)存,處理器需要作兩次內(nèi)存訪(fǎng)問(wèn),而對(duì)齊的內(nèi)存訪(fǎng)問(wèn)僅需要一次訪(fǎng)問(wèn)。假設(shè)一個(gè)處理器總是從內(nèi)存中取8個(gè)字節(jié),則地址必須是8的倍數(shù)。如果我們能保證將所有的double類(lèi)型的數(shù)據(jù)的地址都對(duì)齊成8的倍數(shù),那么就可以用一個(gè)內(nèi)存操作來(lái)讀或者寫(xiě)值了。否則,我們可能需要執(zhí)行兩次內(nèi)存訪(fǎng)問(wèn),因?yàn)閷?duì)象可能被分放在兩個(gè)8字節(jié)內(nèi)存塊中。
    總體來(lái)說(shuō):結(jié)構(gòu)體的內(nèi)存對(duì)齊是拿空間來(lái)?yè)Q取時(shí)間的做法。

那在設(shè)計(jì)結(jié)構(gòu)體的時(shí)候,我們既要滿(mǎn)足對(duì)齊,又要節(jié)省空間,如何做到?
讓占用空間小的成員盡量集中在一起。

例如:

struct S1
{char c1;int i;char c2;
};struct S2
{char c1;char c2;int i;
};

經(jīng)過(guò)上面的計(jì)算,你會(huì)發(fā)現(xiàn)雖然這兩個(gè)結(jié)構(gòu)體的成員一樣,但是大小卻差的很多。

2. 3 修改默認(rèn)對(duì)齊數(shù)

#pragma這個(gè)預(yù)處理指令,可以改變編譯器的默認(rèn)對(duì)齊數(shù)。

#include <stdio.h>
#pragma pack(1)//設(shè)置默認(rèn)對(duì)齊數(shù)為1
struct S
{char c1;int i;char c2;
};
#pragma pack()//取消設(shè)置的對(duì)齊數(shù),還原為默認(rèn)
int main()
{//輸出的結(jié)果是什么?printf("%zd\n", sizeof(struct S));return 0;
}

結(jié)果是6:
結(jié)果
說(shuō)明對(duì)齊數(shù)是在結(jié)構(gòu)體聲明時(shí)計(jì)算的,而不是調(diào)用時(shí)。

盡管使用場(chǎng)景可能比較少,但是在對(duì)齊方式不合適的時(shí)候,我們可以自己更改默認(rèn)對(duì)齊數(shù)。

3. 結(jié)構(gòu)體傳參

#include<stdio.h>
struct S
{int data[1000];int num;
};
struct S s = { {1,2,3,4}, 1000 };
//結(jié)構(gòu)體傳參
void print1(struct S s)
{printf("%d\n", s.num);
}
//結(jié)構(gòu)體地址傳參
void print2(struct S* ps)
{printf("%d\n", ps->num);
}
int main()
{print1(s); //傳結(jié)構(gòu)體print2(&s); //傳地址return 0;
}

上面的 print1print2 函數(shù)哪個(gè)好些?
答案是:首選print2函數(shù)。
原因:
函數(shù)傳參的時(shí)候,參數(shù)是需要壓棧(可以理解為拷貝實(shí)參到形參),會(huì)有時(shí)間和空間上的系統(tǒng)開(kāi)銷(xiāo)。
傳遞一個(gè)結(jié)構(gòu)體對(duì)象,結(jié)構(gòu)體過(guò)大,參數(shù)壓棧的的系統(tǒng)開(kāi)銷(xiāo)就大,會(huì)導(dǎo)致性能的下降。
結(jié)論:結(jié)構(gòu)體傳參的時(shí)候,要傳結(jié)構(gòu)體的地址。

4. 結(jié)構(gòu)體實(shí)現(xiàn)位段

4. 1 什么是位段

位段的聲明和結(jié)構(gòu)是類(lèi)似的,但是有兩個(gè)不同:

  1. 位段的成員必須是 int、unsigned intsigned int(在C99中位段成員也可以選擇其他類(lèi)型)。
  2. 位段的成員名后邊有一個(gè)冒號(hào)和一個(gè)數(shù)字。

比如:

struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};

A就是一個(gè)位段類(lèi)型。
那位段A所占內(nèi)存的大小是多少?

8。
我們來(lái)了解一下。

4. 2 位段成員的內(nèi)存分配

位段的成員可以是 int unsigned int signed int 或者是 char 等類(lèi)型
位段的空間上是按照需要以4個(gè)字節(jié)(int )或者1個(gè)字節(jié) (char )的方式來(lái)開(kāi)辟的。
位段涉及很多不確定因素(比如上一行),位段是不跨平臺(tái)的,注重可移植的程序應(yīng)該避免使用位段。

//一個(gè)例子
#include<stdio.h>
struct S
{char a : 3;char b : 4;char c : 5;char d : 4;
};
int main()
{struct S s = { 0 };s.a = 10;s.b = 12;s.c = 3;s.d = 4;//空間是如何開(kāi)辟的?return 0;
}

在VS上是這樣開(kāi)辟的:每個(gè)字節(jié)從右向左使用,如果下一個(gè)位段成員比較大,就舍棄該字節(jié)中剩下的比特位去開(kāi)辟新的字節(jié)。
VS
那么上面的那個(gè)8字節(jié)也就很好分析出來(lái)了。

4. 3 位段的跨平臺(tái)問(wèn)題

  1. int 位段被當(dāng)成有符號(hào)數(shù)還是無(wú)符號(hào)數(shù)是不確定的。
  2. 位段中最大位的數(shù)目不能確定。
    (16位機(jī)器最大16,32位機(jī)器最大32,寫(xiě)成27,在16位機(jī)器會(huì)出問(wèn)題。
  3. 位段中的成員在內(nèi)存中從左向右分配,還是從右向左分配,標(biāo)準(zhǔn)尚未定義。
  4. 當(dāng)一個(gè)結(jié)構(gòu)包含兩個(gè)位段,第二個(gè)位段成員比較大,無(wú)法容納于第一個(gè)位段剩余的位時(shí),是舍棄
    剩余的位還是利用,這是不確定的。

總結(jié):
跟結(jié)構(gòu)相比,位段可以達(dá)到同樣的效果,并且可以很好的節(jié)省空間,但是有跨平臺(tái)的問(wèn)題存在。

4. 4 位段的使用

下圖是網(wǎng)絡(luò)協(xié)議中,IP數(shù)據(jù)報(bào)的格式,我們可以看到其中很多的屬性只需要幾個(gè)比特位就能描述,這里使用位段,能夠?qū)崿F(xiàn)想要的效果,也節(jié)省了空間,這樣網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)報(bào)大小也會(huì)較小一些,對(duì)網(wǎng)絡(luò)的暢通是有幫助的。
IP數(shù)據(jù)報(bào)

4. 5 位段使用的注意事項(xiàng)

位段的幾個(gè)成員共有同一個(gè)字節(jié),這樣有些成員的起始位置并不是某個(gè)字節(jié)的起始位置,那么這些位置處是沒(méi)有地址的。內(nèi)存中每個(gè)字節(jié)分配一個(gè)地址,一個(gè)字節(jié)內(nèi)部的比特位是沒(méi)有地址的。
所以不能對(duì)位段的成員使用&操作符,這樣就不能使用scanf直接給位段的成員輸入值,只能先輸入放在一個(gè)變量中,然后賦值給位段的成員。

#include<stdio.h>struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};int main()
{struct A sa = { 0 };//scanf("%d", &sa._b);//這是錯(cuò)誤的//正確的示范int b = 0;scanf("%d", &b);sa._b = b;return 0;
}

如果喜歡這篇博客的話(huà)不妨順手點(diǎn)個(gè)贊,收藏,評(píng)論,關(guān)注!
我會(huì)持續(xù)更新更多優(yōu)質(zhì)文章!!

http://www.risenshineclean.com/news/21590.html

相關(guān)文章:

  • 網(wǎng)站開(kāi)發(fā)要多錢(qián)廊坊網(wǎng)站設(shè)計(jì)
  • 貿(mào)易公司做網(wǎng)站愛(ài)鏈網(wǎng)中可以進(jìn)行鏈接買(mǎi)賣(mài)
  • 網(wǎng)站建設(shè) 質(zhì)量標(biāo)準(zhǔn)win10優(yōu)化大師怎么樣
  • 自動(dòng)的網(wǎng)站制作智慧軟文網(wǎng)站
  • 做阿里巴巴企業(yè)網(wǎng)站谷歌seo是什么
  • 做網(wǎng)站價(jià)位軟件推廣平臺(tái)有哪些
  • 博客型網(wǎng)站建設(shè)葉濤網(wǎng)站推廣優(yōu)化
  • hao123網(wǎng)站用什么程序做的網(wǎng)絡(luò)營(yíng)銷(xiāo)就是
  • 網(wǎng)站開(kāi)發(fā)人員結(jié)構(gòu)配比專(zhuān)業(yè)seo關(guān)鍵詞優(yōu)化
  • 保溫管有哪些網(wǎng)站做輕松seo優(yōu)化排名
  • 手機(jī)做網(wǎng)站多少錢(qián)搜索引擎營(yíng)銷(xiāo)的方法有哪些
  • 網(wǎng)站建設(shè)見(jiàn)站分析和準(zhǔn)備論文網(wǎng)站seo優(yōu)化網(wǎng)站
  • 建一個(gè)做筆記的網(wǎng)站提高工作效率
  • 購(gòu)物網(wǎng)站建設(shè)圖標(biāo)大全蘇州seo關(guān)鍵詞優(yōu)化軟件
  • 社交網(wǎng)站源代碼指數(shù)計(jì)算器
  • 虛擬主機(jī)和網(wǎng)站空間百度怎么推廣網(wǎng)站
  • 做網(wǎng)站電話(huà)銷(xiāo)售上海哪家seo好
  • 網(wǎng)站做快照深圳百度推廣seo公司
  • 網(wǎng)站上傳后后臺(tái)進(jìn)不去外鏈下載
  • 宜昌便宜做網(wǎng)站新聞最新消息
  • 用java編程做網(wǎng)站windows優(yōu)化大師的優(yōu)點(diǎn)
  • 免費(fèi)做網(wǎng)站公司哪家好百度公司官網(wǎng)入口
  • 寶雞做網(wǎng)站的公司網(wǎng)站平臺(tái)都有哪些
  • 垂直類(lèi)b2c網(wǎng)站北京網(wǎng)優(yōu)化seo優(yōu)化公司
  • 網(wǎng)站 域名綁定google中文搜索引擎
  • 東莞網(wǎng)站排名優(yōu)化seoapp軟件推廣怎么做
  • 新鄉(xiāng)專(zhuān)業(yè)網(wǎng)站建設(shè)公司地推團(tuán)隊(duì)如何收費(fèi)
  • wordpress禁止評(píng)論優(yōu)化品牌seo關(guān)鍵詞
  • 如今做哪些網(wǎng)站致富百度站長(zhǎng)工具官網(wǎng)
  • 騰訊云服務(wù)器可以做傳奇網(wǎng)站嗎我想在百度上做廣告怎么做