突破编程_C++_面试(基础知识(二))

3 面试题3:形参与实参的区别

形参:函数定义时的参数,可以看作是一个占位符。形参只有在被调用的时候才分配内存单元,只在函数内部有效,调用结束后立即释放。
实参:调用函数时使用的参数,实参可以是常量、变量、表达式、函数等。如果实参和形参的类型不匹配,编译器会尝试进行类型转换。如果无法进行类型转换,编译器将会报错。
具体区别如下:
(1)内存分配:形参只有在调用的时候才会分配内存,调用结束后就会释放内存。而实参的情况就比较复杂,比如一个字符串常量的实参,其内存分配在文字常量区。
(2)类型匹配:实参和形参在数量上,类型上,顺序上应严格一致, 如果实参和形参的类型不匹配,编译器会尝试进行类型转换。如果无法进行类型转换,编译器将会报"类型不匹配"的错误。
(3)数据传送:函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。
(4)传递方式:将实参的值传送给形参的方式分为值传递、指针传递、引用传递。值传递时,形参的值发生改变,实参中的值不会变化。指针传递与引用传递时,对形参的改变会影响到实参。
重点注意
指针传递时,如果对其做创建新对象的操作( new ),则实参中的值不会变化(即不会替换为这个新创建的对象),如下为样例代码:

#include 
using namespace std;

class Student
{
public:
	Student(const string& name)
	{
		m_name = name;
	}
	~Student() {}

public:
	string getName()
	{
		return m_name;
	}

private:
	string m_name;
};

void changeName(Student* st, string name)
{
	st = new Student(name);
}

int main()
{
	Student* st = new Student("zhangsan");
	changeName(st, "lisi");
	printf("name = %s\n", st->getName().c_str());

	delete st;
	st = nullptr;
	return 0;
}

上面代码的输出为:

name = zhangsan

这是由于形参 Student* st 与实参 Student* st 实际上还是两个变量,只不过这两个变量指向同一个地址,所以对形参做操作,其操作的对象还是他们共同指向的地址,即为函数外面的 st 对象。但是当对形参做 new 操作以后,形参便指向了新的地址,该函数执行结束后,打印的字符串依然是原来 st 对象的成员变量。

4 面试题4:值传递、指针传递、引用传递的区别

4.1 按值传递

按值传递是将实际参数的值复制到形式参数。使用这种方式,调用函数本身不对实参进行操作。例如:

#include 

//函数的定义
void swap(int a, int b)
{
	int c=a;
	a=b;
	b=c;
}

int main()
{
	int a=1,b=2;
	swap(a,b);				//a,b 交换值失败
	printf("a=%d, b=%d\n",a,b);
	return 0;
}

上面代码的输出为:

a=1, b=2

4.2 按引用传递

按引用传递是将实际参数的地址传递给形式参数,此时的形参相当于实参的别名。使用这种方式,对形参的改变会影响到实参。例如:

#include 

//函数的定义
void swap(int &a, int &b)
{
	int c=a;
	a=b;
	b=c;
}

int main()
{
	int a=1,b=2;
	swap(a,b);				//a,b 交换值成功
	printf("a=%d, b=%d\n",a,b);
	return 0;
}

上面代码的输出为:

a=2, b=1

4.3 按指针传递

按指针传递是指将实参的地址传递给形参,函数内部可以通过指针来操作实参的值。但需要注意指针为空的情况。样例代码如下:

#include 

//函数的定义
void swap(int* a, int* b)
{
	int c=*a;
	*a=*b;
	*b=c;
}

int main()
{
	int a=1,b=2;
	swap(&a,&b);				//a,b 交换值成功
	printf("a=%d, b=%d\n",a,b);
	return 0;
}

上面代码的输出为:

a=2, b=1

需要注意的是:从效率上来说,按引用传递与按指针传递基本一样(按值传递有拷贝过程,性能很差),不过从安全角度出发,引用传递在参数传递过程中执行强类型检查,而指针传递的类型检查较弱,特别的,如果参数被声明为 void ,那么就不会做类型检查。所以推荐只用引用传递,最好不用指针传递。

你可能感兴趣的:(突破编程_C++_面试,c++,面试)