⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex7.cpp

📁 C/C++程序设计教程
💻 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 + -