定義結構體類型
struct stu
{
char name[20];
int age;
char sex[10];
};
```、
//以下定義結構體指針的寫法不太推薦,但需要了解。
```c
typedef struct stu
{
char name[20];
int age;
char sex[5];
char id[20];
}stu, *stu_p, stu_arr[10];//
//定義結構體類型
//定義了一個指針類型 類似於int *
//定義了一個數組類型 類似於int arr
int main()
{
stu a = { "zhangsan",18, "man", "001" };
stu_p p = &a; //p 是指針的名字
stu_arr arr1; //arr1 是數組的名字 是有十個結構體變量的集合
下面的寫法就一目瞭然,能夠很容易知道是個什麼變量,(與上面的是等效的)
stu student1 = { "zhangsan", 29, "man" };
stu *p = &student1;
stu arr[10];
結構體成員可以是標量(int \float\double…),嵌套數組,指針,甚至是其他結構體。
重命名
typedef struct stu
{
char name[20];
int age;
char sex[10];
}stu_t;
struct stu 叫做結構體類型
就類似於 int float double 這個意思
有的時候覺得寫起來太複雜就重命名stu_t,此時struct stu 等於stu_t。
結構體賦值
struct stu student1 = { "zhangsan", 29, "man" };
struct stu student2 = { "lisi",18, "felman" };
student1 、 student2 就相當於變量名。
舉個例子 int a=10; a 就相當於這裏的student1 、 student2。 花括號裏面就是賦值。
強調
結構體和數組一樣都是一個聚合類型。聚合類型除了在初始化的時候可以整體賦值,其餘時候都不能整體賦值
對於數組,循環賦值。
對於結構體,用. 操作符賦值。
//以下爲錯誤用法
int arr[5];
arr={1,2,3,4,5};
stu a;
a={ "zhangsan",18, "man", "001" };
struct stu s
{
char name[20];
int age;
}
int main()
{
struct stu s;
strcpy(s.name,"zahngsan"); // 錯的 name 是一個數組,不能直接賦值 s.name="zhangsan"
s.age=20;
return 0;
}
成員訪問
printf("%s %d %s", student1.name, student1.age, student1.sex)
對於一個變量必須提到的三個問題:空間,內容,地址。
下面主要介紹關於地址。
既然是一個變量自然可以取地址
stu_t student1 = { "zhangsan", 29, "man" };
stu_t *p = &student1;//與上面的定義一個指針類型是一樣的效果
printf("%s %d %s\n", (*p).name, (*p).age, (*p).sex);//優先級問題
printf("%s %d %s\n", p->name, p->age, p->sex);
->主要是對結構體指針 來引用成員名字。
printf("%s %d %s\n", (*p).name, (*p).age, (*p).sex)
這種寫法實在太過於複雜,因而有了-> .
以下報錯: 注意優先級問題
事實上 . 的優先級比*高,會先和p 結合,故而報錯。
printf("%s %d %s\n", *p.name, *p.age,*p.sex);
結構體傳參數,傳值 ,拷貝
結論
結構體不談“退化、降維”問題,結構體要發生對應的硬拷貝(注意:結構體內部的數組也是硬拷貝)
但數組傳遞參數本身就發生降維問題。
建議
結構體傳參的時候,要傳結構體的指針
void show(stu_t s)
{
printf("%s %d %s", s.name, s.age,s.sex);
printf("show:%p\n", &s);
}
int main()
{
stu_t student1 = { "zhangsan", 29, "man" };
stu_t *p = &student1;
show(student1);
printf("main:%p\n", &student1)
system("pause");
return 0;
}
//區分以下有什麼區別。
void show(stu_t *p)
{
printf("%s %d %s\n", p->name, p->age, p->sex);
printf("show:&*p:%p\n", p);//用的是指針變量p 的內容
printf("show:&p:%p\n", &p);
}
int main()
{
show(&student1);
printf("main:%p\n", &student1);
system("pause");
return 0;
}
//如果是指針其實打印出來的兩個地址是一樣的
覆盤
很重要的一個點就是,學習的過程是由厚到薄。抓住核心,歸納總結。
如果覺得自己越學越難,越學越多,越複雜,可能需要重新找一下方法。理解內在邏輯關係。