国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

我記不住的那些C語言的struct知識(shí)

這篇具有很好參考價(jià)值的文章主要介紹了我記不住的那些C語言的struct知識(shí)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

背景: 最近在重學(xué)C語言,目的是為了能看懂操作系統(tǒng)的底層代碼,也為后續(xù)使用C語言開發(fā)一個(gè)類似redis數(shù)據(jù)庫的中間件做準(zhǔn)備,于是又重新踏上了學(xué)習(xí)C語言的道路,早在上學(xué)期間就學(xué)習(xí)過C語言,但是很久都不用了,語法和技巧都忘記了。計(jì)算機(jī)的知識(shí)真是浩如煙海,用進(jìn)廢退。

本次學(xué)習(xí)struct,C語言沒有對(duì)象object也沒有類class,只有struct提供了對(duì)象object和類class的相似功能。 struct用于 封裝一個(gè)復(fù)雜物體的各個(gè)變量,例如: 學(xué)生,有姓名、學(xué)號(hào)、班級(jí)、年齡、性別等等參數(shù),他們非常相關(guān); 另外一個(gè)用途是 某些函數(shù)需要傳入多個(gè)參數(shù),我們把這些多個(gè)參數(shù)封裝到一個(gè)結(jié)構(gòu)體中,再進(jìn)行傳入這個(gè)結(jié)構(gòu)體或結(jié)構(gòu)體的指針,這樣方便快捷。 結(jié)構(gòu)體所表示的一條數(shù)據(jù),類似數(shù)據(jù)庫學(xué)生表的一行記錄。

1. 定義一個(gè)結(jié)構(gòu)體:

struct student {
    char* name;
    int num;
    int grade;
    int age;
    char sex;
};

// 聲明變量的同時(shí),對(duì)變量進(jìn)行賦值
struct student {
    char* name;
    int num;
    int grade;
    int age;
    char sex;
} s1 = {"xiaolong",1000,1,6,'m'},s2 = {"xiaopeng",1010,1,6,'m'};

2. 定義結(jié)構(gòu)體變量 并對(duì)結(jié)構(gòu)體進(jìn)行設(shè)置:

// 聲明自定義類型的變量時(shí),類型名前面,不要忘記加上struct關(guān)鍵字
struct student xiaoming;

xiaoming.name = "xiaoming";
xiaoming.num = 1001;
xiaoming.grade = 1;
xiaoming.age = 6;
xiaoming.sex = 'm';

// 這種方式需要注意 大括號(hào)里面 值的順序,必須與struct聲明時(shí)屬性的順序保持一致
struct student xiaohong = {"xiaohong",1002,1,6,'f'};

// 否則需要為每個(gè)值指定屬性名
struct student lihua = { .num=1003, .name="lihua", .sex='m', .age=7, .grade=2};

// 可以修改
lihua.age = 8;


// 也可以使用typedef命令

typedef struct student {
    char* name;
    int num;
    int grade;
    int age;
    char sex;
} stu;

// stu就是 struct student的別名
stu xiaohua = {"xiaohua",1020,1,6,'m'};

還有就是 多個(gè)結(jié)構(gòu)體嵌套,嵌套的初始化和設(shè)置與上面一致,這里不再贅述。

3. 結(jié)構(gòu)體的復(fù)制

賦值運(yùn)算符( = )可將 struct 結(jié)構(gòu)每個(gè)屬性的值,一模一樣的復(fù)制一份,拷貝給另外一個(gè)struct變量,與數(shù)組不同(使用賦值運(yùn)算符復(fù)制數(shù)組,不會(huì)復(fù)制數(shù)據(jù),只會(huì)共享地址)

如果 結(jié)構(gòu)體里面 有指針類型的變量,那么復(fù)制的是 指針的值,也就是說 兩個(gè)結(jié)構(gòu)體 指向的是同一個(gè)內(nèi)容,修改一個(gè)會(huì)影響另外一個(gè)的值。

如果 結(jié)構(gòu)體里面 沒有指針類型的變量,那么 復(fù)制的是 數(shù)據(jù)的值,是兩份毫無關(guān)系的數(shù)據(jù),各自修改不影響另外一個(gè)的值。

char* name ; 這種字符指針?biāo)赶虻淖址遣荒苄薷牡模荒苤匦轮赶蛞粋€(gè)新的字符串。

struct student { char name[30]; short age; } a, b;

strcpy(a.name, "xiaohu");
a.age = 18;

b = a;
b.name[0] = ' ';
b.name[1] = 'l';

printf("%s\n", a.name); // xiaohu
printf("%s\n", b.name); //  laohu


struct student2 { char name[30]; short age; } a2, b2;

a2.name = "xiaohu"
a2.age = 18;

b2 = a2;

b2.name = " laohu"       //  內(nèi)存新建了" laohu"字符串,b2的指針這次指向" laohu"

// 也就是說  a2.name 和 b2.name 不再指向同一塊地址空間

printf("%s\n", a2.name); // xiaohu
printf("%s\n", b2.name); //  laohu  這是為什么




struct student3 { char* name; short age; } a3, b3;

a3.name = "xiaohu";
a3.age = 18;

b3 = a3;

// 這是為了 修改字符串所做的測(cè)試, 結(jié)論是 無法修改,雖然能通過編譯,但是運(yùn)行失敗,顯示段錯(cuò)誤。
*(b3.name+0) = ' ';
*(b3.name+1) = 'l';

printf("%s\n", a3.name);
printf("%s\n", b3.name); 

4. 結(jié)構(gòu)體數(shù)組 和 結(jié)構(gòu)體指針

如果將 struct 變量作為參數(shù) 傳入函數(shù),則進(jìn)行了 結(jié)構(gòu)體的復(fù)制,一是會(huì)占用內(nèi)存,二是函數(shù)內(nèi)修改只是修改副本,而不會(huì)影響函數(shù)外部的原始數(shù)據(jù),所以 一般情況下,我們 使用 struct 指針?作為參數(shù) 傳入函數(shù)中。?

void happy(struct student* s){
    (*s).age = (*s).age + 1;   // . 優(yōu)先級(jí)比 * 高,所以需要使用()
}

happy(&xiaoming);


void happy2(struct student* s){
    s->age = s->age + 1 ;   // 或  s->age++; 自增
}

void happy2(struct student* s){
    s->age++;   // 自增 ,  -> 優(yōu)先級(jí)比 ++ 高
}

對(duì)于 struct 的變量 使用 . 獲取屬性,對(duì)于 struct的變量指針 使用 -> 獲取屬性。

xiaoming.age? ==? (*ptr).age == ptr->age

5. 通過 malloc來構(gòu)造鏈表

struct node {
  int data;
  struct node* next;
};

struct node* head;

// 生成一個(gè)三個(gè)節(jié)點(diǎn)的列表 (11)->(22)->(33)
head = malloc(sizeof(struct node));

head->data = 11;
head->next = malloc(sizeof(struct node));

head->next->data = 22;
head->next->next = malloc(sizeof(struct node));

head->next->next->data = 33;
head->next->next->next = NULL;

// 遍歷這個(gè)列表
for (struct node *cur = head; cur != NULL; cur = cur->next) {
  printf("%d\n", cur->data);
}

6. 空間對(duì)齊

struct所占用的空間不是各個(gè)屬性存儲(chǔ)空間的總和,而是最大內(nèi)存占用屬性的存儲(chǔ)空間倍數(shù),其他屬性會(huì)添加空位閾值對(duì)齊。

#include<stdio.h>

int main()
{
    struct student {
        char* name;  // 8 字節(jié)
        int num;     // 4 字節(jié)
        int grade;   // 4 字節(jié)
        int age;     // 4 字節(jié)
        char sex;    // 1 字節(jié)
    };
    printf("student %d\n",sizeof(struct student));

    struct student_other1 {
        char sex;    // 1 字節(jié)
        int num;     // 4 字節(jié)
        int grade;   // 4 字節(jié)
        int age;     // 4 字節(jié)
        char* name;  // 8 字節(jié)
    };
    printf("student_other1 %d\n",sizeof(struct student_other1));

    struct student_other2 {
        char sex;    // 1 字節(jié)
        char* name;  // 8 字節(jié)
        int num;     // 4 字節(jié)
        int grade;   // 4 字節(jié)
        int age;     // 4 字節(jié)
    };
    printf("student_other2 %d\n",sizeof(struct student_other2));
    return 0;
}

我記不住的那些C語言的struct知識(shí)

64位計(jì)算機(jī)?

student:? 8+ 4 + 4?+? 4 + 4 = 24? ?,最后一個(gè)?char sex 本身占用1個(gè)字節(jié),但是為了補(bǔ)齊,和前面的int age 組合成為了一個(gè) 8 字節(jié)。

student_other1 : 4 +4+4+4+8 =24 , 第一個(gè)char sex 本身占用1個(gè)字節(jié),但是為了補(bǔ)齊,和后面的int num?組合成為了一個(gè) 8 字節(jié)

student_other2:? 8 +? 8 + 8 + 8 =32 , 第一個(gè) char sex本身占用1個(gè)字節(jié),但是為了補(bǔ)齊7個(gè)字節(jié),這次單獨(dú)占用8個(gè)字節(jié);? 最后一個(gè) int age 4字節(jié)無法和其他人湊成 8字節(jié)的倍數(shù)了,只能被空位填充,補(bǔ)齊4個(gè)字節(jié),也就變成了8。

字節(jié)對(duì)齊是為了 提高讀寫效率,是存儲(chǔ)空間的倍數(shù), 示例中 最后一個(gè)是 把 占空間最大的指針放在了 屬性順序的中部,導(dǎo)致前面的屬性和后面的屬性都需要補(bǔ)空位才能實(shí)現(xiàn)對(duì)齊,而不是第一個(gè)和第二個(gè)可與其他屬性拼湊來實(shí)現(xiàn)字節(jié)對(duì)齊,所以 第三種是32個(gè)字節(jié)。

結(jié)論是: 不要把 本身所占空間大的屬性 寫在 中間,而是按照各屬性大小,從小到大進(jìn)行書寫,這樣最大的寫在尾部,即 存儲(chǔ)空間遞增的順序來書寫定義每個(gè)屬性,這樣能節(jié)省空間。

7.位字段

位字段其實(shí)就是 二進(jìn)制的位,比如: 在TCP/IP協(xié)議中,有一些標(biāo)志位如下圖所示:

我記不住的那些C語言的struct知識(shí)

?URG/ACK/RST/PSH/SYN/FIN 等標(biāo)志位

下面代碼僅做示例,不是真實(shí)的Linux tcp的代碼:

struct flag {
  unsigned int urg:1;
  unsigned int ack:1;
  unsigned int rst:1;
  unsigned int psh:1;
  unsigned int syn:1;
  unsigned int fin:1;
  unsigned int    :6;
  unsigned int head:4;
} flag;

flag.urg = 0;
flag.ack = 1;

printf("flag %d\n",sizeof(struct flag));

每個(gè)屬性后面的:1 表示指定這些屬性只占用 一個(gè)二進(jìn)制位,? :6代表保留的6位,:4代表是頭部4位。

8. 彈性數(shù)組成員

如果在struct中聲明數(shù)組成員,但我一開始不知道有多少,如果給定一個(gè)很大的數(shù)會(huì)浪費(fèi)空間。

struct vstring {
  int len;
  char chars[];
};
struct vstring* str = malloc(sizeof(struct vstring) + n * sizeof(char));
str->len = n;

彈性成員的數(shù)組,必須是 struct 結(jié)構(gòu)的最后一個(gè)屬性。另外,除了彈性數(shù)組成員,struct 結(jié)構(gòu)必須至少還有一個(gè)其他屬性。文章來源地址http://www.zghlxwxcb.cn/news/detail-469735.html

