?? ex12.cpp
字號:
pAdd->pNext=pFind; //插入位置在表尾的結點前,鏈頭之后
} //[pPrev]< [pAdd]<= [pFind]<[...]<=[Tail]
else //此時pFind->pNext=0同時 pFind->elem<key
{ pFind->pNext=pAdd; //插入位置在原先表尾之后
pAdd->pNext=NULL; // [pFind= tail ]<= [pAdd]
}
return pHead; //返回原來的表頭
}
void Show(SList* p)
{ for(int k=1;p!=0;p=p->pNext,k++)
printf("[%d,%c]-",p->elem,p->data);
printf("\n");
}
SList a={ 6,'a',NULL}; //定義全局結構變量a和數組d
SList d[]={8,'d',NULL,5,'d',NULL,4,'d',NULL,9,'d',NULL};
void main()
{ const int n=sizeof(d)/sizeof(SList); //計算結構數組d的維數
SList c[n]={7,'c',0,5,'c',0,4,'c',0,9,'c',0}; //定義局部結構數組c
SList *pBegin=0; //設置一個局部指針旨在指向鏈表的頭結點
int k ;for(k=n-1;k>=0;k--) //將數組c元素的地址作為插入結點實參
pBegin=Insert(pBegin,&c[k]); //根據從小到大的次序形成鏈表
Show(pBegin);
for( k=0;k<n;k++) //將數組d元素的地址作為插入結點實參
pBegin=Insert(pBegin,d+k);
Show(Insert(pBegin,&a)); //將a結點加入pBegin為首的鏈表
} /*輸出結果如下*/
////////////[例12.12]將一個結點從鏈表中脫離出來
# include <stdio.h>
typedef struct SList_tag
{ int elem; char data;
struct SList_tag* pNext;
} SList;
SList* Detach(SList*pHead,int key)
{ if(pHead==NULL) //頭結點是空指針無功返回
{printf("NULL List\n");return pHead;}
if(key==pHead->elem)
{ pHead=pHead->pNext; //原頭結點的下屬升為新的頭結點
printf("the Head element=%d detached\n",key);
return pHead; //返回新的鏈首
}
SList*pFind=pHead; // pFind是搜尋捕獲要脫離的探針
SList*pPrev; // pPrev紀錄捕獲結點的前結點
while(key!=pFind->elem&&pFind->pNext!=NULL)
{ //未探到要找的結點同時后面尚有結點,繼續循環//
pPrev=pFind;
pFind=pFind->pNext;
}
if(key==pFind->elem) //找到了結點
{ pPrev->pNext=pFind->pNext; //建立新的關聯
printf("the element=%d detached\n",pFind->elem);
}
else printf("element not found\n"); //原鏈表中無篩選尺度所指定的結點
return pHead; //返回原來的表頭
}
extern void Show(SList* p) ;
extern SList* Insert(SList*pHead,SList*pAdd);
SList d[]={8,'d',0,5,'d',0,4,'d',0,9,'d',0};//定義全局結構數組d
void main(void)
{ SList *pOldH=0;
for(int k=0;k<4;k++)
pOldH=Insert(pOldH,d+k); //輸出結果如下:
Show(pOldH); //[4,d]-[5,d]-[8,d]-[9,d]-
SList* pNewH =Detach(pOldH,4); //the Head element=4 detached
Show(pNewH); //[5,d]-[8,d]-[9,d]-
Show(pOldH); //[4,d]-[5,d]-[8,d]-[9,d]-
}
//////////////[例12.13] 聯合的內存和結構的內存大小比較
#include<stdio.h>
typedef struct s_a { double d; char c[9]; } A;// 結構A的長度為24
typedef struct s_b { double d; long k[2];} B; // 結構B的長度為16
typedef union u_t { A a; B b; } U; //聯合U的長度單獨由成員a確定
typedef struct s_t { A a; B b; } S; //結構S的長度是成員a和b長度之和
void main (void)
{ printf("sizeof(A)=%d,",sizeof(A)); printf("sizeof(B)= %d,",sizeof(B));
printf("sizeof(U)= %d,",sizeof(U)); printf("sizeof(S)= %d",sizeof(S));
} //輸出:sizeof(A)= 24,sizeof(B)= 16,16,sizeof(U)= 24,24,sizeof(S)= 40
/////////////[例12.14] 聯合指針入口形參和聯合引用返回
#include<stdio.h>
inline int f(int k){return k;}
typedef union u_t { char* s; int (*f)(int); int d; } Un ;
Un& initial(Un*p ,int n,char * s) //成員名s,f在全局函數中不單獨使用
{ switch(n) //單獨使用的名稱s,f具有其它的含義
{ case 1: p->s=s; break;//char*型局部指針s初始化字符指針成員s
case 2: p->f=f; break; //全局函數名f初始化int (*)(int)型的函數指針成員
default: p->d=n;break;//對 int 型的變量成員d賦值
} //三個成員互斥地使用同一內存
return *p;
}
void main (void)
{ Un x;
for(int n=1;n<4;n++)
{ Un y= initial(&x,n,"abcd");
switch(n)
{ case 1: printf("[%s,%s]\t",x.s,y.s); break;
case 2: printf("[%d,%d]\t",x.f(1),y.f(2)); break;
default: printf("[%d,%d]\n",x.d,y.d); break;
}
}
} //輸出:[abcd,abcd] [1,2] [3,3]
/////////////[例12.15] 強制類型轉換顯示低尾端存儲格式(8位二進制數的低位在右邊,高位在左邊)
#include<stdio.h>
void main()
{ unsigned long m=0x87654321UL;
unsigned char * p=(unsigned char*)&m;
for(int i=0;i<sizeof(long);i++) printf("%x ",*p++);
} //低尾端的PC計算上輸出結果:21 43 65 87
/////////////[例12.16] 聯合的內存布局和內存數據的解釋
#include<stdio.h>
typedef union u_t { char c[2]; unsigned long k; } U;
void main()
{ U x = {3,1}; //x.c[0]=3;x.c[1]=1; 潛在地導致x.c[2]=0;x.c[3]=0;
printf("%d,0x%08x\t",x.k,x.k);
x.k= 0x67686162UL;
printf("%c,%d,%c,%d; ",x.c[0],x.c[0],x.c[1],x.c[1]);
printf("%c,%d,%c,%d\n ",x.c[2],x.c[2],x.c[3],x.c[3]);// "越界"索引字符成員數組元素
} //輸出:259,0x00000103 b,98,a,97; h,104,g,103
////////// [例12.17]浮點數和整型數內存存儲格式不同
#include<stdio.h>
typedef union u_fl { float f; long k; } Ua;
typedef union u_il { int f; long k; } Ub;
//struct Sab { Ua a; Ub b;} s={ 1.0,2 };這個結構的聲明相當于下面的結構
struct Sab { union {float f ; long k;} a; Ub b;} s={ 1.0,2 };
void main() //Sab結構中兩個成員是聯合變量,聯合變量s.a的類型相當于Ua類型
{ printf("[%1.0f,%d]\t",s.a.f,s.b.f);
Ua & x=(Ua &)s.a ; //引用x是聯合變量s.a的別名,此處顯式類型轉換是必須的
x.f=10; printf("[%d,%d]\t",(long)(x.f+s.a.f),x.k);// x.k輸出結果1092616192
x.k=20; printf("[%d,%d]\t",(long)x.f,x.k+s.a.k);// (long)x.f輸出結果0
Ub & y=s.b ; //引用y是聯合變量s.b的別名
y.f=10; printf("[%d,%d]\t",(long)y.f,s.b.k);
y.k=20; printf("[%d,%d]\n",(long)s.b.f,y.k);
} //輸出:[1,2] [20,1092616192] [0,40] [10,10] [20,20]
///////////[例12.18] 無名聯合直接定義局部共享的多個變量n,m, x, y。
#include<stdio.h>
void main (void)
{ union { int n; long m; double x; double y; } ;
printf("[%p,%p]\t",&n,&y);
n=3; printf("[%d,%d]\t",n,m);
x=6; printf("[%f,%f]\n",x,y);
}//輸出:[0065FDF0,0065FDF0] [3,3] [6.000000,6.000000]
/////// [例12.19]無名聯合 static union{ point_t z; point3d b;};定義靜態全局結構變量b和z
# include <stdio.h>
typedef struct { double v[3]; } point_t;
typedef struct { double x,y,z; } point3d;
typedef union { point_t z; point3d b;} Ua ; //結構變量作為聯合Ua的成員
point3d* CrossProduct( point3d in1, point3d& a)
{ const point3d in2=a;
a.x = in1.y * in2.z - in1.z * in2.y;
a.y = in1.z * in2.x - in1.x * in2.z;
a.z = in1.x * in2.y - in1.y * in2.x;
return &a;
}
static union { point_t z; point3d b; };
extern point_t * q; // 外部連接屬性的全局指針
const point3d x={1,1,0};
point_t* q;
void main(void)
{ b.x=0; b.y=2; b.z=1;
q=(point_t*)CrossProduct(x,b);
if( b.x==z.v[0] && b.y==z.v[1] && b.z==z.v[2])
printf("b={%4.1f,%4.1f,%4.1f}\t", b.x, b.y,b.z);
printf("q={%4.1f,%4.1f,%4.1f}\t", q->v[0], q->v[1], q->v[2]);
Ua a={1,2,3}; //對聯合的第一個結構變量成員z初始化
printf("a={%4.1f,%4.1f,%4.1f}\n", a.b.x, a.b.y,a.b.z);//輸出第2個成員b的值
} //輸出: b={ 1.0,-1.0, 2.0} q={ 1.0,-1.0, 2.0} a={ 1.0, 2.0, 3.0}
/////////[例12.20] 結構范圍中的無名聯合實現不同課題組之間的數據接口
# include<stdio.h>
# include<string.h>
typedef struct a_t //結構中實際上只有三個獨立的成員
{ union { int n; int number; }; //成員名稱n和number是等價的
union { float f; float income; }; //成員名稱f和income是同等的
union { char *s; char *name; }; //成員名稱s和name是合一的
} A, B;
int SeqFind(const B s[],int n,float key) //浮點型變量key作為待查的關鍵指標
{ //順序查找關鍵字key對應的數組元素
for(int i=0;i<n;i++) //從數組元素的起始依次與關鍵字比較
if(s[i].income==key) return i; //如果相等則返回數組的下標
return -1; //否則返回-1這個失敗標志
}
int SeqFind(const A s[],int n,const char* key) //順序或線性查找算法
{ //字符串指針key作為查找的標準
for(int i=0;i<n;i++)
if(strcmp(s[i].s,key)==0) return i; //調用字符串比較函數strcmp進行判斷
return -1;
}
void InitData(B b[],int n[],float f[],char (*s)[20],int num=5)
{ //對結構數組的成員進行初始化的函數
for(int i=0;i<num;i++)
{ b[i].number=n[i]; b[i].income=f[i];
b[i].name =s[i]; //指針通過賦值語句初始化
}
}
void show(B& r) //引用語法輸出結構變量的成員
{ printf("{%d,%f,%s}\t",r.number,r.income,r.name); }
void show(A* s,int n) //指針語法輸出結構數組的成員
{ for(A*p=s;p<s+n;p++) printf("{%d,%4.1f,%s},",p->n,p->f,p->s);
printf("\n");
}
const int N=5;
static char ca[N][20]={"Hisen","Boir","Rose","Bush","Kelin"};
void main()
{ static int na[N]={11,22,33,44,55};
float xa[N]={88,90,70,80,60}; A sa[N];
InitData(sa,na,xa,ca,N); show(sa,N);
int k=SeqFind(sa,N,"Rose"); if(k!=-1) show(sa[k]);
k=SeqFind(sa,N,60); if(k!=-1) show(sa[k]);
}//輸出結果:
////////[例12.21] 結構變量的類型轉換與復制
#include <stdio.h>
typedef struct sa { int m; } A;
typedef struct sb { int x; int y; } B;
void show(B& b) { printf("b={%d,%d}\t",b.x,b.y); }
void main()
{ A a={1}; B b={3,4};
(struct sa&)b=a; show(b);
a.m=8; b=(B &)a; show(b); /*越界復制b.z的值不定*/
} //程序輸出:b={1,4} b={8, 6684216}
1
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -