第10章 結構型、共用型、枚舉型及用戶自定義型數據

花費一個下午和一個晚上我抄了這麼多東西,那麼我有怎用的收穫呢?2016年11月2日
我總是抄這些知識點是個壞習慣。。。需要想辦法解決

  • 數組、變量一旦定義以後只能存儲定義的類型數據
  • 一個結構體變量可以包含不同的數據類型的數據
  • 結構體類型是C語言中最重要的構造數據類型。

結構體類型概念及其應用

共用體類型
枚舉類型
結構體數組
結構體指針
typedef定義

10.1 結構體類型

10.1.1 結構體類型簡介

  • 結構體類型是不同類型數據的集合,它是用戶自己定義的數據類型。
    (1)結構體中可以包含不用類型的數據,數組只能包含同一類型的數據
    (2)結構體可以相互賦值,而數組不能直接相互賦值。因爲結構體類型本身是數據類型,而數組是同一類型數據的集合。

10.1.2 結構體類型定義

在C語言中,一個學生的信息可以用如下結構體保存:

struct s
{
    char name[10];
    int age;
    char[sex];
}
上述語句定義一個結構類型s,s爲結構體名,大括號中爲一個結構體包含的成員
字符型數組
整形變量
字符型變量

結構體定義形式如下:

struct 結構體名
{
    結構體成員
}

結構體成員可以是變量、數組、指針、等數據類型,定義了結構體之後,就可以用它來聲明結構體變量。
結構體變量聲明以後,即可引用結構體中的成員。

結構體變量的定義方式有以下三種:

(1)先定義結構體,後定義結構體變量。

struct s
{
    char name[10];
    int age;
    char sex;
};
struct s s1,s2;

通過結構體S定義了兩個結構體變量s1和s2,程序可以直接引用兩個結構體變量中的成員。

(2)定義結構體同時定義結構體變量

struct s
{
    char name[10];
    int age;
    char sex;
}s1,s2;

在定義結構體的同時定義了兩個結構體變量s1和s2;

(3)只定義結構體變量

struct
{
    char name[10];
    int age;
    char sex;
}S1,S2;

沒有定義結構體類型名,直接定義了兩個結構體變量s1和s2,因爲沒有定義結構體類型名,因此除了直接定義,不能使用其他方式定義定義結構體變量。

注意:
(1)結構體是用戶自定義類型,結構體可用來定義結構體變量,但不能用來傳遞信息。
(2)結構體中可以嵌套另外一個結構體,即一個結構體中可以包含多個結構體。

struct time
{
    int hour;
    int minute;
    int second;
};
struct data
{
    int day;
    int month;
    int year;
    struct time t;
}d;

在結構體中嵌套了結構體,通過結構體可以用來調用結構體中的成員

10.1.3 結構體類型引用

定義結構體變量之後,可以通過操作符’.‘來引用結構體中的成員。

結構體成員的引用方式:  結構體變量名.成員名;
struct s
{
    char name[10];
    int age;
    char sex;
}s1;

結構體大括號後的分號爲結構體定義基本形式,若沒加上則會出錯。

範例10.1:從鍵盤上輸入一個學生的信息,將這些信息存儲至結構體中並輸出。
分析:定義一個結構體,包含學生的一些基本信息,然後對結構體進行賦值,最後輸出結構體中的成員。

#include <stdio.h>
void main()
{
    struct s
    {
        char name[10];
        int age;
        char sex;
        float score;//定義結構體類型變量s1
    }s1;
    printf("輸入學生姓名:");
    gets_s(s1.name);
    printf("輸入學生的性別:");
    s1.sex=getchar();
    printf("輸入學生歲數:");//從鍵盤獲取字符串保存至結構體相應的變量中
    scanf("%d",&s1.age);
    printf("輸入學生的分數:");
    scanf("%f",&s1.score);
    printf("年齡:%s\n",s1.name);
    printf("名字:%s\n",s1.age);
    printf("性別:%c\n",s1.sex);//輸出這些信息至屏幕上
    printf("分數:%f\n",s1.score);

}

10.1.4結構體變量初始化

結構體變量與變量相似,在定義結構體變量的同時便可對其各個成員賦初始值,即結構體變量的初始化。

結構體變量的初始化與定義類似:

(1)第一種方式:

struct s
{
    char name[10];
    int age;
    char sex;
    float score;
};
struct s s1={'lihai',20,'M',90.5}

(2)第二種方式

struct
{
    char name[10];
    int age;
    char sex;
    float score;
}s1={'lihai',20,'M',90.5};

不能在結構體內部進行初始化

struct
{
    char name[10] ="LiHai";
    int age = 20;
    char sex ='M';
    float score =90.5;
}s1;

10.2 結構體數組

10.2.1 結構體數組定義

結構體定義形式與數組定義形式類似:

(1)先定義結構體,後定義結構體數

struct s
{
    char name[10];
    int age;
    char sex;
    float score;
};
struct s a[10];

(2)定義結構體的同時定義結構體數組

struct s
{
    char name[10];
    int age;
    char sex;
    flaot score;
}a[10];
定義了包含10個元素的結構體數組,每一個結構體元素佔據17個字節,其中字符型數組佔10個字節,整形變量佔2個字節,字符型變量佔1個字節,浮點型變量佔4個字節

10.2.2 結構體數組引用

結構體數組定義以後,通過下標即可引用相應的結構體元素。

範例10.2現有3個候選人,10個人進行投票,統計每一個候選人的票數。
分析:將這3個候選人定義爲結構體類型,10個人進行投票,將每個人的投票與結構體中的名字進行比較,若相等則其票數加1,最後輸出3個候選人的票數。

#include <stdio.h>
#include <string.h>

struct
{
    char name[10];
    int c;
}p[3] = {"zhang",0,"li",0,"hu",0};
void main()
{
    int i, j;
    char n[10];
    for (i = 0; i < 10; i++)
    {
        scanf("%s",n);
        for (j = 0; j < 3; j++)
        {
            if (strcmp(n, p[j].name) == 0)
                p[j].c++;
        }
    }
    printf("最終的結果:\n");
    for (j = 0; j < 3; j++)
        printf("%s:%d票\n",p[j].name,p[j].c);
}

#  10.2.3 結構體數組的初始化

結構體數組可以在定義時就賦予初值,即進行初始化。結構體數組初始化方式有兩種。
(1)初始化數組所有元素

struct
{
    char name[10];
    int age;
    float score;
}s[3]={{"Zhang lin",20,80.5},{"Li Tao",19,89.0},{"Xiu Yan",21,90.0}};

定義一個包含三個元素的結構體數組,並對其中所有元素進行了初始化。
(2)初始化數組部分元素,且結構體中嵌套另一個結構體。

struct Time
{
    int hour;
    int minute;
    int second;
    struct Data
    {
    int year;
    int month;
    int day;
    }
    }t[10]={
{6,56,34,(2009,5,24)},
{7,35,56,(2010,7,2)};
};

10.3 結構指針

結構指針指向已定義的結構體變量在內存中的首地址,從而對地址中的內容進行操作。

10.3.1 結構體指針概念及其定義

結構體指針可以指向結構體變量的首地址,其定義形式如下:

struct 結構體類型 *指針名

struct st
{
    char name[10];
    int age;
    char sex;
    float score;
}s;
struct st *p;

定義一個結構體st的指針P,但其值是不確定的。通過以下語句可將結構體變量s的地址賦給p,使p指向結構體變量

p = & s;
其中‘&’爲取地址符,&s表示結構體變量S的地址。指針賦值後,通過指針即可訪問結構體中的成員。
(*p).name (*p).sex
括號不能省去,因爲”.“的優先級比”.“高。
在C語言中通過指針還可以用另外一種方式來訪問結構體成員,即使用運算符”–>“