到了這里,關(guān)于我記不住的那些C語言的struct知識(shí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【C語言】struct結(jié)構(gòu)體

    【C語言】struct結(jié)構(gòu)體

    具有相同或不同類型元素的集合叫做結(jié)構(gòu)體。定義一個(gè)結(jié)構(gòu)體,本質(zhì)是在制作一個(gè)類型: 在C中,結(jié)構(gòu)體內(nèi)只能存放各種類型的變量,不能存函數(shù): 像上面這樣就是聲明了一個(gè)結(jié)構(gòu)體 struct Student ,此時(shí)的 struct Student 相當(dāng)于一個(gè)類型名。 然后我們可以用這個(gè)自己聲明的結(jié)構(gòu)體

    2024年02月03日
    瀏覽(20)
  • c語言中:struct timespec

    在C語言中, struct timespec 是一個(gè)結(jié)構(gòu)體,通常用于處理時(shí)間和時(shí)間間隔。這個(gè)結(jié)構(gòu)體通常包含以下兩個(gè)成員: tv_sec :這是一個(gè)長整型( long ),用于存儲(chǔ)秒數(shù)。它表示時(shí)間的整數(shù)部分,即秒數(shù)。 tv_nsec :這是一個(gè)長整型( long ),用于存儲(chǔ)納秒(nanoseconds)。它表示時(shí)間的小

    2024年02月09日
    瀏覽(16)
  • 【C語言】struct PLUS版~

    ??????https://blog.csdn.net/weixin_71138261/article/details/126999227?spm=1001.2014.3001.5501 ?基礎(chǔ)版在上面的鏈接中已經(jīng)詳細(xì)解說過了 但是上一次的代碼有很嚴(yán)重的問題: 如果我只想要儲(chǔ)存兩個(gè)人的信息,還要開辟100個(gè)人的信息嗎?沒有 如果儲(chǔ)存1000000個(gè),放不下了。 那么我們程序員

    2024年02月12日
    瀏覽(17)
  • 【go語言基礎(chǔ)】結(jié)構(gòu)體struct

    主要是敲代碼,敲的過程中會(huì)慢慢體會(huì)。 結(jié)構(gòu)體是用戶定義的類型,表示若干字段的集合,目的是將數(shù)據(jù)整合在一起。 簡(jiǎn)單的說,類似Java中的實(shí)體類。存儲(chǔ)某個(gè)實(shí)體屬性的集合。 注意:結(jié)構(gòu)體名字,結(jié)構(gòu)體屬性名的首字母大寫代表其余的包可以訪問該結(jié)構(gòu)體,類似Java中的

    2024年02月13日
    瀏覽(22)
  • Go語言入門6(struct 結(jié)構(gòu)體)

    ?結(jié)構(gòu)體是一種聚合的數(shù)據(jù)類型,是由零個(gè)或多個(gè)任意類型的值聚合成的實(shí)體。每個(gè)值稱為結(jié)構(gòu)體的成員 type + 結(jié)構(gòu)體名 + struct + {成員列表} ??如果結(jié)構(gòu)體成員名字是以大寫字母開頭的,那么該成員就是導(dǎo)出的。這是Go語言導(dǎo)出規(guī)則決 定的。一個(gè)結(jié)構(gòu)體可能同時(shí)包含導(dǎo)出和

    2023年04月12日
    瀏覽(20)
  • C語言中的typedef struct用法

    在學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)的時(shí)候,我經(jīng)常遇到typedef struct,剛開始感覺很別扭,查閱資料之后才真真理解了。 先從結(jié)構(gòu)體說起。 1、結(jié)構(gòu)體用法 如果要定義一個(gè)該結(jié)構(gòu)體變量,就需要:struct Student st1; 有沒有覺得很麻煩,我們隱隱約約察覺到,多寫一個(gè)struct很費(fèi)勁,因此才有了下面的

    2024年02月07日
    瀏覽(13)
  • ChatGPT之后,下個(gè)AIGC殺手級(jí)應(yīng)用已近在眼前

    ChatGPT之后,下個(gè)AIGC殺手級(jí)應(yīng)用已近在眼前

    魚羊 發(fā)自 凹非寺 量子位 | 公眾號(hào) QbitAI 大模型模式,正在新一波AIGC的浪潮里被再度驗(yàn)證。 從AI畫畫的出圈,到現(xiàn)如今ChatGPT的火爆,面向大眾的爆款產(chǎn)品接口背后,無不是大模型技術(shù)的突破創(chuàng)新。 而當(dāng)這種“大力出奇跡”的技術(shù)路徑價(jià)值愈發(fā)凸顯,行業(yè)內(nèi)外也不禁好奇:

    2024年02月10日
    瀏覽(25)
  • 【C語言】學(xué)數(shù)據(jù)結(jié)構(gòu)前必學(xué)的結(jié)構(gòu)體struct詳細(xì)

    【C語言】學(xué)數(shù)據(jù)結(jié)構(gòu)前必學(xué)的結(jié)構(gòu)體struct詳細(xì)

    佛祖說,他可以滿足程序猿一個(gè)愿望。程序猿許愿有生之年寫出一個(gè)沒有bug的程序,然后他得到了永生。 目錄 1、結(jié)構(gòu)體的聲明與定義 1.1結(jié)構(gòu)體是什么? 1.2為什么要有結(jié)構(gòu)? 1.3結(jié)構(gòu)體的聲明 1.4結(jié)構(gòu)體成員類型 1.5結(jié)構(gòu)體變量定義和初始化 2、結(jié)構(gòu)體成員的訪問 3、結(jié)構(gòu)體傳參

    2024年02月11日
    瀏覽(20)
  • python pyqt5與opencv 遇到的那些坑,pyqt5頁面搭建,設(shè)置pyqt5設(shè)置背景圖

    設(shè)置pyqt5的背景圖片,可以設(shè)置一個(gè)lable控件,將控件至于底層,然后設(shè)置他的背景圖 注意路徑 解決代碼 使用Qt Desiggnei 繪制界面后轉(zhuǎn)換成py代碼后 最好不要在生成的py頁面代碼添加 信號(hào)槽,到時(shí)候頁面改動(dòng)比較麻煩 轉(zhuǎn)換代碼 pyuic5 -o 【轉(zhuǎn)換后的.py】 【UI界面的.ui】 推薦的方

    2024年02月09日
    瀏覽(81)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包