当前位置:   article > 正文

VC++(二)面向过程程序设计_用面向程序写vc

用面向程序写vc

//学习 《Visual+C++从入门到精通第三版》与《面向对象程序设计与Visual C++6.0教程》

面向过程程序设计

函数

int GetMax(int x,int y,int z=0)
默认值参数== ==不能出现在非默认值的左边

定义数组参数时,可以不指定大小。(C++编译器传递的是数组的首地址)
void Sort (int array[],int len)-------合法
?如何限制函数调用时必须传递指定长度的数组?
使用数组的引用作为函数的参数,这时数组的长度将作为参数的一部分

void Sort (int (&array)[10])//括号不可省略,省略后实质上在定义引用数组,非法
   {
    	int itemp=0;
    	for (int i=0;i<10;i++)
    	{
    	 	for (int j=0;j<10;j++)
    	 	{
    	 		if (array[i]>array[j]+1)
    	 			{
    	 				itemp=array[i];
    	 				array[i]=array[j];
    	 				array[j]=itemp;
    	 			}
    	 	}
    	}
    	printf("排序之后:");
    	for (int i=0;i<10;i++)
    		printf("%4d",array[i]);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

参数为数组、指针或引用类型引用传递方式(修改参数会影响到原本变量的值
其他情况值传递方式(修改参数不影响原有参数)
传值调用传地址调用引用调用
主函数swap(x,y)swap(&x,&y)swap(x,y)
调用函数void swap(int a,int b)void swap(int *a,int *b)void swap(int &a,int &b)
实质形参的变化与实参无关通过形参指针对实参进行间接读写被调用函数使用实参的别名,改变形参实质上是在改变实参

内联函数

  • 适用于简单且调用频繁的函数
  • 空间换时间的方法
  • 添加了inline关键字声明的内联函数是对编译器的一个建议,并非强制执行。对于微软的C++编译器可以使用_forceinline 关键字强制执行

inline 返回值类型 函数名(形参)
{
……
}

重载函数

  • 多个函数具有相同的函数名称
  • 编译器依靠参数类型或参数个数不同来区分调用哪个函数
  • 函数的返回值类型并不作为区分重载函数的一部分
  • 当参数类型为指针或引用类型,const关键字将作为重载函数的标识,其他参数类型不行
//以下重载函数合法
bool Validate(const int *x)
{
		return (*x>0)?1:0;
}
bool Validate(int *x)
{
		return (*x>0)?1:0;
//~~这个例子好像没啥意义啊?~~ 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • typedef(用typedef定义的与原有类型相同时) 、参数的默认值不作为区分重载函数的标识
  • 局部域中声明的函数将隐藏而不是重载全局域中的函数
//main中的函数调用是非法的
bool Validate(float x)
{……}
bool Validate(int x)
{……}
int main(int argc,char*argc[])
{
	bool Validate(double x);//前置声明第三个重载函数
	validate(10.5f);//试图调用第二个(????)函数导致错误,因为第一、二个函数被隐藏了
//正确调用: ::Validate(10.5f);
	return 0;
}
bool Validate(double x,double y)
{……}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

函数指针
== ==

  • C++中,函数名实际上是指向函数的指针
  • 函数指针指向的函数必须与函数指针定义的函数形式相同
typedef int (*ptfun)(int ,int );
int invoke(int x,int y,ptfun fun)
{ return fun(x,y);}
int sum(int x,int y){return x+y;}
int sub(int x,int y){return x-y;}
int mul(int x,int y){return x*y;}
int divi(int x,int y){return x/y;}
int main(int argc,char*argv[])
{
	ptfun pfun;
	ptfun=sum;
	int ret =inveke(20,10,pfun);
	pfun =mul;
	ret =invoke(20,10,pfun);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

typedef的详细用法

  • 相同名称的内部变量会隐藏外层局部作用域中的变量,访问全局变量要使用"::"
  • 对于全局变量默认值为0,局部变量其值不可预见
    命名空间

namespace 名称
{
常量、变量、函数等对象的定义
}

namespace Output
{
	const int MAXLEN=128;
	int ivar=10;
	void PutoutText(const char* dchData)
	{
		if (pchData!=NULL)
		{
			printf("PutoutText 命名空间: %s\n",pchData);
		}
	}
}
//引用
Output::PutoutText("Welcome to China");
//如果访问同一个命名空间中的多个对象
using namespace Output;
(访问Output命名空间中的函数)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

-对于命名空间的五点补充

  1. 同一个命名空间,可以在多个文件中进行不同的定义,此时命名空间中的内容为所有文件中此命名空间内容的总和(所以在不同文件的同一空间中也不能出现相同名称的变量)
  2. 命名空间可嵌套
namespace Windows
{
	……
	namespace GDI
	{
		void WriteText(const char*pchMag)
		{……}
		……
	}
}
//引用 WriteText
Windows::GDI::WriteText("2008");
//或(注意此时不能访问Windows中除GDI之外的定义对象)
using namespace Windows::GDI;
WriteText("2008");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 函数中定义的局部变量与命名空间中的变量同名时,命名空间中的变量将被隐藏。
    如果想要访问被隐藏的命名空间中的变量,需使用命名空间作为前缀,如“Output::ivar"(尽管前文已经使用using 命令引用命名空间Output

4.引用多个命名空间中存在的相同名字的函数时会出现编译错误,此时使用具体命名空间进行区分,如:Windows::PutoutText(“Welcome to China”)
5. 可以定义未命名命名空间,此时其仅适用于当前文件且其中对象不能与全局对象完全相同(可以重载)

函数模板

template
type Sum (type svar,type yvar)
{
return xvar+yvar;
}

class也可用typedef代替
type是用户定义的标识符,也可以是其他标识符
调用时

int ans=Sum(10,20);//10,20的数据类型与int一致
double ans=Sum(10.2,10.3)//10.2,10.3的数据类型与double 一致
int ans=Sum<int>(10.5,20);//正确调用,认为是两个int类型数相加

一个含有模板非类型参数,模板类型参数的例子

template <class type,int len>
type Max (type array[len])//获取数组最大值
{
	type ret =array[0];
	for (int i=1;i<len;i++)
		ret =(ret>array[i]?ret:array[i];
	return ret;
}

//调用
int array[5]={1,2,3,4,5};
int iret =Max<int,5>(array);
double dset[3]={10.5,11.2,9.8};
double dret =Max<double,3>(dset);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

函数模板重载的例子

template<class type>
type Sum(type xvar,type yvar)
{return xvar+yvar;}
template<class type>
type Sum(type array[],int len)
{
	type ret =0;
	for (int i=0;i<len;i++)
		ret+=array[i];
	return ret;
}
//调用
int main(int argc,char*argv[])
{
	int iret =Sum(10,20);
	printf("整数之和:%d\n",iret);
	int array[5]={1,2,3,4,5};
	int ret=Sum(array,5);
	printf("数组元素之和:%d\n",ret);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

编译预处理

  • 宏定义
    #define
    #undef
  • 文件包含指令
    #include<系统头文件>
    #include"文件名"
  • 条件编译
//哪段成立编译哪段
#if 常量表达式1
	程序段1
#elif 常量表达式2
	程序段2
	……
#else 
	程序段n+1
#endif
	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果标识符被#define定义,且没有执行undef语句,则编译程序段1,否则编译程序段2,else 可省略

#ifdef 标识符
    程序段1
#else
	程序段2
#endif
  • 1
  • 2
  • 3
  • 4
  • 5

#如果标识符没有被定义,编译程序段1,否则编译程序段2,else 可省略

#ifndef 标识符
    程序段1
#else
	程序段2
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/215342
推荐阅读
相关标签
  

闽ICP备14008679号