C語言博客作業--結構體


C語言博客作業--結構體

一、PTA實驗作業

題目1:結構體數組按總分排序

1. 本題PTA提交列表

2. 設計思路(偽代碼或流程圖)

calc函數
傳入結構體的地址和長度
定義結構體指針,指向傳入的結構體
for p=stu to stu+n
    for i=0 to 2
        初始化sum為0
    end
end
指針返回初始位置
for p=stu to stu+n
    for i=0 to 2
        累加sum
    end
end
sort函數
定義結構體指針stu,和p2作為內循環指針,max指針存放最大sum的變量地址
定義結構體變量作為交換兩變量
for p=stu to stu+n-1
    max存p
    for p2=p+1 to stu+n-1
        如果p2指的變量里的sum大於max指的變量里的sum
            交換兩變量的數據
    end
end

3.代碼截圖

4.本題調試過程碰到問題及PTA提交列表情況說明。

前幾次提交時少復制了后面的幾個花括號,導致了幾次編譯錯誤
calc函數sum沒有初始化,導致devc++上答案錯誤
解決方法:遍歷結構體的sum,初始化為0

題目2:計算職工工資

1. 本題PTA提交列表

2. 設計思路(偽代碼或流程圖)

struct staff{
	char name[100];
	double base,flow,put,actual; 
};//name為名字,base為基本工資,flow為浮動工資,put為支出,actual為實際工資
定義n為人數,i為循環變量
輸入n
定義結構數組,長度為n
for i=0 to n-1
    輸入單個結構的內容
end
for i=0 to n-1
    計算實際工資
end
for i=0 to n-1
    輸出
end

3.代碼截圖

4.本題調試過程碰到問題及PTA提交列表情況說明。

定義結構體時基本工資,浮動工資,支出定義成了int,計算的結果卻放到了浮點型的變量里,輸出結果用的是%f,用函數寫是編譯錯誤,去掉函數就變成答案錯誤。

解決方法:改變定義的類型

題目3:通訊錄的錄入與顯示

1. 本題PTA提交列表

2. 設計思路(偽代碼或流程圖)

struct list{
	char name[100];
	char birthday[100];
	char sex;
	char tel[100];
	char mobil[100];
};//name表示名字,birthday生日,sex性別,tel電話,mobil手機
定義為存入信息數,i為循環變量,num為查找信息編號,n2查找個數
輸入n
定義結構體數組lis【n】
for i=0 to n-1
    輸入信息
end
輸入查找信息個數
for i=0 to n2-1
    輸入查找信息的編號
    如果編號在可用范圍內,輸出信息
    否則輸出沒找到
end

3.代碼截圖

4.本題調試過程碰到問題及PTA提交列表情況說明。

答案錯誤:輸出時信息的位置放錯了
解決方法:調整了信息的位置輸出
部分正確:定義電話的時后給的長度不夠
解決方法:加大了電話的數組長度

二、截圖本周題目集的PTA最后排名

三、閱讀代碼

  • 編一程序,用指針數組在主函數中輸入十個等長的字符串。用另一函數對它們排序,然后在主函數中輸出10個已排好序的字符串
#include<stdio.h> 
#include<string.h> 
void sort(char *[]); 
int main()
{   
     int i;   
    char str[10][6], *p[10];   
    printf("please input 10 string:/n");   
    for(i=0;i<10;i++)//首先將10個str的首地址賦值給10個p[i];   
        p[i]=str[i];//將第i個字符串的首地址賦予指針數組p的第i個元素;  
    for(i=0;i<10;i++)    
        scanf("%s",p[i]);//scanf輸入到&p[i]  
    sort(p);   
    printf("the output 10 string:/n");  
    for(i=0;i<10;i++)    
        printf("%s/n",p[i]);//輸出到p[i]; 
}
void sort(char *s[]) 
{   
    char *temp;  int i,j;   
    for(i=0;i<9;i++)   
        for(j=0;j<9-i;j++)     
            if(strcmp(*(s+j),*(s+j+1))>0)    {      
                temp=*(s+j);//*(s+j)指向數組指針,我想應該是字符串的首地址;所以可以直接賦值給temp指針;     
                *(s+j)=*(s+j+1);     
                *(s+j+1)=temp;    
            } 
}

這道題指針的做法很有借鑒價值,將第i個字符串的首地址賦予指針數組p的第i個元素,后續就不用再拿二維數組的地址來用,簡化程序,提高可讀性。

  • 有n個結構體變量,內含學生學號、姓名和3門課程的成績。要求輸出平均成績最高的學生的信息(包括學號、姓名、3門課程成績和平均成績)。
#include<stdio.h>  
#define N 3 //學生數為3  
struct student  
{  
    long num;  
    char name[20];  
    int score[3];  
    float aver;  
}stu[N];  
int main()  
{  
    void input(struct student stu[]);  
    struct student max(struct student stu[]);  
    void print(struct student stu);  
    struct student *p=stu;  
    input(p);  
    print(max(p));  
    return 0;  
}  
void input(struct student stu[])  
{  
    int i;  
    printf("請輸入%d個學生的信息(學號、姓名、三門課成績):\n",N);  
    for(i=0;i<N;i++)  
    {  
        scanf("%ld %s %d %d %d",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);  
        stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;  
    }  
}  
struct student max(struct student stu[])  
{  
    int i,m=0;  
    for(i=1;i<N;i++)  
        if(stu[i].aver>stu[m].aver) m=i;  
    return stu[m];  
}  
void print(struct student stu)  
{  
    printf("\n成績最高的學生是:\n");  
    printf("學號:%ld\n姓名:%s\n三門課成績:%d %d %d\n平均成績:%5.2f\n\n",  
                          stu.num,stu.name,stu.score[0],stu.score[1],stu.score[2],stu.aver);  
}  

這道題使用了結構體,但是我覺得更好的地方是用函數來分裝代碼,整個結構很好,值得借鑒。

四、本周學習總結

1.總結本周學習內容。

結構體、共用體、枚舉這種構造數據類型特點。

結構體
struct 結構體名
{
成員表列
} 變量表列;
例:
struct data{
    int a;
    char b;
    double c;
} s1;

結構體變量就像數組一樣,但是不同於數組的是,他內部的元素可以不同,而且結構體內部還可以嵌套,這對於數據的分類管理就起到很大作用。

共用體
union 共用體名
{
成員表列
} 變量表列;
列:
union data
{
    int i;
    char ch;
    float f;
} a, b, c;

1.同一個內存段可以用來存放幾種不同類型的成員,但是在每一瞬間只能存放其中的一種,而不是同時存放幾種。
2.共用體變量中起作用的成員是最后一次存放的成員,在存入一個新成員后,原有成員就失去作用。
3.共用體變量的地址和它的各成員的地址都是同一地址。
4.不能對共用體變量名賦值,也不能企圖引用變量名來得到一個值。
5.共用體類型可以出現在結構體類型的定義中,也可以定義共用體數組。反之,結構體也可以出現在共用體類型的定義中,數組也可以作為共用體的成員。
6.共用體變量的初始化。
(1)union data a=b; //把共用體變量初始化為另一個共用體
(2)union data a={123}; //初始化共用體為第一個成員
(3)union data a={.ch='a'}; //指定初始化項目,按照C99標准
7.共用體變量也可以作為函數的參數和返回值。

共用體的使用大大降低編程時內存的占用,但是使用時也要格外小心,不同於結構體數據所占內存不同,共同體占的內存相同,取值只取最后存放的數,所以使用時要注意。
此外結構體與共用體的定義方式差不多,可以結合起來記憶。

枚舉

enum 枚舉名{
標識符[=整型常數],
標識符[=整型常數],
...
標識符[=整型常數]
} 枚舉變量;
例:
enum weekday{sun,mon,tue,wed,thu,fri,sat};

如果枚舉沒有初始化,即省掉"=整型常數"時, 則從第一個標識符開始,順次賦給標識符0, 1, 2, ...。但當枚舉中的某個成員賦值后,其后的成員按依次加1的規則確定其值。
例如下列枚舉說明后,x1, x2, x3, x4的值分別為0, 1, 2, 3。enum Num{x1, x2, x3, x4}x;
當定義改變成

enum Num
{
    x1,
    x2=0,
    x3=50,
    x4
}x;
則x1=0, x2=0, x3=50, x4=51
  1. 枚舉中每個成員(標識符)結束符是"," 不是";", 最后一個成員可省略","。

  2. 初始化時可以賦負數, 以后的標識符仍依次加1。

  3. 枚舉變量只能取枚舉說明結構中的某個標識符常量。

  4. 枚舉值是常量,不是變量。不能在程序中用賦值語句再對它賦值。例如對枚舉weekday的元素再作以下賦值: sun=5;mon=2;sun=mon; 都是錯誤的。

  5. 枚舉元素本身由系統定義了一個表示序號的數值,從0 開始順序定義為0,1,2…。如在weekday中,sun值為0,mon值為1, …,sat值為6。

  6. 只能把枚舉值賦予枚舉變量,不能把元素的數值直接賦予枚舉變量。如: a=sun;b=mon; 是正確的。而: a=0;b=1; 是錯誤的。如一定要把數值賦予枚舉變量,則必須用強制類型轉換,如: a=(enum weekday)2;其意義是將順序號為2的枚舉元素賦予枚舉變量a,相當於: a=tue; 還應該說明的是枚舉元素不是字符常量也不是字符串常量, 使用時不要加單、雙引號。

相比於結構體或共同體,枚舉的定義方法有點類似,但有很大區別,如2所提到,以及系統定義數值要非常注意;枚舉的使用方便了常量的使用,使代碼可讀性大大提高。

遞歸函數原理:

遞歸(recursion)就是子程序(或函數)直接調用自己或通過一系列調用語句間接調用自己,是一種描述問題和解決問題的基本方法。

遞歸通常用來解決結構自相似的問題。所謂結構自相似,是指構成原問題的子問題與原問題在結構上相似,可以用類似的方法解決。具體地,整個問題的解決,可以分為兩部分:第一部分是一些特殊情況,有>直接的解法;第二部分與原問題相似,但比原問題的規模小。實際上,遞歸是把一個不能或不好解決的大問題轉化為一個或幾個小問題,再把這些小問題進一步分解成更小的問題,直至每個小問題都可以直接
解決。因此,遞歸有兩個基本要素:
(1)邊界條件:確定遞歸到何時終止,也稱為遞歸出口。
(2)遞歸模式:大問題是如何分解為小問題的,也稱為遞歸體。遞歸函數只有具備了這兩個要素,才能在有限次計算后得出結果

在遞歸函數中,調用函數和被調用函數是同一個函數,需要注意的是遞歸函數的調用層次,如果把調用遞歸函數的主函數稱為第0層,進入函數后,首次遞歸調用自身稱為第1層調用;從第i層遞歸調用自身稱>為第i+1層。反之,退出第i+1層調用應該返回第i層。

遞歸函數的內部執行過程:

一個遞歸函數的調用過程類似於多個函數的嵌套的調用,只不過調用函數和被調用函數是同一個函數。為了保證遞歸函數的正確執行,系統需設立一個工作棧。具體地說,遞歸調用的內部執行過程如下:
(1)運動開始時,首先為遞歸調用建立一個工作棧,其結構包括值參、局部變量和返回地址;
(2)每次執行遞歸調用之前,把遞歸函數的值參和局部變量的當前值以及調用后的返回地址壓棧;
(3)每次遞歸調用結束后,將棧頂元素出棧,使相應的值參和局部變量恢復為調用前的值,然后轉向返回地址指定的位置繼續執行。

總之,遞歸函數就是將一個復雜的問題分解成幾個相似的小問題,調用函數來解決問題。只需考慮問題的分解,及分解到邊界時如何解決即可,其他部分交給計算機來解決。

2.羅列本周一些錯題。

對於以下結構定義,(*p)->str++中的++加在()。 (2分)
struct { int len; char\ *str; } *p;
A、
指針str上
B、
指針p上
C、
str指向的內容上
D、
語法錯誤
答案:d 錯選:c
分析:*p已經是內容,不能->,如果是p->str++,則++加在指針str上
線性表用順序實現。請填空寫一個求線性表L 中所有奇數之和的算法。
例如:
L=(1,2,3,4,5) 其和為 9(本題結構體定義很不錯。)

#include <stdio.h>
#define N 10
typedef struct sqlist
 {
   int data[N];
   int last;
   }LIST;

 int Total(List list)
 {

     return sum;  
 }
 void Show(LIST list)
 {
   int i;
   for(i=0;i<=list.last;i++)
      printf("%3d", list.data[i]);
   printf("\n");
 }
int main()
 {
    LIST list;
    int i,sum;
    for(i=0;i<=5;i++)
     list.data[i]=i;
    list.last=5;
    Show(list);
    sum=Total(list);
    printf("sum=%3d\n",sum);
    return 0;
}
參考答案
int sum=0;
for(int i=0;i<=list.last;i++)
   if(list.data[i]%2)
      sum+=list.data[i];
我的作答


int sum=0,i;
for(i=0;i<list.last;i+=2){
    sum+=list.data[i];
}

分析,沒看清楚題目,題目要的是奇數的和,不是下標


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM