?? ex7.cpp
字號:
// 第7章 程序的結構
// [例7.1]初始化語句中引入的局部變量的作用范圍
#include <iostream.h>
void main()
{ for (int k=0;k<100;++k)
cout << k << "\n";
cout << k << "1.\n"; //(在Builder5.0中此處的變量k是沒有定義的變量
for (int k=100;k>=0;--k) //( vc6.0 中[int k=100;]導致變量k兩次定義
cout << k << "\n";
}
// [例7.2]標號名在一個特殊的名稱空間
# include<iostream.h>
void main(void)
{ char chs; const int n=8;
for(int k=0; k<n;k++)
{ if(k%2) goto k; //標號k與變量k同名
chs='a'+k; goto n; //標號n與常量n同名
k: chs='A'+k;
n: cout<<chs<<" ";
}
} //輸出: a B c D e F g H
//[例7.3] 單獨使用三目運算符表達式語句,其中的操作數為void型的函數調用
#include<stdio.h>
void a(int x){ printf("a=%d\t",x);}
char * s="b=%d\t"; //定義char*型全局指針s,初始化指向格式字符串"b=%d\t"
void main() //初始化char*型指針的字符串率先被安排在全局數據區
{ int a=1,b=3; //隨后將字符串數據區的首地址初始化char*型指針s
char * s="%d,%d"; //定義外層局部指針s,指向格式字符串"%d,%d"
{char * s="輸入兩個整數";printf("%s",s);} //定義內層局部指針s
scanf(s,&a,&b); //外層局部指針s具有塊作用域,隱藏了全局指針s
a>b ? ::a(a): printf(::s,b); //全局分辨符突出索引全局指針::s
}
//[例7.4] static關鍵字屏蔽函數在模塊間連接
// c.pp
#include<stdio.h>
extern int x; extern int y; //外部全局變量說明,x,y其它模塊中定義。
extern int a[]; //不完備地說明一個數組a,數組的維數在定義點確定
void main(){printf("%d,%d,%d,%d\n",x,y,a[0],a[1]);} //輸出1,2,3,4
// a.cpp
static long f(long x); //a.cpp文件中的靜態的內部函數f
int x=f(1); //定義全局變量x。調用內部函數f
long f(long x) { return x; } //內部函數f的定義
int a[]={3,4}; //定義全局數組a[],這個數組的維數由初始化表的個數靈活確定
b.cpp
static long f(long x) { return x; } //b.cpp文件中的靜態的內部函數f
int y=f(2); //定義全局變量y,調用內部函數f
//
#include <stdio.h> //定義靜態變量并初始化為0
void f() { static int n=0; n++; printf("%d ",n); }
void main() { f(); f(); f(); }
//輸出結果:1 2 3
////////////////////
void g(int k) { static int n=k; n++; printf("%d ",n); }
void main() { g(3); g(7); g(0); }
//////////////////
void h() { static int n=0; n++; printf("%d ",n); n=20; }
void main() { h(); h(); h(); }
// [例7.5]全局范圍的初始化語句[long x=fx();long& y=fy();]導致函數在main之前調用
#include<stdio.h> //返回引用的函數fy不應返回非靜態的局部變量
typedef long LONG; //long的全局別名 LONG
long fx() { LONG z; scanf("%d",&z); return z;}//fx函數返回非靜態的局部變量z
long& fy() //返回引用的函數fy動態地返回靜態變量名z或q
{ static LONG q=5; //定義局部的靜態變量q,初始賦值為5
typedef long LINT; //long的局部別名LINT
static LINT z; //定義靜態的局部變量z
scanf("%d",&z); //從鍵盤動態讀入z的值
if(z!=1) return z; //if~else雙路分支返回變量名
else return q; //z等于1返回q
} //局部別名LINT在fy函數體中索引,全局別名 LONG在隨后的范圍索引
LONG x=fx(); //定義全局變量x,這個初始化語句動態確定x的值。
long& y=fy(); //聲明全局引用y,y動態地關聯局部靜態變量z或q
void main() { printf("y=%d,x=%d",y,x); }
// [例7.6]靜態局部變量求n!
# include<stdio.h>
extern long f(int n)
{ static int s=1;
return s*=n;
}
void main()
{ int k ;
for(k=1;k<4;k++)
printf("%d!=%d;",k,f(k));
}
//[例7.7]靜態全局變量求n!
static int s=1;
# include<stdio.h>
long f(int n){ return s*=n; }
void main()
{ int k;
for(k=1;k<3;k++)
printf("%d!=%d;",k,f(k));
printf("%d!=%d;",k,s*=k);
}
// [例7.8]局部變量求n!階乘
#include <stdio.h>
long f (int n)
{ long s=1;int j=n;
for(;j>0;j--) s*=j;
return s;
}
void main(void)
{ int k ;
for(k=1;k<4;k++)
printf("%d!=%d;",k,f(k));
}
//[例7.9]返回long*型指針值的函數與static關鍵字內部屏蔽的編程技術
// a.cpp
#include<stdio.h>
void Show(const char* s,long p[]) {printf("%s p[0]=%d,p[1]=%d \n",s,p[0],p[1]); }
extern long* fg(); long* fx(); //四個返回long*型指針值的函數原型
extern long* fy(); long* fz(); //非靜態的全局函數具有extern的默認屬性
void main(void) /*程序運行輸出結果如下*/
{ Show("globle",fg()); //globle p[0]=1,p[1]=2
Show("static",fx()); // static p[0]=3,p[1]=4
Show("heap ",fy()); // heap p[0]=5,p[1]=6
Show("stack ",fz()); //stack p[0]=-858993460,p[1]=-858993460
} //函數調用fg(),fx(),fy(),fz()是long*型的表達式
// xyz.cpp
long* fz() { long a[]={7,8,9}; return a+1; }//返回一個局部內存地址危險!
long* fx() { static long a[]={2,3,4}; return a+1; }//返回靜態局部內存的地址
long* fy() { long* y=new long[2]; y[0]=5;y[1]=6; return y;}//返回堆空間的地址
// g.cpp
static long g[]={1,2,3}; //定義long型靜態全局數組g[3]
long* fg() { return g; } // fg返回靜態全局數組的首地址
// [例7.10]求二維數組中的元素最后一次小于60所在的行的函數int* low(int(*)[3], int)
# include<stdio.h> // const int m中的m為動態的只讀形參
const int M=3; //M是全局的作為立即數的整型常數
int* low(int (*)[M], int n); //函數原型為指向數組的指針形參,返回int*型的地址
void show(int a[],const int m) {for(int j=0;j<m;j++) printf("%d,",a[j]);}
void main() //程序運行輸出:61,58,78, 70,90,56,
{ int a[][M]={60,70,80,85,95,75,{70,90,56},88,90,78,{61,58,78},80,90,70};
const int n=sizeof(a)/sizeof(a[0]);//這個n=6是局部的作為立即數的整型常數
int * p=low(a,n);// low(a,n)在整個二維數組求小于60所在的行,得到p=a[4]
for(int i=0;i<n;i+=2,p=low(a,n-i)) // p=low(a,n-2)的結果為p=a[2]
if(p!=0) show(p,M); // if(p!=0)過濾開關是重要的
} //low(a,n-2)在數據區間60,70,80,85,95,75,{70,90,56},88,90,78求小于60所在的行
int* low(int a[][M], int n) //函數定義為二維數組形參
{ int* low= 0; //low既是局部指針名又是全局作用范圍的函數名
for(int i=0;i<n;i++) //編譯器優先采用局部名稱low
for(int j=0;j<M;j++) if(a[i][j]<60) low=a[i];
return low; //沒有找到小于60的元素,函數返回0,找到則返回a[i]。
} //函數返回局部指針名low,而不是全局函數名low,返回的a[i]是實參的地址。 [例]返回指向二維數組的指針的函數與順序法求數組中的極大值所在的行(多學時)
///[例7.11]////////////////////
#include<stdio.h>
const int M=3; //標題頭不能寫成double(*)[3] FindFirstMax (double (*pt)[M],int n)
typedef double(*PT)[M]; //聲明一個double(*)[3]類型的別名PT,以指定返回類型
PT FindFirstMax (double (*q)[M],int n) //返回PT型指針的函數
{ double max=q[0][0]; //指向二維數組的指針q的生存期局限于此函數體
int keep=0;
for(int i=0;i<n;i++) //外層循環搜尋二維數組的每一行
{ double* pi=q[i]; //設置一個臨時指針pi,優化尋址計算
for(int j=0;j<M;j++) if(pi[j]>max) {keep=i; max=pi[j];}
} //函數返回double(*)[3]型的地址q+keep
return q+keep; //返回的這個地址指向實參對應的數組空間
} //局部指針q的生存期到此結束
double b[][3]={{60,70,58},{70,80,78},{90,95,85},{80,45,95}};//定義全局數組
const int m=sizeof(b)/sizeof(b[0]); //聲明靜態的整型常數m
PT q= FindFirstMax(b,m); //定義double(*)[3]型的全局指針q,并調用函數初始化
void main(void)
{ double* const p=*q; //設置一個臨時指針p,優化尋址計算
int keep=q-b; // keep=q-b得到極大值所在的行的下標
for(int k=0;k<3;k++) printf("b[%d][%d]=%4.1f\t", keep,k,p[k]);
} //輸出結果:b[2][0]=90.0 b[2][1]=95.0 b[2][2]=85.0
// [例7.12]返回二級指針的函數返回堆空間指針數組的首地址[注意左右兩邊的異同](多學時)
int** ppHeap (int n,int m)
{ int** pp=new int*[n];
int *p=new int[n*m];
for(int j=0;j<n;j++) pp[j]=p+j*m;
return pp;
}
/*2次調用new運算符函數*/
int a[]={1,2,3,4,5,6};
int**s=ppHeap(2,3); /*定義全局指針s */
#include<stdio.h>
void main()
{ int* p=*s;
for(int i=0;i<6;i++)
p[i]=a[i];
printf("%d,%d",s[0][2], s[1][2]);
} /*輸出:3,6*/
///////////////////////////////////////
int** ppnHeap (int n,int m)
{ int** pp=new int*[n];
for(int j=0;j<n;j++)
pp[j] =new int[m];
return pp;
}
/*n+1次調用new運算符函數*/
int a[][3]={1,2,3,4,5,6};
int**s=ppnHeap(2,3);
#include<stdio.h>
void main()
{ for(int i=0;i<2;i++)
{ int* p=s[i];
for(int j=0;j<3;j++) p[j]=a[i][j];
}
printf("%d,%d",s[0][2], s[1][2]);
} //輸出:3,6
// [例7.13]整型表達式強制轉換為枚舉變量,引起枚舉變量的值超出枚舉常數之外。
# include<stdio.h>
void main(void)
{ enum Enum {z, charDat=sizeof('c'),fltDat=1+3,intDat=sizeof(1)}e,x=intDat;
e=(Enum )(charDat+fltDat+x+intDat); //強制類型轉換
printf("E=%d,%d\n", e,(z+intDat)/fltDat); //輸出結果為E=13,1
}
//[例7.14]無名枚舉直接指定case分支的多個符號常數
#include<stdio.h>
enum { LINE=1, RECTANGLE, TRIANGLE };//聲明一組全局枚舉常數
const char * GetString(int nType)//返回const char *型的指針值的函數
{ switch (nType) //從char*型類型轉換為const char *型是默許的,是安全的
{ case LINE: return ("Line");
case RECTANGLE: return "Rectangle";
case TRIANGLE: return "Triangle";
default: return "Unknown";
} //字符串"Unknown"等系統先行安排在全局只讀數據區,但屬性為char*型
} //函數返回這些全局只讀字符串的首地址
void main(void)
{ enum { five=5}; //聲明一個局部范圍的枚舉常數five
printf("%d,%s\t",LINE,"Line");
printf("%d,%s\t",TRIANGLE,GetString(TRIANGLE));
printf("%d,%s\n",five,GetString(five));
} //輸出:1,Line 3,Triangle 5,Unknown
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -