1. 程式人生 > >2018計算機專案部第二次培訓

2018計算機專案部第二次培訓

計算機專案部第二次培訓總結

文章目錄


此次部門培訓是c語言的最後一講,所以講的內容會顯得比複雜,所以下課之後一定要再經過自己的練習。首先先介紹了c語言中結構體這種特殊的聚合資料型別,然後給大家簡單介紹了一下連結串列的定義和概念,並講解了插入和刪除的具體程式碼。最後給大家科普了一下工程檔案的具體種類。臨近下課的時候給大家做了幾道簡單的陣列迭代題進行了一下練習。

1. 結構體

結構體本身是一種特殊的資料結構,和我們之前接觸的int,char型別都有一些不同。在C語言中,結構體(struct)指的是一種資料結構,是C語言中聚合資料型別

(aggregate data type)的一類。結構體可以被宣告為變數、指標或陣列等,用以實現較複雜的資料結構。結構體同時也是一些元素的集合,這些元素稱為結構體的成員(member),且這些成員可以為不同的型別,成員一般用名字訪問。以下是三種不同的定義方式。

#include <stdio.h>
#include <stdlib.h>
main()
{
    //1.先定義結構,再說明結構變數
    struct stu
    {
        int num;
        char name[20];
        int age;
    };
    struct
stu boy1,boy2; // 例如: struct stu { int num; char name[20]; int age; }; STU boy1,boy2; // 2.在定義結構型別的同時說明結構變數。 typedef struct stu { int num; char name[20]; int age; } boy1,boy2; //3.直接說明結構變數 struct { int num;
char name[20]; int age; } boy1,boy2; }

接下來介紹的是結構體的巢狀,結構體中可以放置int, char型別的資料,自然也能房子結構體型別的資料。首先定義一個date,由month(月),day(日),year(年)三個成員組成。在定義並說明變數boy1和boy2時,其中的成員birthday被說明為date結構型別。成員名可以與其他的變數同名,互不干擾。就像圖片中顯示的一樣:
在stu結構體中嵌套了birthday結構體


#include <stdio.h>
#include <stdlib.h>
main()
{
    Struct date
    {
        Int month;
        Int day;
        Int year;
    };
    Struct
    {
        Int num;
        Char name[20];
        Char sex;
        Struct date birthday;
        Float score;
    } boy1,boy2;
}

最後講解了結構體的賦值,這裡給大家介紹的是兩種最常見的結構體的賦值方式,即結構變數的賦值就是給各個成員賦值,可以用輸入語句或者賦值語句來完成。結構變數成員的一般形式:結構變數名.成員名 例如:boy1.num= 即第一個人的學號。如果成員變數本身就是一個結構,那麼需要逐級找到最低階的成員才能使用。例如:boy1.birthday.month 即第一個人出生的月份。

這裡我使用了一個小練習來作為示範,設計兩個個名字叫做boy1和boy2的結構體,其中包含name,sex,num,score四個變數,嘗試使用輸入和賦值語句對boy1的四個變數賦值,並使得boy2等於boy1的基礎上進行對name新的賦值,最後輸出boy1和boy2的所有成員變數

//結構體賦值練習:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    struct stu
    {
        int num;
        char name[20] ="jsjxmb";
        char sex[100]="may be a girl";
        float score;
    } boy1,boy2;

    boy1.num = 102;
    printf("boy1: num\tname\t\tsex\tscore\n");
    printf("     num=%d\tname=%s\tsex=%s\tscore=%f\n",boy1.num,boy1.name,boy1.sex,boy1.score);
    printf("please input sex and score:\n");
    scanf("%s %f",boy1.sex,&boy1.score);

    boy2 = boy1;
    printf("num\tname\t\tsex\tscore\n");
    printf("num=%d\tname=%s\tsex=%s\tscore=%f\n",boy2.num,boy2.name,boy2.sex,boy2.score);
    return 0;
}

到此結構體的內容就結束了

2. 連結串列

連結串列是c語言課程中的一個難點,尤其是當小部員們還沒能熟練掌握指標的時候,所以我在培訓的時候儘量多的舉了例子來幫助小部員們進行理解。首先先是連結串列的概念和我們為什麼要使用它。連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成。每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。它雖較於線性儲存結構操作起來稍顯複雜,但在插入和離散的儲存結構中會更加方便操作。首先我簡單介紹了連結串列作為一個結構體該如何定義

typedef struct _londe
{
  int data;
  struct _londe *next;
}Londe;

data部分的資料型別並不固定,放的是需要儲存的資料,而定義的結構體指標*next是指向下一個節點的地址,通過這個指標把不同的結構體連線起來形成了連結串列。

