c语言中函数声明可以添加 默认参数值吗?

c语言中函数声明可以添加 默认参数值吗?,第1张

#include

void foo(int x, int y, int z)

{

printf("x = %d at [%X]n", x, &x);

printf("y = %d at [%X]n", y, &y);

printf("z = %d at [%X]n", z, &z);

}

int main(int argc, char *argv[])

{

foo(100, 200, 300);

return 0

}

运行结果:

x = 100 at [BFE28760]

y = 200 at [BFE28764]

z = 300 at [BFE28768]

C程序栈底为高地址,栈顶为低地址,因此上面的实例可以说明函数参数入栈顺序的确是从右至左的。可到底为什么呢?查了一直些文献得知,参数入栈顺序是和具体编译器实现相关的。比如,Pascal语言中参数就是从左到右入栈的,有些语言中还可以橡升通过修饰符进行指定,如Visual C++.即然两种方式都可以,为什么C语言要选择从右至左呢?

进一步发现,Pascal语言不支持可变长参数,而C语言支持这种特色,正是这个原因使得C语言函数参数入栈顺序为从右至左。具体原因为:C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入栈方式,最前面的参数被压在栈底。除非知道参数个数,否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定,正好和动态参数个数的方向相反。

因春如烂此,C语言函数参数采用自右扒漏向左的入栈顺序,主要原因是为了支持可变长参数形式。换句话说,如果不支持这个特色,C语言完全和Pascal一样,采用自左向右的参数入栈方式

定义全局参数

直接点击菜单服务器>全局参数,添加一个area参数,默认值设置为“华北”,

注:全局参数保存在工程下面的config.xml中。

打开报表

参数过滤设置

双击地区数据列单元格,选择过滤标签,橘李森在值区域中选择参数选项,可在下拉框中看到一个名为area的参数,选中它,点击添加按钮,

注:全局参数area并不是在当前模板下创建的,但是可以在模板中直接调用。

制作参数界面

点击参数模块处的笔,使参数界面处于可编扰手辑状态,参数界面的右下方会显示没有添加控件的参数名称,全局参数也会显示

点击添加全部,设置参数界面,

保存报表并发布

保存报表并分页预览,默认参数值为“华圆亩北”,直接点击查询,即可询出华北的数据

一般进行成员变量初始化用两种方法

第一种是通过在构造函数内赋值

class

point

{

public:

point(){

_x

=

0

_y

=

0}

point(

int

x,

int

y

){

_x

=

0

_y

=

0

}

private:

int

_x,

_y

}

第二种是使用初始化列表

class

point

{

public:

point():_x(0),_y(0){}

point(

int

x,

int

y

):_x(x),_y(y){}

private:

int

_x,

_y

}

这两种用法是有区别的

一、在有些情况下,必须使用初始化列表。特别是const和引用数据成员被初始化时。

class

point

{

//

这个类的定义就要求使用初始化成员列表,因为const成员只能被初始化,不局猛能被赋值

public:

point():_x(0),_y(0){}

point(

int

x,

int

y

):_x(x),_y(y){}

//point(){

_x

=

0

_y

=

0}

//point(

int

x,

int

y

){

_x

=

0

_y

=

0

}

private:

const

int

_x,

_y

}

二、是从效率方面来说的,对于内置类型或复合类型,差异不会太大,但对于非内置数据类型,差异还是很明显的

如再给point类添加一个新的string类型的成员变量

class

point

{

const

int

_x,

_y

string

_name

}

构造函数内赋值进行初始化

point(

int

x,

int

y,

string

name

){

_x

=

0

_y

=

0

_name

=

name

}

_name

=

name

这个表达式会调用string类的缺省构造函数一次,再调用operator=函数进行赋值一次。所以需调用两次函数:一次构造,一次赋值

用初始化列表进行初始化

point(

int

x,

int

y,

string

name

):_x(x),_y(y),

_name(name){}

_name会通过拷贝构造函数仅以轮察一个函数调用的代码完成初始化

即使是一个很简单的string类型,不必要的函数调用也会造成很高的代价。随着类越来越大,越来越复杂,它们的构造函数也越来越大而复杂,那么对象创建的代价也越来越高,所以一般情况下使用初始化列表进行初始化,不但可以满足const和引用成员的初始化要求,还可以避免低效腊腊茄的初始化数据成员。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11990060.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存