網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
struct
C 語(yǔ)言沒(méi)有其他語(yǔ)言的對(duì)象(object)和類(class)的概念,struct 結(jié)構(gòu)很大程度上提供了對(duì)象和類的功能。
下面是struct自定義數(shù)據(jù)類型的一個(gè)例子。
struct tag {
member-list
member-list
member-list
...
} variable-list;
聲明了數(shù)據(jù)類型car和該類型的變量car。
struct car
{
char *name;
float price;
int speed;
} mycar;
struct car myca = {"大眾", 178.9, 100};
mycar.name = "本田";
如果將 struct 變量傳入函數(shù),函數(shù)內(nèi)部得到的是一個(gè)原始值的副本。
#include <stdio.h>
struct turtle {
char* name;
char* species;
int age;
};
void happy(struct turtle t) {
t.age = t.age + 1;
}
int main() {
struct turtle myTurtle = {"MyTurtle", "sea turtle", 99};
happy(myTurtle);
printf("Age is %i\n", myTurtle.age); // 輸出 99
return 0;
}
上面示例中,函數(shù)happy()傳入的是一個(gè) struct 變量myTurtle,函數(shù)內(nèi)部有一個(gè)自增操作。但是,執(zhí)行完happy()以后,函數(shù)外部的age屬性值根本沒(méi)變。原因就是函數(shù)內(nèi)部得到的是 struct 變量的副本,改變副本影響不到函數(shù)外部的原始數(shù)據(jù)。
指針變量也可以指向struct結(jié)構(gòu)。
struct book {
char title[500];
char author[100];
float value;
}* b1;
上面示例中,變量b1是一個(gè)指針,指向的數(shù)據(jù)是struct book類型的實(shí)例。
為了使用指向該結(jié)構(gòu)的指針訪問(wèn)結(jié)構(gòu)的成員,必須使用 -> 運(yùn)算符,如下所示:
b1->title;//9-2.c
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
// 函數(shù)聲明
void printBook(struct Books *books);
int main()
{
struct Books Book1;
struct Books Book2;
/**
* Book1 描述
*/
strcpy(Book1.title, "C Programming");
strcpy(Book1.author, "Nuha Ali");
strcpy(Book1.subject, "C Programming Tutorial");
Book1.book_id = 6495407;
/* Book2 詳述 */
strcpy(Book2.title, "Telecom Billing");
strcpy(Book2.author, "Zara Ali");
strcpy(Book2.subject, "Telecom Billing Tutorial");
Book2.book_id = 6495700;
/* 通過(guò)傳 Book1 的地址來(lái)輸出 Book1 信息 */
printBook(&Book1);
/* 通過(guò)傳 Book2 的地址來(lái)輸出 Book2 信息 */
printBook(&Book2);
return 0;
}
void printBook(struct Books *book)
{
printf("Book title : %s\n", book->title);
printf("Book author : %s\n", book->author);
printf("Book subject : %s\n", book->subject);
printf("Book before book_id : %d\n", book->book_id);
(*book).book_id = (*book).book_id + 1;
printf("Book agter book_id : %d\n", book->book_id);
}
struct 結(jié)構(gòu)也可以作為數(shù)組成員。下面示例聲明了一個(gè)有1000個(gè)成員的數(shù)組books,每個(gè)成員都是自定義類型book的實(shí)例。
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main(int argc, char const *argv[])
{
struct Books books[1000];
books[0].book_id = 22;
books[0].book_id = 7;
return 0;
}
struct的嵌套
struct 結(jié)構(gòu)的成員可以是另一個(gè) struct 結(jié)構(gòu)。
struct species {
char* name;
int kinds;
};
struct fish {
char* name;
int age;
struct species breed;
};
上面示例中,fish的屬性breed是另一個(gè) struct 結(jié)構(gòu)species。
// 寫(xiě)法三
struct fish shark = {
.name="shark",
.age=9,
.breed={"Selachimorpha", 500}
};
引用breed屬性的內(nèi)部屬性,要使用兩次點(diǎn)運(yùn)算符(shark.breed.name)。
對(duì)字符數(shù)組屬性賦值,要使用strcpy()函數(shù),不能直接賦值,因?yàn)橹苯痈牡糇址麛?shù)組名的地址會(huì)報(bào)錯(cuò)。
strcpy(shark.breed.name), "Harry");
struct 結(jié)構(gòu)內(nèi)部不僅可以引用其他結(jié)構(gòu),還可以自我引用,即結(jié)構(gòu)內(nèi)部引用當(dāng)前結(jié)構(gòu)。比如,鏈表結(jié)構(gòu)的節(jié)點(diǎn)就可以寫(xiě)成下面這樣。
struct node {
int data;
struct node* next;
};
上面示例中,node結(jié)構(gòu)的next屬性,就是指向另一個(gè)node實(shí)例的指針。下面,使用這個(gè)結(jié)構(gòu)自定義一個(gè)數(shù)據(jù)鏈表。
// p9-2.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
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);
}
return 0;
}
實(shí)驗(yàn)
考慮下面發(fā)這些聲明和數(shù)據(jù),并debug
#include <stdio.h>
int main(int argc, char const *argv[])
{
struct NODE
{
int a;
struct NODE *b;
struct NODE *c;
};
// 5個(gè)成員的數(shù)組nodes
struct NODE nodes[5] =
{
{5, nodes + 3, NULL},
{15, nodes + 4, nodes + 3},
{22, NULL, NULL},
{12, nodes + 1, nodes},
{18, nodes + 2, nodes + 1},
};
struct NODE *np = nodes + 2;
struct NODE **npp = &nodes[1].b;
/* nodes 是數(shù)組,數(shù)組名就是該數(shù)組的指針,也是該數(shù)組第一個(gè)元素的指針 */
// 輸出該數(shù)組的地址
printf("nodes的地址是 %p\n", nodes); // 0x7ffeefbff460
printf("nodes的地址是 %p \n", &nodes);
printf("nodes+2的地址是 %p \n", nodes + 2);
// printf("%d\n", nodes.a)//錯(cuò)誤;指針訪問(wèn)屬性 需要使用 ->
printf("nodes[0] a的值 %d\n", nodes->a); // 5 通過(guò)指針訪問(wèn)
printf("(*nodes).a)的值 %d\n", (*nodes).a); // (*nodes)獲取的是nodes[1]
printf("nodes[3] a的值 %d\n", nodes[3].a); // 12
printf("nodes[3].c的值 %p\n", nodes[3].c); //0x7ffeefbff460
// 訪問(wèn)的是nodes[0]
printf("nodes[3].c->a的值 %d\n", nodes[3].c->a); // 5
// printf("%d\n", *nodes); 使用* 操作符對(duì)指針執(zhí)行間接訪問(wèn),*nodes的右值是nodes的整個(gè)結(jié)構(gòu)
// printf("%d\n", *nodes.a); //錯(cuò)誤
printf("nodes[4]的值地址 %p \n", &nodes[4]);
printf("nodes[3].b->b的值 %p \n", nodes[3].b->b); // nodes[3].b 獲取的是 nodes + 1 即 nodes[1]的指針,然后nodes[1]->b ,就是nodes[4]的指針
// [] () . -> 是一級(jí)運(yùn)算 從左往右邊 結(jié)合, * &是二級(jí)運(yùn)算
printf("*nodes[3].b->b的值 %p \n", *nodes[3].b->b); // {18, nodes + 2, nodes + 1},//最后運(yùn)算*,由前邊可以知道 nodes[3].b->b就是nodes[4]的指針,然后*,得到nodes[4]。看下一提題的驗(yàn)證
printf("nodes[3] a 的值 %d \n", (*nodes[3].b->b).a); // 18
printf("&nodes[3].a 的值%p \n", &nodes[3].a); // 數(shù)子12 第物理地址
// printf("&n??odes[3].c %p \n", &nodes[3].c);
printf("&nodes[3].c的值%p \n", &nodes[3].c->a); //數(shù)字15 的物理地址
printf("&nodes->a 的值%p \n", &nodes->a); //數(shù)字5 的物理地址
printf("nodes+2的地址是 %p \n", nodes + 2);
printf("np的值%p \n", np); // np為nodes[2]的地址
printf("np->a的值%d \n", np->a); // 12
// printf("np->c->c->a的值%d \n", np->c->c->a); // 12
printf("npp的值%p \n", npp); // np為nodes[2]的地址
// printf("npp->a的值%p \n", npp->a); // 非法
printf("*npp的值%p \n", *npp);
printf("**npp的值%p \n", **npp);
return 0;
}
原文鏈接:https://blog.csdn.net/m0_64407685/article/details/126663975
相關(guān)推薦
- 2022-12-28 C++關(guān)鍵字const使用方法詳解_C 語(yǔ)言
- 2022-02-01 uniapp 開(kāi)發(fā)h5 優(yōu)化加載速度
- 2023-11-23 記錄apscheduler任務(wù)模塊添加任務(wù)后立即執(zhí)行
- 2022-03-30 .Net?Core以windows服務(wù)方式部署_C#教程
- 2023-02-01 Bat腳本之在文件中查找多個(gè)字符串并保存到文件中_DOS/BAT
- 2022-07-06 C#使用ADO.Net連接數(shù)據(jù)庫(kù)與DbProviderFactory實(shí)現(xiàn)多數(shù)據(jù)庫(kù)訪問(wèn)_C#教程
- 2023-08-16 uniapp中v-model數(shù)據(jù)無(wú)法讀取問(wèn)題 failed for prop “value“
- 2023-05-22 關(guān)于PyTorch中nn.Module類的簡(jiǎn)介_(kāi)python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支