p --> name      p-->age        p-->sex

10.3.2 結構體數組指針

結構體數組也可以定義指針,通過指針對其進行操作
(1)(++p)->num和(p++)–>num的區別
先使P的值加1,使P指向數組的下一個元素,再訪問該元素的結構體成員num
先訪問元素的結構體成員num,再使p的值加1,指向下一個元素。
(2)結構體數組指針P指向數組有以下三種方式

p=s;   p=&s;   p=&s[0];

10.3.3 結構體指針應用

gets_s函數不接受一個參數
double
printf 格式字符串需要類型char的參數,但可變參數1擁有了類型double

#include <stdio.h>
#include <stdlib.h>

struct st
{
    char name[10];
    char age[5];
    char sex[6];
    float score;
}s;//結構體變量s
void main()
{
    struct st *p = &s; //定義結構指針
    char a[20];
    printf("輸入名字:");//實現結構成員的數據輸入
    gets_s(p->name);
    printf("輸入年齡: ");
    gets_s(p->age);
    printf("輸入性別: ");
    gets_s(p->sex);
    printf("輸入分數: ");
    //gets_s(s);
    //p->score = atof(s);//該函數的功能是將字符型數據轉化爲浮點型數據
    printf("名字:%s\n",p->name);
    printf("性別:%s\n",p->sex);
    printf("年齡:%s\n",p->age);
    printf("分數: %s\n",p->score);

}

10.4 結構與函數參數

  • 結構體可以用來作爲函數的參數

10.4.1 結構體變量作爲函數參數

  • 將結構體變量作爲實參傳遞給一個函數
  • 將結構體變量的值傳遞給函數,即傳值調用

範例10.7 編寫一個程序,將結構體變量作爲實參傳遞給其他的函數,

分析:結構體變量直接傳遞給函數,是傳值調用,因此函數內形參值的變化不會影響實參的值。

#include <stdio.h>
#include <stdlib.h>

struct st
{
    char name[10];
    char age[5];
    char sex[6];
    float score;
};
void out(st stu)//自定義函數
{
    printf("名字:%s\n",stu.name);//輸出結構體成員
    printf("性別:%s\n",stu.sex);
    printf("年齡:%s\n",stu.age);
    printf("分數:%s\n",stu.score);
}
void in(st stu)
{
    char score[10];
    printf("輸入名字: ");//從鍵盤獲取字符串至stu.name
    gets_s(stu.name);
    printf("輸入年齡: ");
    gets_s(stu.age);
    printf("輸入性別: ");
    gets_s(stu.sex);
    printf("輸入分數: ");
    gets_s(score);
    stu.score = atof(score);
    out(stu);//調用OUT()函數輸出學生信息
}
    void main()
    {
        struct st s =                          {"LiMing","20","man",87.5};
        in(s);
        out(s);//調用in()函數
    }

注意:
雖然in()函數中對結構體變量重新進行賦值,但由於傳遞方式爲傳值調用,因此不會影響主函數main()中結構體變量的值。

10.4.2 結構體地址作爲函數參數

  • 將結構體變量地址作爲參數傳遞給函數,則形參應爲相同類型的指針,這種方式爲傳址方式,因此函數內結構體變量值的變化會影響實參。

範例10.8 編寫一個程序,將結構體變量的地址作爲實參傳遞給其他的函數

分析:結構體變量地址傳遞給函數,是傳址調用。因此形參值的變化不會影響實參值。

#include <stdio.h>
#include <stdlib.h>

struct st
{
    char name[10];
    char age[5];
    char sex[6];
    float score;
};
void out(st stu)
{
    printf("名字: %s\n",stu.name);
    printf("性別: %s\n",stu.sex);
    printf("年齡: %s\n",stu.age);
    printf("分數: %s\n",stu.score);
}
void in(st *stu)
{
    char score[10];
    printf("輸入名字:");
    gets_s(stu->name);
    printf("輸入性別:");
    gets_s(stu->sex);
    printf("輸入分數:");
    gets_s(score);
    stu->score = atof(score);
}
void main()
{
    struct st s = { "Li maing","20","man",87.5};
    out(s);
    in(&s);
}

10.4.3 結構體數組作爲函數參數

  • 數組名可以代表數組的首地址。結構體數組可以作爲參數傳遞給函數,即將結構體數組的首地址傳遞給函數。

範例10.9 編寫一個程序,將結構體數組作爲實參傳遞給其他的函數。

分析:結構體數組傳遞給函數,即將結構體數組首地址傳遞給函數,然後便可以對數組中的內容進行操作。

#include <stdio.h>
#include <stdlib.h>

struct st
{
    char name[10];
    char age[5];
    char sex[6];
    float score;
};
void prin(st s[])
{
    int i;
    for (i = 0; i < 3; i++)
    {
        printf("名字:%s\n",s[i].name);
        printf("年齡:%s\n",s[i].age);
        printf("性別: %s\n",s[i].sex);
        printf("分數:%s\n",s[i].score);
    }
}
void main()
{
    struct st s[3] = {
        {"Li Ming","20","man",87.0},
        {"Hu Su","19","women",89.0},
        {"Jun Yi","21","man",90.5}
    };
    prin(s);
}

10.5共用體

都是將不同的數據類型組合在一起,共用體與結構體所佔的空間不同

10.5.1 共用體概念及其定義

  • 共用體爲用戶自定義構造類型
  • 結構體類型存儲時採用覆蓋方式,即後一個類型的數據會覆蓋前一個類型數據。
  • 結構體變量所佔空間爲所有成員佔據的空間之和。
  • 共用體變量所佔空間爲成員中所佔空間最大的成員字節數。

共用體定義形式如下

union  共用體名
{
    成員表
}共用體變量名;

例子:

union  day
{
    int x;
    float y;
    double z;
    char c;
}t;

成員指針運算符
成員選擇運算符

結構體與共用體的區別:

對共用體變量進行操作,可以通過’.‘和 ’->‘運算符來實現。若操作對象爲共用體變量,則用”.“運算符。若操作對象爲共用體類型指針,則使用”->”運算符。
- (1)結構體成員都有自己的存儲空間。結構體變量所佔存儲空間爲各個成員所佔存儲空間之和
共用體變量所佔存儲空間爲各個成員中佔存儲空間最大的成員的字節數。
- (2)結構體變量可以同時對其所有成員賦值,
共用體類型不能同時對所有的成員賦值,只能單獨賦值
- (3)結構體變量可以初始化,
共用體在定義時不能賦值

10.5.2 共用體變量應用

要引用共用體變量中成員,可以通過共用體變量來引用,也可以通過共用體指針來引用。

(1)共用體變量的值爲最後一次賦的值

union  day
{
    char c;
    int i;
    float j;
}t;
t.c ='f';
t.i ='6';
t.j =4.5;
最後一個共用體變量t的值爲4.5,前面兩個值都被覆蓋。

(2)共用體變量在定義時不能賦值
如何定義共用體變量?

union day
{
    char c;
    int i;
    float j;
}t={'z',4,9.0};
上述程序是錯誤的

(2)不能對共用體變量整體進行賦值。

union day
{
    char c;
    int i;
    float j;
}t;
t='w';
t=98;
最後兩行都是錯誤的

(4)與結構體類似,可以定義數組

union  day
{
    char c;
    int i;
    float j;
}t[5];

範例10.10:通過下面的例子,瞭解共用體的存儲過程

分析:共用體是用戶自定義類型,是不同數據類型的集合。

#include <stdio.h>

union
{
    int x;
    char y;
    float z;
}s;
void main()
{
    printf("sizeof(s.x)=%d\n",sizeof(s.x));
    printf("sizeof(s.y)=%d\n",sizeof(s.y));
    printf("sizeof(s.z)=%d\n",sizeof(s.z));
    printf("sizeof(s)=%d\n",sizeof(s));
}

