12天学好C语言——记录我的C语言学习之路(Day 12)
生活随笔
收集整理的這篇文章主要介紹了
12天学好C语言——记录我的C语言学习之路(Day 12)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
12天學好C語言——記錄我的C語言學習之路
Day 12:
進入最后一天的學習,用這樣一個程序來綜合考量指針和字符串的關系,寫完這個程序,你對字符串和指針的理解應該就不錯了。
//輸入一個字符串,內有數字和非數字字符,如:A123x456 17234?532tab32622,然后將,123,456,17234,532,32622這些被非數字字符分割開的數字找出來,輸出這些數。
//此程序的關鍵點在于遇到需要輸出的字符就記錄下來,然后判斷他的下一個字符是不是有效字符,有效則不做判定繼續(xù)執(zhí)行有效字符的記錄工作,如果遇到無效字符,那么這時候就要輸出 從記錄的第一個字符開始到這個無效字符的前一個字符 之間的所有字符。我們記錄的正是這一段有效字符的個數(用k記錄),也正是這段字符的首、尾地址的差,然后用指針變量指向首地址,依次輸出地址里面的值。
//當然,我輸出的形式還是char,如果題目要求讀者將分割開來的數用int型輸出,那么不妨將每一個字符都做一個這樣的處理,比方說第一個分割出來的數是123,這時的123是字符'1'字符'2'和字符'3',另外我們知道這時的 k=3 ,我們可以用
//?? ('1'-'0')*pow(10,k-1)+('2'-'0')*pow(10,k-2)+('3'-'0')*pow(10,k-3) 來表示,這里的重點在于字符型數字如何轉化成整型的數字,用到的是 這個數字字符 和 數字字符'0' 之間的距離正好就是 這個數字字符 的 值。另外,這里的k-1,k-2,k-3可以用k-i來表示,i的范圍是1~k
/*//program 12.1
#include<stdio.h>
#include<string.h>
int main()
{
??? char a[]="A123x456 17234?532tab32622";
??? void search(char *);
??? search(a);
??? return 0;
}
void search(char *a)
{
??? char *p1=a;
??? long length=strlen(a);
??? int i=0,k=0,sum=0;
??? for (;i<length; i++) {
??????? p1=a+i;
??????? if (*p1>48&&*p1<57) {
??????????? k++;
??????????? if (*(p1+1)<48||*(p1+1)>57) {
??????????????? for (int j=0; j<k; j++) {//這個和下面的程序就略有不同了,這里每次分割完一個數字,就將k初始化為0,而且每次用到j的時候也都是從0開始使用的。所以結果也是正確的
??????????????????? printf("%c",*(p1-k+1+j));
??????????????? }
??????????????? k=0;
??????????????? printf(" ");
??????????????? sum++;
??????????? }
??????? }
??? }
??? printf("\n共有%d個數字被分割",sum);
}
*/
如果你上面的程序會了,那么你試著做一做下面這個題。
//55234152349555098958788955584? 分割這樣一串數字,要求是用5分割,如將左邊的一串數字分割成
//55 2341 5 2349 555 0989 5 87889 555 84? 然后最后得到的結果為2341 2349 0989 87889 84
/*//program 12.2
#include <stdio.h>
#include <string.h>
int main()
{
??? char a[]="55234152349555098958788955584";
??? void search(char *);
??? search(a);
??? return 0;
}
void search(char *p){
??? long length=strlen(p);
??? int i=0,k=0,j=0,sum=0;
??? for (; i<length; i++) {
??????? if (*(p+i)!='5') {
??????????? k++;
??????????? if (*(p+i+1)=='5'||*(p+i+1)=='\0') {//這里必須加上空值,因為上面不是5結尾的
??????????????? for (; j<k; j++) {
??????????????????? printf("%c",*(p+i-k+1+j));//這個地方是一個比較逗B的巧合,因為我們在輸出第一個分割出來的數字時,k和j都沒有歸0,那么如上面的一串數字,在輸出第二個數字的時候,k是從5開始的(因為第一個分割出來的數字有4位,也就是k=4),那么等第二個數字遍歷完畢時,k應該變成了8(同理,第二個分割出來的數字也是有4位的)。再看j,第一次分割結束的時候跳出for循環(huán)的時候j做了一次j++,那么j的值就和k當時的值是一樣的,所以j在進入第二個分割數的for循環(huán)的時候j應該是4,而不是0,那么第二次分割出來的數字的首字符應該是*(p+10-8+1+4),也就是*(p+7),正好就是數字2349中2的地址。這個地方可以說是誤打誤撞,讀者可能在看這個地方的時候看不懂是怎么得到的正確結果。
??????????????? }
??????????????? sum++;
??????????????? printf(" ");
??????????? }
??????? }
??? }
??? printf("\n共有%d個數字被分割",sum);
}
*/
好了指針部分也差不多結束了,敲了不少程序,希望大家能夠準確理解指針~
接下來轉入結構體,也是最后一個環(huán)節(jié)的學習。
//結構體類型事實上和int,char,float類型都大同小異,只不過結構體類型是我們自己定義的類型。結構體類型和結構體變量不是一回事,我們知道只能對變量賦值,存取或者運算,而不能對類型如此,類型是不需要分配空間的,只能對變量分配空間。
//定義結構體類型的格式:????? struct 結構體名{ 成員表列 };???? 注意在聲明結構體類型的時候要最后加上分號。
//當然在聲明結構體類型的同時可以定義變量:????? struct 結構體名{ 成員表列 } 變量名表列;
//另外要注意的是結構體類型中的成員名和程序中的變量名如果相同,但二者不代表同一對象的,是兩回事,互不干擾
//定義Student結構體類型,然后將一個同學信息(學號,姓名,性別,住址)放在一個結構體變量中,然后輸出該學生的成績。
/*//program 12.3
#include "stdio.h"
int main()
{
??? struct Student
??? {
??????? int number;
??????? char name[20];
??????? char sex[20];//注意,如果在結構體類型中有成員是字符串形式的,那么這里要將成員定義成字符數組的形式
??????? char addr[30];
??? };
??? struct Student a={123456,"wangzhongyao","man","shandongshengjinanshi"};//這里是先聲明結構體類型,然后再定義結構體變量a,分開進行。下面給出在結構體類型聲明的同時定義變量的情況。
??? printf("No.%d\nname:%s\nsex:%s\naddress:%s\n",a.number,a.name,a.sex,a.addr);//這里輸出的并不是a,而是a的各個屬性,我們輸出的是a的詳細信息,所以要用? a.變量名? 來輸出。這里很重要。
??? return 0;
}
*/
//還是上面的程序,在結構體類型聲明的同時定義結構體變量。
/*//program 12.4
#include<stdio.h>
int main()
{
??? struct Student
??? {
??????? int number;
??????? char name[20];
??????? char sex[10];
??????? char addr[30];
??? }
??? a={123,"maxingze","man","jiningshilaozhaizhen"},b={1234,"yuetianhao","man","jiningshijiaxiangxian"};
??? //這里注意,在結構體類型聲明的同時定義結構體變量的話,要把結構體變量定義在結構體類型聲明時最后一個分號的前面!!!!!這里一定要注意哦!!!
??? printf("No.%d\nname:%s\nsex:%s\naddr:%s\n\n",a.number,a.name,a.sex,a.addr);
??? printf("No.%d\nname:%s\nsex:%s\naddr:%s\n\n",b.number,b.name,b.sex,b.addr);
??? return 0;
}
*/
/*//program 12.5
?//對結構體類型中某一成員進行初始化(不完全初始化成員),其余未被初始化的成員是什么情況?下面給出解答。
#include<stdio.h>
int main()
{
??? struct Student
??? {
??????? int card;
??????? char name[10];
??????? char sex[10];
??????? char bumen[20];
??? }
??? a={.name="man"};//允許對結構體中的某一成員初始化,其他 未被初始化的 數值型成員 被初始化為0,未被初始化的 字符型成員 被初始化為'\0',未被初始化的 指針型成員 被初始化為NULL。這里必須要牢記!!!!!!!
??? printf("Card:%d\nname:%s\nsex:%s\nbumen:%s\n",a.card,a.name,a.sex,a.bumen);
??? return 0;
}
*/
/*//program 12.6
//結構體變量之間可以互相賦值
#include <stdio.h>
int main()
{
??? struct Student
??? {
??????? int card;
??????? char name[10];
??????? char sex[10];
??? }
??? a={123,"a","man"},b={321,"b","woman"};//在結構體類型聲明的時候定義變量,要注意定義多個變量的時候中間用','隔開,在最后的一個變量定義結束時加一個';'即可,當然最后加很多';'也沒有錯誤(驗證得到)。
??? a=b;//同類型結構體變量之間可以相互賦值(如:?? a=b;),同樣同類型結構體變量中相同成員也可以互相賦值(如:?? a.card=b.card;)
??? printf("card:%d\nname:%s\nsex:%s\n",a.card,a.name,a.sex);
??? return 0;
}
*/
//注意不能用以下語句整體讀入結構體變量
//scanf("%d,%s,%s\n",&a);?? 因為結構體變量的地址主要用作函數參數,傳遞結構體變量的地址。(這句話需要讀者好好理解!!!)
//那應該怎么讀入結構體變量呢? 顯然要將結構體變量中每一個成員 分別 讀入,如下:
//scanf("%d,%s,%s\n",&a.card,&a.name,&a.sex);
//輸入兩個學生的學號、姓名和成績,輸出成績較高的學生的學號、姓名和成績
//下面的題目中沒有寫兩個學生成績相等的情況,讀者可以自行加上
/*//program 12.7
#include "stdio.h"
int main()
{
??? struct Student
??? {
??????? int number;
??????? char name[20];
??????? int grade;//成績是一個整數,這里不要錯誤的聲明為數組類型
??? }
??? a,b;
??? printf("請輸入兩個學生的學號、姓名、成績:\nNo.1:\n");
??? scanf("%d%s%d",&a.number,a.name,&a.grade);
??? //scanf(格式控制,地址表列);? 這里的地址表列可以是變量的地址,也可以是字符串的首地址。(這句話很重要,在上面一句輸入語句中,只有a.name沒有加'&'號,這是因為name為數組名,代表了字符串數組的首地址,所以說a.name就是一個地址,所以不用再加'&'了)
??? printf("No.2:\n");
??? scanf("%d%s%d",&b.number,b.name,&b.grade);
??? if (a.grade>b.grade) {
??????? printf("number:%d\nname:%s\ngrade:%d\n",a.number,a.name,a.grade);
??? }
??? else
??? {
??????? printf("number:%d\nname:%s\ngrade:%d\n",b.number,b.name,b.grade);
??? }
??? return 0;
}
*/
/*//program 12.8
//有3個候選人,編一個統計選票的程序,先后輸入備選人的名字,然后輸出個人選票結果
#include <stdio.h>
struct Person
{
??? char name[20];
??? int count;
}lead[3]={"ma",0,"wang",0,"zheng",0};
int main()
{
??? char lead_name[20];//聲明一個字符數組,用來存放下面10次投票時 每一次 投票的人選姓名
??? printf("請投票10次:\n");
??? for (int i=0; i<10; i++) {
??????? scanf("%s",lead_name);//這里的lead_name就是數組名,表示的就是這個字符串的首地址。i=10,所以這里要輸入10個字符串,分10次輸入,下面調用strcmp函數就是將 每一次 投票的任選姓名和候選名單中的三個姓名比較,如果一樣,那么結構體變量中的count成員就+1 。
??????? for (int j=0; j<3; j++) {
??????????? if (strcmp(lead_name,lead[j].name)==0)//這里為什么能用lead_name呢?這個不是地址么,這里應該是比較兩個字符串的值把? 記住就好了,字符數組,用數組名來比較即可
??????????? {
??????????????? lead[j].count++;
??????????? }
??????? }
??? }
??? for (int i=0; i<3; i++) {
??????? printf("%s:%d\n",lead[i].name,lead[i].count);
??? }
??? return 0;
}
*/
//定義結構體數組的一般形式是
// struct 結構體名 { 成員表列 } 數組名[數組長度] ;
//或者是先聲明一個結構體類型,然后再定義結構體數組,在已經聲明好結構體類型的情況下我們可以這樣定義:
//結構體類型 數組名[數組長度]={初值表列};? (如:? struct Person a[3]={"ma",0,"wang",0,"zheng",0};? )
//有n個學生的信息(學號、姓名、成績),要求按照成績的高低順序輸出各學生的信息
/*//program 12.9
#include "stdio.h"
struct Student
{
??? int number;
??? char name[20];
??? int grade;
};
void change(struct Student *a,int n)
{
??? struct Student temp;//這里的temp和上面數組中的成員是一樣的類型,用來在下面排序時作交換的。
??? int i,j,k;
??? for (i=0; i<n-1; i++) {
??????? k=i;
??????? for (j=i+1; j<n; j++) {
??????????? if (a[k].grade<a[j].grade) {
??????????????? k=j;
??????????? }
??????? }
??????? temp=a[k];
??????? a[k]=a[i];
??????? a[i]=temp;
??? }
??? for (i=0; i<n; i++) {
??????? printf("number:%d name:%s grade:%d\n",a[i].number,a[i].name,a[i].grade);
??? }
}
int main()
{
??? struct Student ss[]={1001,"wang",98,1002,"ma",99,1003,"zheng",87,1004,"yue",89,1005,"zhang",100};
??? void change(struct Student *a,int n);
??? change(ss,5);
??? return 0;
}
*/
//結構體指針。通過 指向 結構體變量 的指針 來訪問 結構體變量 中的 成員。
//首先我們要知道,這個結構體指針是指向結構體變量的,然后再通過指針去訪問結構體變量的成員。
//結構體指針其實和普通指針差不多,就是指向的結構體變量,而且多了一種形式(p->number)。
/*//program 12.10
#include "stdio.h"
#include "string.h"
struct Student
{
??? int number;
??? char name[30];
??? char sex[10];
??? int grade;
};
int main()
{
??? struct Student a;
??? a.number=1001;
??? strcpy(a.name,"Xingze Ma");//這里需要注意一下,如果不是直接對整個結構體變量初始化,而是對其中一個一個成員分別初始化,那么在初始化字符數組成員的時候(也就是需要初始化一個字符串),需要用到strcpy函數,這個函數是復制字符串的。對于字符串的賦值,不能說char a[10];? a=“123”; 這樣錯誤。 對于字符串賦值,要么在聲明的初始化(char a[10]=“123”;),要么用scanf函數給字符串輸入值,要么就要用strcpy函數復制字符串,而也是本題中用的方法,也最為常用
??? strcpy(a.sex,"gay");
??? a.grade=59;
??? struct Student *p;
??? p=&a;
??? printf("number:%d\nname:%s\nsex:%s\ngrade:%d\n\n",(*p).number,(*p).name,(*p).sex,(*p).grade);
??? //'.'運算符優(yōu)先于'*'運算符,所以這里必須加括號(*p)
??? printf("number:%d\nname:%s\nsex:%s\ngrade:%d\n",p->number,p->name,p->sex,p->grade);
??? //為了方便,允許把 (*p).number 用 p->number 來代替,含義是p所指向的 結構體變量 中的 number成員
??? //所以以下3種情況是等價的
??? //struct Student a;??? struct Student *p=&a;
??? //①a.number ②(*p).number ③p->number
??? return 0;
}
*/
//指向結構體數組的指針
//和指向一般數組的指針也別無二致,就是指向結構體數組的首地址即可
/*//program 12.11
#include "stdio.h"
struct Student
{
??? int card;
??? char name[20];
??? char sex[20];
}
a[]={{1001,"wang","man"},{1002,"ma","woman"},{1003,"zheng","gay"}};
int main()
{
??? struct Student *p=a;
??? for (; p<a+3; p++) {//這里無論是什么情況下在for循環(huán)中用指針,這是p<a+3,而不是p<p+3 , 牢記!!!!
??????? printf("card:%d\nname:%s\nsex:%s\n\n",p->card,(*p).name,p->sex);
??? }
??? return 0;
}
*/
//用 結構體變量 和 結構體變量的指針 作函數參數
//有n個結構體變量,內含學生學號、姓名和3門課程的成績。要求輸出平均成績最高的學生的信息。
/*//program 12.12
#include "stdio.h"
#define N 3
struct Student
{
??? int num;
??? char name[20];
??? float score[3];
??? float aver;
};
void scanf1(struct Student ss[])
{
??? printf("請輸入各學生信息:\n");
??? for (int i=0; i<N; i++) {
??????? scanf("%d%s%f%f%f",&ss[i].num,&ss[i].name,&ss[i].score[0],&ss[i].score[1],&ss[i].score[2]);
??????? ss[i].aver=(ss[i].score[0]+ss[i].score[1]+ss[i].score[2])/3;
??? }
}
struct Student max(struct Student ss[])
{
??? float max=ss[0].aver;
??? int k=0;
??? for(int i=1;i<N;i++)
??? {
??????? if(max<ss[i].aver)
??????? {
??????????? max=ss[i].aver;
??????????? k=i;
??????? }
??? }
??? return ss[k];
}
void print(struct Student s)
{
??? printf("成績最好的學生是:\n%d %s %5.2f %5.2f %5.2f",s.num,s.name,s.score[0],s.score[1],s.score[2]);
}
int main()
{
??? void scanf1(struct Student ss[]);//這里要傳入結構體數組中數組元素,因為我們比較好幾個學生的平均成績,自然要準備一個數組存放它們
??? struct Student max(struct Student ss[]);
??? void print(struct Student s);
??? struct Student s[N];
??? scanf1(s);//這里傳進去的是數組s[N]的首地址,所以這里我們也可以用指針操作,可以定義一個結構體指針指向s[N],然后調用函數的時候用p來調用,其作用是一樣的
??? print(max(s));
??? //struct Student q;
??? //q=max(p);
??? //print(q);
??? return 0;
}
*/
program 12.12 將我們學過的知識基本上匯合了一下,我們的學習也就到此結束了,短短12天,學到的東西很多,我只把C語言部分介紹到結構體,剩下還有一些結構體和鏈表、共用體類型、文件讀寫等等部分我就不一一介紹了。時間有限,由讀者自行學習。希望讀者能學習到一些知識,那么我寫的這幾篇連載博客也就有價值了。希望大家學習愉快!
?? ??? ??? ??? ??? ??? ??? ????
Day 12:
進入最后一天的學習,用這樣一個程序來綜合考量指針和字符串的關系,寫完這個程序,你對字符串和指針的理解應該就不錯了。
//輸入一個字符串,內有數字和非數字字符,如:A123x456 17234?532tab32622,然后將,123,456,17234,532,32622這些被非數字字符分割開的數字找出來,輸出這些數。
//此程序的關鍵點在于遇到需要輸出的字符就記錄下來,然后判斷他的下一個字符是不是有效字符,有效則不做判定繼續(xù)執(zhí)行有效字符的記錄工作,如果遇到無效字符,那么這時候就要輸出 從記錄的第一個字符開始到這個無效字符的前一個字符 之間的所有字符。我們記錄的正是這一段有效字符的個數(用k記錄),也正是這段字符的首、尾地址的差,然后用指針變量指向首地址,依次輸出地址里面的值。
//當然,我輸出的形式還是char,如果題目要求讀者將分割開來的數用int型輸出,那么不妨將每一個字符都做一個這樣的處理,比方說第一個分割出來的數是123,這時的123是字符'1'字符'2'和字符'3',另外我們知道這時的 k=3 ,我們可以用
//?? ('1'-'0')*pow(10,k-1)+('2'-'0')*pow(10,k-2)+('3'-'0')*pow(10,k-3) 來表示,這里的重點在于字符型數字如何轉化成整型的數字,用到的是 這個數字字符 和 數字字符'0' 之間的距離正好就是 這個數字字符 的 值。另外,這里的k-1,k-2,k-3可以用k-i來表示,i的范圍是1~k
/*//program 12.1
#include<stdio.h>
#include<string.h>
int main()
{
??? char a[]="A123x456 17234?532tab32622";
??? void search(char *);
??? search(a);
??? return 0;
}
void search(char *a)
{
??? char *p1=a;
??? long length=strlen(a);
??? int i=0,k=0,sum=0;
??? for (;i<length; i++) {
??????? p1=a+i;
??????? if (*p1>48&&*p1<57) {
??????????? k++;
??????????? if (*(p1+1)<48||*(p1+1)>57) {
??????????????? for (int j=0; j<k; j++) {//這個和下面的程序就略有不同了,這里每次分割完一個數字,就將k初始化為0,而且每次用到j的時候也都是從0開始使用的。所以結果也是正確的
??????????????????? printf("%c",*(p1-k+1+j));
??????????????? }
??????????????? k=0;
??????????????? printf(" ");
??????????????? sum++;
??????????? }
??????? }
??? }
??? printf("\n共有%d個數字被分割",sum);
}
*/
如果你上面的程序會了,那么你試著做一做下面這個題。
//55234152349555098958788955584? 分割這樣一串數字,要求是用5分割,如將左邊的一串數字分割成
//55 2341 5 2349 555 0989 5 87889 555 84? 然后最后得到的結果為2341 2349 0989 87889 84
/*//program 12.2
#include <stdio.h>
#include <string.h>
int main()
{
??? char a[]="55234152349555098958788955584";
??? void search(char *);
??? search(a);
??? return 0;
}
void search(char *p){
??? long length=strlen(p);
??? int i=0,k=0,j=0,sum=0;
??? for (; i<length; i++) {
??????? if (*(p+i)!='5') {
??????????? k++;
??????????? if (*(p+i+1)=='5'||*(p+i+1)=='\0') {//這里必須加上空值,因為上面不是5結尾的
??????????????? for (; j<k; j++) {
??????????????????? printf("%c",*(p+i-k+1+j));//這個地方是一個比較逗B的巧合,因為我們在輸出第一個分割出來的數字時,k和j都沒有歸0,那么如上面的一串數字,在輸出第二個數字的時候,k是從5開始的(因為第一個分割出來的數字有4位,也就是k=4),那么等第二個數字遍歷完畢時,k應該變成了8(同理,第二個分割出來的數字也是有4位的)。再看j,第一次分割結束的時候跳出for循環(huán)的時候j做了一次j++,那么j的值就和k當時的值是一樣的,所以j在進入第二個分割數的for循環(huán)的時候j應該是4,而不是0,那么第二次分割出來的數字的首字符應該是*(p+10-8+1+4),也就是*(p+7),正好就是數字2349中2的地址。這個地方可以說是誤打誤撞,讀者可能在看這個地方的時候看不懂是怎么得到的正確結果。
??????????????? }
??????????????? sum++;
??????????????? printf(" ");
??????????? }
??????? }
??? }
??? printf("\n共有%d個數字被分割",sum);
}
*/
好了指針部分也差不多結束了,敲了不少程序,希望大家能夠準確理解指針~
接下來轉入結構體,也是最后一個環(huán)節(jié)的學習。
//結構體類型事實上和int,char,float類型都大同小異,只不過結構體類型是我們自己定義的類型。結構體類型和結構體變量不是一回事,我們知道只能對變量賦值,存取或者運算,而不能對類型如此,類型是不需要分配空間的,只能對變量分配空間。
//定義結構體類型的格式:????? struct 結構體名{ 成員表列 };???? 注意在聲明結構體類型的時候要最后加上分號。
//當然在聲明結構體類型的同時可以定義變量:????? struct 結構體名{ 成員表列 } 變量名表列;
//另外要注意的是結構體類型中的成員名和程序中的變量名如果相同,但二者不代表同一對象的,是兩回事,互不干擾
//定義Student結構體類型,然后將一個同學信息(學號,姓名,性別,住址)放在一個結構體變量中,然后輸出該學生的成績。
/*//program 12.3
#include "stdio.h"
int main()
{
??? struct Student
??? {
??????? int number;
??????? char name[20];
??????? char sex[20];//注意,如果在結構體類型中有成員是字符串形式的,那么這里要將成員定義成字符數組的形式
??????? char addr[30];
??? };
??? struct Student a={123456,"wangzhongyao","man","shandongshengjinanshi"};//這里是先聲明結構體類型,然后再定義結構體變量a,分開進行。下面給出在結構體類型聲明的同時定義變量的情況。
??? printf("No.%d\nname:%s\nsex:%s\naddress:%s\n",a.number,a.name,a.sex,a.addr);//這里輸出的并不是a,而是a的各個屬性,我們輸出的是a的詳細信息,所以要用? a.變量名? 來輸出。這里很重要。
??? return 0;
}
*/
//還是上面的程序,在結構體類型聲明的同時定義結構體變量。
/*//program 12.4
#include<stdio.h>
int main()
{
??? struct Student
??? {
??????? int number;
??????? char name[20];
??????? char sex[10];
??????? char addr[30];
??? }
??? a={123,"maxingze","man","jiningshilaozhaizhen"},b={1234,"yuetianhao","man","jiningshijiaxiangxian"};
??? //這里注意,在結構體類型聲明的同時定義結構體變量的話,要把結構體變量定義在結構體類型聲明時最后一個分號的前面!!!!!這里一定要注意哦!!!
??? printf("No.%d\nname:%s\nsex:%s\naddr:%s\n\n",a.number,a.name,a.sex,a.addr);
??? printf("No.%d\nname:%s\nsex:%s\naddr:%s\n\n",b.number,b.name,b.sex,b.addr);
??? return 0;
}
*/
/*//program 12.5
?//對結構體類型中某一成員進行初始化(不完全初始化成員),其余未被初始化的成員是什么情況?下面給出解答。
#include<stdio.h>
int main()
{
??? struct Student
??? {
??????? int card;
??????? char name[10];
??????? char sex[10];
??????? char bumen[20];
??? }
??? a={.name="man"};//允許對結構體中的某一成員初始化,其他 未被初始化的 數值型成員 被初始化為0,未被初始化的 字符型成員 被初始化為'\0',未被初始化的 指針型成員 被初始化為NULL。這里必須要牢記!!!!!!!
??? printf("Card:%d\nname:%s\nsex:%s\nbumen:%s\n",a.card,a.name,a.sex,a.bumen);
??? return 0;
}
*/
/*//program 12.6
//結構體變量之間可以互相賦值
#include <stdio.h>
int main()
{
??? struct Student
??? {
??????? int card;
??????? char name[10];
??????? char sex[10];
??? }
??? a={123,"a","man"},b={321,"b","woman"};//在結構體類型聲明的時候定義變量,要注意定義多個變量的時候中間用','隔開,在最后的一個變量定義結束時加一個';'即可,當然最后加很多';'也沒有錯誤(驗證得到)。
??? a=b;//同類型結構體變量之間可以相互賦值(如:?? a=b;),同樣同類型結構體變量中相同成員也可以互相賦值(如:?? a.card=b.card;)
??? printf("card:%d\nname:%s\nsex:%s\n",a.card,a.name,a.sex);
??? return 0;
}
*/
//注意不能用以下語句整體讀入結構體變量
//scanf("%d,%s,%s\n",&a);?? 因為結構體變量的地址主要用作函數參數,傳遞結構體變量的地址。(這句話需要讀者好好理解!!!)
//那應該怎么讀入結構體變量呢? 顯然要將結構體變量中每一個成員 分別 讀入,如下:
//scanf("%d,%s,%s\n",&a.card,&a.name,&a.sex);
//輸入兩個學生的學號、姓名和成績,輸出成績較高的學生的學號、姓名和成績
//下面的題目中沒有寫兩個學生成績相等的情況,讀者可以自行加上
/*//program 12.7
#include "stdio.h"
int main()
{
??? struct Student
??? {
??????? int number;
??????? char name[20];
??????? int grade;//成績是一個整數,這里不要錯誤的聲明為數組類型
??? }
??? a,b;
??? printf("請輸入兩個學生的學號、姓名、成績:\nNo.1:\n");
??? scanf("%d%s%d",&a.number,a.name,&a.grade);
??? //scanf(格式控制,地址表列);? 這里的地址表列可以是變量的地址,也可以是字符串的首地址。(這句話很重要,在上面一句輸入語句中,只有a.name沒有加'&'號,這是因為name為數組名,代表了字符串數組的首地址,所以說a.name就是一個地址,所以不用再加'&'了)
??? printf("No.2:\n");
??? scanf("%d%s%d",&b.number,b.name,&b.grade);
??? if (a.grade>b.grade) {
??????? printf("number:%d\nname:%s\ngrade:%d\n",a.number,a.name,a.grade);
??? }
??? else
??? {
??????? printf("number:%d\nname:%s\ngrade:%d\n",b.number,b.name,b.grade);
??? }
??? return 0;
}
*/
/*//program 12.8
//有3個候選人,編一個統計選票的程序,先后輸入備選人的名字,然后輸出個人選票結果
#include <stdio.h>
struct Person
{
??? char name[20];
??? int count;
}lead[3]={"ma",0,"wang",0,"zheng",0};
int main()
{
??? char lead_name[20];//聲明一個字符數組,用來存放下面10次投票時 每一次 投票的人選姓名
??? printf("請投票10次:\n");
??? for (int i=0; i<10; i++) {
??????? scanf("%s",lead_name);//這里的lead_name就是數組名,表示的就是這個字符串的首地址。i=10,所以這里要輸入10個字符串,分10次輸入,下面調用strcmp函數就是將 每一次 投票的任選姓名和候選名單中的三個姓名比較,如果一樣,那么結構體變量中的count成員就+1 。
??????? for (int j=0; j<3; j++) {
??????????? if (strcmp(lead_name,lead[j].name)==0)//這里為什么能用lead_name呢?這個不是地址么,這里應該是比較兩個字符串的值把? 記住就好了,字符數組,用數組名來比較即可
??????????? {
??????????????? lead[j].count++;
??????????? }
??????? }
??? }
??? for (int i=0; i<3; i++) {
??????? printf("%s:%d\n",lead[i].name,lead[i].count);
??? }
??? return 0;
}
*/
//定義結構體數組的一般形式是
// struct 結構體名 { 成員表列 } 數組名[數組長度] ;
//或者是先聲明一個結構體類型,然后再定義結構體數組,在已經聲明好結構體類型的情況下我們可以這樣定義:
//結構體類型 數組名[數組長度]={初值表列};? (如:? struct Person a[3]={"ma",0,"wang",0,"zheng",0};? )
//有n個學生的信息(學號、姓名、成績),要求按照成績的高低順序輸出各學生的信息
/*//program 12.9
#include "stdio.h"
struct Student
{
??? int number;
??? char name[20];
??? int grade;
};
void change(struct Student *a,int n)
{
??? struct Student temp;//這里的temp和上面數組中的成員是一樣的類型,用來在下面排序時作交換的。
??? int i,j,k;
??? for (i=0; i<n-1; i++) {
??????? k=i;
??????? for (j=i+1; j<n; j++) {
??????????? if (a[k].grade<a[j].grade) {
??????????????? k=j;
??????????? }
??????? }
??????? temp=a[k];
??????? a[k]=a[i];
??????? a[i]=temp;
??? }
??? for (i=0; i<n; i++) {
??????? printf("number:%d name:%s grade:%d\n",a[i].number,a[i].name,a[i].grade);
??? }
}
int main()
{
??? struct Student ss[]={1001,"wang",98,1002,"ma",99,1003,"zheng",87,1004,"yue",89,1005,"zhang",100};
??? void change(struct Student *a,int n);
??? change(ss,5);
??? return 0;
}
*/
//結構體指針。通過 指向 結構體變量 的指針 來訪問 結構體變量 中的 成員。
//首先我們要知道,這個結構體指針是指向結構體變量的,然后再通過指針去訪問結構體變量的成員。
//結構體指針其實和普通指針差不多,就是指向的結構體變量,而且多了一種形式(p->number)。
/*//program 12.10
#include "stdio.h"
#include "string.h"
struct Student
{
??? int number;
??? char name[30];
??? char sex[10];
??? int grade;
};
int main()
{
??? struct Student a;
??? a.number=1001;
??? strcpy(a.name,"Xingze Ma");//這里需要注意一下,如果不是直接對整個結構體變量初始化,而是對其中一個一個成員分別初始化,那么在初始化字符數組成員的時候(也就是需要初始化一個字符串),需要用到strcpy函數,這個函數是復制字符串的。對于字符串的賦值,不能說char a[10];? a=“123”; 這樣錯誤。 對于字符串賦值,要么在聲明的初始化(char a[10]=“123”;),要么用scanf函數給字符串輸入值,要么就要用strcpy函數復制字符串,而也是本題中用的方法,也最為常用
??? strcpy(a.sex,"gay");
??? a.grade=59;
??? struct Student *p;
??? p=&a;
??? printf("number:%d\nname:%s\nsex:%s\ngrade:%d\n\n",(*p).number,(*p).name,(*p).sex,(*p).grade);
??? //'.'運算符優(yōu)先于'*'運算符,所以這里必須加括號(*p)
??? printf("number:%d\nname:%s\nsex:%s\ngrade:%d\n",p->number,p->name,p->sex,p->grade);
??? //為了方便,允許把 (*p).number 用 p->number 來代替,含義是p所指向的 結構體變量 中的 number成員
??? //所以以下3種情況是等價的
??? //struct Student a;??? struct Student *p=&a;
??? //①a.number ②(*p).number ③p->number
??? return 0;
}
*/
//指向結構體數組的指針
//和指向一般數組的指針也別無二致,就是指向結構體數組的首地址即可
/*//program 12.11
#include "stdio.h"
struct Student
{
??? int card;
??? char name[20];
??? char sex[20];
}
a[]={{1001,"wang","man"},{1002,"ma","woman"},{1003,"zheng","gay"}};
int main()
{
??? struct Student *p=a;
??? for (; p<a+3; p++) {//這里無論是什么情況下在for循環(huán)中用指針,這是p<a+3,而不是p<p+3 , 牢記!!!!
??????? printf("card:%d\nname:%s\nsex:%s\n\n",p->card,(*p).name,p->sex);
??? }
??? return 0;
}
*/
//用 結構體變量 和 結構體變量的指針 作函數參數
//有n個結構體變量,內含學生學號、姓名和3門課程的成績。要求輸出平均成績最高的學生的信息。
/*//program 12.12
#include "stdio.h"
#define N 3
struct Student
{
??? int num;
??? char name[20];
??? float score[3];
??? float aver;
};
void scanf1(struct Student ss[])
{
??? printf("請輸入各學生信息:\n");
??? for (int i=0; i<N; i++) {
??????? scanf("%d%s%f%f%f",&ss[i].num,&ss[i].name,&ss[i].score[0],&ss[i].score[1],&ss[i].score[2]);
??????? ss[i].aver=(ss[i].score[0]+ss[i].score[1]+ss[i].score[2])/3;
??? }
}
struct Student max(struct Student ss[])
{
??? float max=ss[0].aver;
??? int k=0;
??? for(int i=1;i<N;i++)
??? {
??????? if(max<ss[i].aver)
??????? {
??????????? max=ss[i].aver;
??????????? k=i;
??????? }
??? }
??? return ss[k];
}
void print(struct Student s)
{
??? printf("成績最好的學生是:\n%d %s %5.2f %5.2f %5.2f",s.num,s.name,s.score[0],s.score[1],s.score[2]);
}
int main()
{
??? void scanf1(struct Student ss[]);//這里要傳入結構體數組中數組元素,因為我們比較好幾個學生的平均成績,自然要準備一個數組存放它們
??? struct Student max(struct Student ss[]);
??? void print(struct Student s);
??? struct Student s[N];
??? scanf1(s);//這里傳進去的是數組s[N]的首地址,所以這里我們也可以用指針操作,可以定義一個結構體指針指向s[N],然后調用函數的時候用p來調用,其作用是一樣的
??? print(max(s));
??? //struct Student q;
??? //q=max(p);
??? //print(q);
??? return 0;
}
*/
program 12.12 將我們學過的知識基本上匯合了一下,我們的學習也就到此結束了,短短12天,學到的東西很多,我只把C語言部分介紹到結構體,剩下還有一些結構體和鏈表、共用體類型、文件讀寫等等部分我就不一一介紹了。時間有限,由讀者自行學習。希望讀者能學習到一些知識,那么我寫的這幾篇連載博客也就有價值了。希望大家學習愉快!
?? ??? ??? ??? ??? ??? ??? ????
版權聲明:本文為博主原創(chuàng)文章,未經博主允許不得轉載。
轉載于:https://www.cnblogs.com/wzy294250051/p/4787903.html
總結
以上是生活随笔為你收集整理的12天学好C语言——记录我的C语言学习之路(Day 12)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu安装
- 下一篇: location.pathname;ou