結(jié)構(gòu)體
結(jié)構(gòu)體的聲明
結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個成員可以是不同類型的變量
struct tag
{
member-list;
}variable-list;
問:C++的new和C語言的結(jié)構(gòu)體有什么異同?
ChatAI答:
C++中的new
是一個運算符,用于在堆上分配動態(tài)內(nèi)存,并返回指向該內(nèi)存的地址。它會自動調(diào)用要分配的對象的構(gòu)造函數(shù),以便初始化新分配的內(nèi)存。與之相反,C語言中的結(jié)構(gòu)體只是一種用戶自定義的數(shù)據(jù)類型。我們可以在棧上或者堆上申請結(jié)構(gòu)體變量內(nèi)存,但在C語言中不會自動調(diào)用結(jié)構(gòu)體的構(gòu)造函數(shù)。
C++中的new
還有一個重載版本,可以顯式地調(diào)用類的構(gòu)造函數(shù)來初始化新分配的內(nèi)存。而在C語言中,如果結(jié)構(gòu)體中有指向其他類型的指針,需要手動分配空間并進(jìn)行初始化,否則可能導(dǎo)致內(nèi)存泄漏或者越界錯誤。
此外,C++中的new
還可以拋出異常,而C語言中的結(jié)構(gòu)體是不支持異常處理的。
綜上所述,C++中的new
提供了更高級別的內(nèi)存分配方式,同時還能夠自動調(diào)用構(gòu)造函數(shù)來初始化,更加方便和安全。
問:匿名結(jié)構(gòu)體可以聲明了一個集合后再聲明另外一個不一樣集合的匿名結(jié)構(gòu)體嗎?
ChatAI答:
可以,匿名結(jié)構(gòu)體的定義與使用方式與普通結(jié)構(gòu)體一樣,可以在同一作用域內(nèi)用多個匿名結(jié)構(gòu)體類型的變量或聲明。
下面是一個示例代碼:
#include <stdio.h>
int main()
{
struct {
int x;
int y;
} s1 = {1, 2}, s2 = {3, 4};
struct {
double x;
double y;
} s3 = {1.23, 4.56}, s4 = {7.89, 9.87};
printf("s1: x=%d, y=%d\n", s1.x, s1.y);
printf("s2: x=%d, y=%d\n", s2.x, s2.y);
printf("s3: x=%f, y=%f\n", s3.x, s3.y);
printf("s4: x=%f, y=%f\n", s4.x, s4.y);
return 0;
}
在這個例子中,我們在同一作用域內(nèi)定義了兩個不同的匿名結(jié)構(gòu)體,其中s1
和s2
類型相同,而s3
和s4
類型相同??梢钥吹?,它們被視為兩個不同的結(jié)構(gòu)體類型,內(nèi)部成員的類型和名稱可以不同。在使用時,也沒有區(qū)別,可以直接使用.
操作符訪問內(nèi)部成員。
問:C++的鏈表和C的鏈表有何異同
ChatAI答:
C語言和C++語言中的鏈表在實現(xiàn)和使用上有一些異同點:
-
數(shù)據(jù)結(jié)構(gòu)實現(xiàn)
- C語言中通常使用結(jié)構(gòu)體來實現(xiàn)鏈表的節(jié)點,結(jié)構(gòu)體內(nèi)部包含指向前驅(qū)和后繼節(jié)點的指針。
- C++語言中可以使用類(class)或結(jié)構(gòu)體(struct)來實現(xiàn)鏈表節(jié)點,通過類或結(jié)構(gòu)體實現(xiàn)的鏈表節(jié)點可以使用類的成員函數(shù)來實現(xiàn)插入、刪除、遍歷等操作。
-
頭文件和命名空間
- 在C語言中,鏈表通常以結(jié)構(gòu)體和相關(guān)的函數(shù)以及宏定義形式定義在單獨的頭文件中,并且可能需要包含其他系統(tǒng)頭文件以使用標(biāo)準(zhǔn)庫函數(shù)、類型和宏定義等。
- 在C++語言中,鏈表的實現(xiàn)通常放在類或命名空間中。例如,可以使用
std::list
來定義一個標(biāo)準(zhǔn)庫中的鏈表實現(xiàn)。
-
模板支持
- C語言不支持模板,因此需要在代碼中每次為需要操作的數(shù)據(jù)類型編寫專門的函數(shù)。
- C++支持模板,可以使用通用的泛型編程方式來實現(xiàn)鏈表,從而支持對任何類型數(shù)據(jù)進(jìn)行操作。
-
對象和構(gòu)造函數(shù)/析構(gòu)函數(shù)支持
- 在C語言中,鏈表通常由一組函數(shù)和結(jié)構(gòu)體成員變量構(gòu)成,沒有構(gòu)造函數(shù)和析構(gòu)函數(shù)的概念,因此需要手動初始化和清理鏈表的節(jié)點和指針。
- 在C++語言中,鏈表可以作為一個對象來看待,支持使用構(gòu)造函數(shù)和析構(gòu)函數(shù)進(jìn)行自動初始化和清理。必要的資源申請和釋放由構(gòu)造函數(shù)和析構(gòu)函數(shù)負(fù)責(zé)處理,使用起來更加方便。
除了上述區(qū)別,C++語言中的鏈表還可以利用STL標(biāo)準(zhǔn)庫提供的迭代器、算法和其他容器等功能,提供更豐富的數(shù)據(jù)結(jié)構(gòu)和算法支持??偟膩碚f,C++語言的鏈表實現(xiàn)更加現(xiàn)代化、方便、可靠和安全。
結(jié)構(gòu)體內(nèi)存對齊
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
struct S1
{
char c1;
int a;
char c2;
};
struct S2
{
char c1;
char c2;
int a;
};
struct S3 //16
{
double d;
char c;
int i;
};
struct S4 //32
{
char c1;
struct S3 s3;
double d;
};
int main()
{
struct S1 s1 = { 0 };
printf("%d\n", sizeof(s1));//12
struct S2 s2 = { 0 };
printf("%d\n", sizeof(s2));//8
return 0;
}
輸出:12 8
結(jié)構(gòu)體的對齊規(guī)則:
1、第一個成員在結(jié)構(gòu)體變量偏移量為0的地址處。
2、其他成員變量要對齊到某個數(shù)字(對齊數(shù))的整數(shù)倍的地址處。
對齊數(shù)=編譯器默認(rèn)的一個對齊數(shù)與該成員大小的較小值。
VS中默認(rèn)的值為8 gcc沒有默認(rèn)對齊數(shù)
3、結(jié)構(gòu)體總大小為最大對齊數(shù)(每個成員變量都有一個對齊數(shù))的整數(shù)倍。
4、如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。
修改默認(rèn)對齊數(shù)
#pragma pack(4)
#pragma pack()
C語言結(jié)構(gòu)體偏移量
在C語言中,結(jié)構(gòu)體是一種用戶自定義的數(shù)據(jù)類型,它允許將不同的變量類型組合在一起,并按照用戶定義的方式對它們進(jìn)行存儲。結(jié)構(gòu)體中的每個成員在內(nèi)存中是按照定義的順序依次存放的,每個成員的偏移量從結(jié)構(gòu)體變量的起始地址開始依次增加??梢允褂肅語言中的“offsetof”宏來計算結(jié)構(gòu)體中各個成員的偏移量,語法如下:
#include <stddef.h>
#define offsetof(type, member) ((size_t) &((type *)0)->member)
其中,type表示結(jié)構(gòu)體類型,member表示結(jié)構(gòu)體成員名。使用這個宏,可以計算處任意結(jié)構(gòu)體類型中指定成員的偏移量。文章來源:http://www.zghlxwxcb.cn/news/detail-457239.html
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stddef.h>
struct S
{
char c;
int i;
double d;
};
int main()
{
//offsetof();
printf("%d\n", offsetof(struct S, c));
printf("%d\n", offsetof(struct S, i));
printf("%d\n", offsetof(struct S, d));
return 0;
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-457239.html
結(jié)構(gòu)體傳參
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
struct S
{
char c;
int a;
double d;
};
void Init(struct S* ps)
{
ps->a = 100;
ps->c = 'w';
ps->d = 3.14;
}
int main()
{
struct S s;
Init(&s);
return 0;
}
到了這里,關(guān)于第四十九天學(xué)習(xí)記錄:C語言進(jìn)階:結(jié)構(gòu)體的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!