10.5.3 共同體與結構體的嵌套

C語言中,結構體還可以與共用體嵌套使用

範例10.11 編寫一個程序,實現結構體與共用體的嵌套使用。

分析:
結構體可以嵌套共用體,共用體也可以嵌套結構體。當要引用其中的成員時,可以通過”.“或者”->”

#include <stdio.h>

void main()
{
    struct std
    {
        union
        {
            int m;
            int n;
        }a;
        int x;
        int y;
    }s;
    s.x = 3;
    s.y = 5;
    s.a.m = s.x*s.y;
    s.a.n = s.y - s.x;
    printf("結果:%d,%d\n",s.a.m,s.a.n);
}

範例10.12
現假設有若干人的信息要記錄,其中包括學生和老師。學生的信息包括姓名、性別、編號、職業、平均成績,老師的信息包括姓名、性別、編號、職業、任課科目,編寫一個程序,從鍵盤上輸入數據,並將結果輸出至屏幕。

#include <stdio.h>

struct
{
    char n[10];
    char sex;
    char num[20];
    char j;
    union
    {
        float score;
        char course[10];
    }a;
}s[3];

void main()
{
    int i;
    for (i = 0; i < 3; i++)
    {
        scanf("%s %c %c",&s[i].n,&s[i].sex,&s[i].num,&s[i].j);
        if (s[i].j == 's')
            scanf("%f", &s[i].a.score);
        else
            scanf("%f",&s[i].a.course);
    }
    for (i = 0; i < 3; i++)
    {
        if (s[i].j == 's')
            printf("%s,%c,%s,%c,%f\n", s[i].n, s[i].sex, s[i].num, s[i].j, s[i].a.score);
        else
            printf("%s,%c,%s,%c,%s\n", s[i].n, s[i].sex, s[i].num, s[i].j, s[i].a.course);
    }
}

10.6 枚舉類型

enum 枚舉類型名(枚舉元素表)

例子:

enum  color(red,blue,green,white,black);

enum爲關鍵字,color爲枚舉類型名
red 、blue green white 和black爲枚舉元素

定義了枚舉類型後,可以用來定義枚舉類型的變量

enum  color a,b;

定義了兩個**枚舉類型變量**a和b,其取值範圍在枚舉元素之內,只能爲其中的某一個值。

a=red;
b=white;

枚舉類型具有以下4個特點。
(1)枚舉元素爲常量,從起始位置開始值爲0,1,2。。。

enum color(red,blue,green,white,black);
enum color c;
c= green;
printf("%d",c);

輸出結果爲2,因爲green在枚舉元素的第三個位置,因此其默認值爲2.

(2)枚舉元素爲常量,不能賦值,但可以在定義時進行賦值

enum color(red,blue,green,white,black);
red =5;
green = 0;
上述程序是錯誤的,編譯時將會出錯

(3)枚舉常量可以用來進行比較

if(c>red)
if(c<white)
因爲枚舉元素都有一個默認值,因此可將枚舉類型變量的值與枚舉元素進行比較。

(4)枚舉類型不能直接進行賦值,但可以強制轉化進行賦值。

c =4;
是錯誤的
c = (enum color)4;
將數字強制轉化再進行賦值,是正確的

範例10.13 現有紅、黃、藍、綠、白5中顏色,從中取出兩個球,打印出所有可能的結果。

#include <stdio.h>

void main()
{
    enum color { red, yellow, blue, green, white };
    enum color i, j;
    for (i = red; i <= white; i++)
    {
        for (j = red; j <= white; j++)
            if (i != j)
                printf("%d ,%d\n", i, j);
    }

}
//枚舉類型上的此操作需要適用於用戶定義的運算符函數
二進制“++”:“main::color”不定義該運算符或到預定義運算符可接收的類型的轉換   

10.7 用戶自定義類型

C語言中可以用關鍵字typedef爲已有類型重新定義名稱,其定義形式如下:

typedef  類型名 標識名

其中類型名可以爲C語言中的任意類型,標識名用戶自己命名的名字。

typedef  int integer

上述程序用integer表示int類型。

integer x;
int x;

定義變量的方式是等價的,都表示定義一個整型變量

10.14 編寫一個程序,通過typedef自定義類型

分析:typedef關鍵字自定義類型,但它不是創建一個新的類型,而是將已有的類型用新的標識符來表示。

#include <stdio.h>
typedef union  //通過typedef自定義類型
{
    int a[5];
    float b[5];
    char c[5];
}ns;
void main()
{
    ns x;  //通過自定義類型定義變量
    printf("共用體所佔空間:%d\n",sizeof(x));
}
//本例用typedef 自定義類型
//通過關鍵字typedef爲共同體類型定義了一個新的標識符
//利用新定義的標識符定義變量

10.8 鏈表

鏈表是C語言中重要的數據結構,常常被用來處理大量數據。雖然數組也可以用來存儲大量的數據,但數據必須要先聲明其大小才能使用。在程序的執行過程中不能改變數組的大小,因此定義時一般將數組定的很大,這樣往往會造成存儲空間的浪費。
鏈表是一種動態的存儲結構,她可以根據實際情況改變內存空間的大小。若需要則臨時開闢存儲空間,不需要則釋放存儲空間,這樣可以很好地解決存儲空間浪費的問題。
鏈表是很複雜的數據結構,

10.8.1單向鏈表

單向鏈表是有若干個結點組成的,每個結點是有數據區域和指針區域兩個部分組成的。
數據區域用來存放用戶需要存儲的數據,
指針區域用來存放下一個結點的地址,便於尋找下一個結點
鏈表中一般都有一個頭結點head,用來指向鏈表的第一個結點,即整個鏈表的首地址。
鏈表中的最後一個結點中指針區域值爲空,即NULL,作爲鏈表的結束標誌。
數組的存儲空間是連續的,而鏈表是根據實際情況動態申請內存的,因此其存儲空間不是連續的。單項鍊表的示意結構

單向鏈表每一個結點中的指針區域必須存放下一個結點的地址,才能尋找到下一個結點,否則將不能尋找到下一個結點。

單向鏈表的每一個結點數據結構定義形式如下:

struct node
{
    int data;
    struct node *next;
};
定義一個結點類型node,通過該標識符可以定義變量,
整形變量
指向struct node 類型的指針next

範例10.15 通過下面的例子,簡單瞭解鏈表的概念

分析:單向鏈表的存儲是單向的,其存取必須按照順序進行。每個結點指針區域應存放下一個結點的地址,只有最後一個結點的指針區域爲空。

#include <stdio.h>

struct st
{
    char name[10];
    int n;
    float score;
    struct st *next; //結構體類型指針
};
void main()
{
    struct st s1 = { "wanghu",5324,98.5,NULL };//定義結構體變量s1並進行初始化
    struct st s2 = { "liuli",32121,78.5,NULL };
    struct st s3 = { "Hutao",45221,86.0,NULL };
    struct st s4 = { "Yuyan",21243,89.9,NULL };
    struct st *head;  //定義結構體頭指針
    head = &s1;    //使head指向結構體s1
    s1.next = &s2;  //使s1中next指針指向結構體s2
    s2.next = &s3;
    s3.next = &s4;
    s4.next = NULL; //使s4中next指針爲空
    struct st *p = NULL; //定義結構體指針指向鏈表頭結點
    while (p != NULL)//通過while循環輸出所有結點
    {
        printf("%s,%d,%.lf\n",p->name,p->n,p->score);
        p = p->next;

    }
}

定義了一個鏈表的結點類型
其中包括三種數據級一個指向結構體的指針
定義4個結點並對其初始化
定義一個頭結點,用來指向第一個結點
將第一個結點S1的地址賦給頭結點,後一個結點的地址賦給前一個結點的指針域,最後一個結點的指針賦值爲空

10.8.3 雙向鏈表

雙向鏈表包含有兩個指針。單向鏈表只有一個指針,指向下一個結點,因此要在單向鏈表中尋找一個結點,只能從開始的位置逐個往下尋找,
雙向鏈表中包含有兩個指針,分別指向前驅和後繼,因此可以從該鏈表中的任一結點出發來尋找某一結點,可以很方便地訪問一個結點的前驅和後繼

雙向鏈表的定義形式如下:

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

上述程序定義了一個雙向鏈表結點類型,其中包含三個部分,數據域data,指向結點前驅指針pre和後向結點後繼指針next。

10.17 編寫一個程序,實現雙向鏈表的輸入、輸出

#include <stdio.h>
#include <malloc.h>

typedef struct node
{
    int data;
    struct node *pre;
    struct node *next;
}lnode,*link;
void create(link *l)
{
    int i, n;
    link p, q;
    (*l) = (link)malloc(sizeof(node));
    (*l)->pre = *l;
    (*l)->next = NULL;
    q = *l;
    printf("輸入鏈表的大小: ");
    scanf("%d",&n);
    for (i = 1; i <= n; i++)
    {
        p = (link)malloc(sizeof(node));
        printf("輸入數據: ");
        scanf("%d",&p->data);
        p->next = NULL;
        p->pre = q;
        p->next = p;
        q = p;
    }
}
void prin(link l)
{
    l = l->next;
    while (l)
    {
        printf("%d ",l->data);
        l = l->next;
    }
}
void main()
{
    link L;
    create(&L);
    prin(L);
}
定義了雙向鏈表結點類型名node和類型指針link.
自定義函數create()通過該函數來創建雙向鏈表
通過while循環判斷下一個結點是否爲空來輸出鏈表中的結點。

10.8.4 鏈表中插入結點和刪除節點

10.18
修改10.17,實現鏈表中的結點的插入和刪除功能。
分析:要插入一個結點,首先應明確其要插入的位置,可通過改變相鄰位置結點指針域的值來實現結點的插入。
要刪除一個結點,也可以通過改變指針域來實現。

#include <stdio.h>
#include <malloc.h>

typedef struct node
{
    int data;
    struct node *next;
}lnode, *link;
void create(link *l)
{
    int i, n;
    link p, q;
    (*l) = (link)malloc(sizeof(node));
    (*l)->next = NULL;
    q = *l;
    printf("輸入鏈表的大小: ");
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        p = (link)malloc(sizeof(node));
        printf("輸入數據: ");
        scanf("%d", &p->data);
        p->next = NULL;
        p->next = p;
        q = p;
    }
}
void insert(link *l)
{
    int i, n, e;
    link p = *l, s;
    printf("輸入要插入結點的位置: ");
    scanf("%d", &n);
    printf("輸入要插入結點的值: ");
    scanf("%d", &e);
    for (i = 1; i < n; i++)
    {
        p = p->next;
        s = (link)malloc(sizeof(node));
        s->data = e;
        s->next = p->next;
        p->next = s;
    }
}
void idelete(link *l)
{
    int i, n;
    link p = *l, s;
    printf("輸入要刪除結點的位置: ");
    scanf("%d", &n);
    for (i = 1; i < n; i++)
    {
        p = p->next;
        s = p->next;
        p = p->next;
        p->next = s->next;
    }
}

void prin(link l)
{
    l = l->next;
    while (l)
    {
        printf("%d ", l->data);
        l = l->next;
    }
    printf("\n");
}
void main()
{
    link L;
    create(&L);
    prin(L);
    insert(&L);
    prin(L);
}

自定義函數insert().該函數的功能將一個結點插入至鏈表的指定位置,形成一個新的鏈表。
自定義函數prin(),此函數用來刪除鏈表上特定位置上的結點,從而實現刪除結點的功能。

發佈了26 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章