📄 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 + -