接下來我為部員們介紹的主要是連結串列的增刪改查的基本操作,應為大多數人是第一次接觸這方面的知識,所以培訓的時候主要以講解原理為主

  1. 連結串列的插入
    在這裡插入圖片描述
//查詢連結串列
Londe *insert(Londe *head,int i)
{
    Londe *s,*q,*first;
    first=head;
    s=(Londe *)malloc(sizeof(Londe));
    s->next=0;
    s->data=i;
    while(head!=NULL)
    {
        if(head->data>=i)
        {
            q=head;
        }
        head=head->next;
    }
    head=first;
    while (head->next!=q)
    {
        head=head->next;
    }
    head->next=s;
    s->next=q;
    head=first;
    while(first!=0)
    {
        printf("%d ",first->data);
        first=first->next;
    }
    return head;
}

  1. 連結串列的刪除
    在這裡插入圖片描述
//刪除連結串列
Londe *_delete(Londe *head,int m)
{
    Londe *s,*q,*first;
    first=head;
    s=(Londe *)malloc(sizeof(Londe));
    s->next=0;
    s->data=m;
    while(head!=NULL)
    {
        if(head->data==m)
        {
            q=head;
            break;
        }
        head=head->next;
    }
    head=first;
    if(q==first)
    {
        first=first->next;
    }
    else
    {
        while(head->next!=q)
        {
            head=head->next;
        }
        head->next=q->next;
    }
    head=first;
    while(first!=0)
    {
        printf("%d ",first->data);
        first=first->next;
    }
    return head;
}

連結串列的插入和刪除的原理基本一致,其核心目的都是找到目標的前一個節點和後一個節點的位置,這其中就用到了查方面的知識。在確定好位置之後要通過對next指標的值的改變來實現對原本佇列順序的改變,其難點在於對結構體指標的理解和運用。

3. IO流

考慮到小部員們對檔案和對其的管理方面的知識和運用的缺乏,所以在培訓的時候是以科普為主,首先是告訴了大家如何找到自己的工程目錄,在codeblocks裡點選紅圈所在的位置就能檢視到自己的工程路徑
在這裡插入圖片描述
其次給部員們介紹了開啟關閉檔案的基本程式碼和原理,併為他們分析了不同的檔案讀取和寫入的方式
在這裡插入圖片描述
然後重點為他們分析了絕對路徑和相對路徑之間的區別,並通過程式碼對他們進行了展示,最後在IO流方面以一道小練習題收尾:嘗試在工程下面建立一個test.txt檔案,然後往裡面寫入“jsjxmb”這行字元,並再次讀取出來

//檔案讀取
#include <stdio.h>
#include <stdlib.h>
main()
{
    FILE *fp;
    char s[80];
    fp=fopen("test1.txt","rt");
    if (fp==NULL)
    {
        printf("Can not open this file\n");
        exit(0);
    }
    fgets(s,80,fp);
    puts(s);
    fclose(fp);
}

//檔案寫入
main()
{
    FILE *fp;
    char s[80];
    fp=fopen("test1.txt","wt");
    if (fp==NULL)
    {
        printf("Can not open this file\n");
        exit(0);
    }
    gets(s);
    fputs(s,fp);
    fclose(fp);
}

4. 陣列與迭代小練習

在課上的最後二十分鐘,我給大家佈置了兩道書上的練習題,一道是輸入兩個陣列,要求輸出它們的交集,另外一道是一個簡單的約瑟夫環問題。第一道題的核心思想在於節省算力,最好的解決思想在於讓兩個陣列同時移動,即同時取出陣列中的數進行比較,程式碼解釋如下:

//求交集
#include<stdio.h>
int jiaoji(int a[],int b[],int c[],int m,int n)
{
    int k,i=0,p=0,q=0;
    while (p<m&&q<n)
    {
        if(a[p]==b[q])
        {
            c[i]=a[p];
            p++;
            i++;
            q++;
        }

        else if(a[p]<b[q])
        {
            p++;
        }
        else
        {
            q++;
        }
    }
    return i;
}

int main()
{
    int m=7,n=6;
    int i,h,a[100],b[100],c[100];
    printf("給a賦值:");
    for (i=0; i<m; i++)
    {
        scanf("%d",&a[i]);
    }
    printf("\n");
    printf("給b賦值:");
    for (i=0; i<n; i++)
    {
        scanf("%d",&b[i]);
    }
    i=jiaoji(a,b,c,m,n);
    for (h=0; h<i; h++)
    {
        printf(" %d ",c[h]);
    }
}

約瑟夫環是一道經典的陣列迭代問題,其核心思想在於當迴圈完一遍之後如何保證計算的自殺人數不發生改變而又從環的開頭開始從新計算,而課本上已有對這部分內容的詳細解釋和程式碼,大家可以在課餘時間內嘗試用while迴圈來完成這段迭代。