首先,实现一个简单的队列:
#define Maxsize 100
#define ElemType int
//队列
typedef struct Queue{
ElemType data[Maxsize];
int head,rear;
}Queue;
void InitiateQueue(Queue &s) {
s.head = s.rear = -1;
}
01 用指针写队列的pop和push函数:
void pushQ(Queue *s,int x) {
s->data[++s->rear] = x;
}
void popQ(Queue *s, int& x) {
x = s->data[++s->head] ;
}
对应的调用方法是:
int main() {
Queue qa, * s;
InitiateQueue(qa);
s = &qa; //"&"在这里起到了取地址的作用
int x,y;
for (int i = 0; i < 5; i++) {
scanf_s("%d", &x);
printf("接收到输入x=%d \n",x);
pushQ(s,x); //s是指向[Queue]这个数据结构的指针
}
for (int i = 0; i < 5; i++) {
popQ(s,y); //s是指向[Queue]这个数据结构的指针
printf("现在出队的是:%d", y);
}
}
02 用引用写队列的pop和push函数:
void pushQ(Queue &s,int x) {
s.data[++s.rear] = x;
}
void popQ(Queue &s, int& x) {
x = s.data[++s.head] ;
}
对应的调用方法是:
int main() {
Queue qa, * s;
InitiateQueue(qa);
s = &qa;
int x,y;
for (int i = 0; i < 5; i++) {
scanf_s("%d", &x);
printf("接收到输入x=%d \n",x);
pushQ(qa,x); //qa在这里是一个[Queue]类型的数据
}
for (int i = 0; i < 5; i++) {
popQ(qa,y); //qa在这里是一个[Queue]类型的数据
printf("现在出队的是:%d", y);
}
}
我们来选几句比较一下:
传指针 | void pushQ(Queue *s,int x) | pushQ(s,x); |
传引用 | void pushQ(Queue &s,int x) { | pushQ(qa,x); |
对于pushQ函数,我们希望传进去的队列可以得到修改,并在接下来的程序中使用。所以不能直接传Queue类型变量,因为按相关规定(实际参数与形式参数的关系),这相当于在函数中又创建了一个Queue类型的变量,把我们传进去的Queue类型变量的值赋给了它,修改了这个在只在函数中存在的变量,我们原来的值并没有被改变;
而上述两种方法都可以实现在我们传进去的内容上修改。
第一种,我们给的实际参数是s,一个[Queue]类型的指针;函数中的形式参数也是一个[Queue]类型的指针(为了方便我也起名为s了,姑且在这里叫它s2)。执行函数时,s的值————即我们的[Queue]类型数据qa的地址被从一个指针赋给另一个指针,对队列的所有的操作都是对这个地址完成的。所以即使函数结束,形式参数s2完成使命消逝了,对队列的改变也依然有效。
第二种,我们给的实际参数是qa,一个[Queue]类型的数据(变量),也是我们要修改的内容;函数中的形式参数是一个[Queue]类型的引用&s。参考其他教程知道,引用相当于另起一个名字。执行此函数时,相当于进行了Queue &s=qa;
那这个"&"出现在赋值号左边好像就不是取地址的意思,而是做引用(为什么说好像,因为我也不是很确定...)所以与Queue s = qa本质的区别是,前者的s是qa的别名,对s的任何操作,对qa也同样生效,而后者是把qa的值给赋给s,对s的操作和qa无关。如此,我们需要用前一种来实现对传进去的参数本身的改变。
———————————————————————————————————————————
写这篇文的原因是我老是分不清在函数的定义中为形式参数加*和&,与在调用函数时为实际参数加*和&的区别...经过多番查阅和几轮踩BUG尝试,有了以上体会。作为一名可爱的小白,有理解有误之处,欢迎大家指正。我也会继续学习,有新的认识再回来补充。
(小结:声明变量时用的*表示声明了一个指向对应类型的指针,但如果跟在一个实际存在的变量前面,则表示取这个地址上对应的内容——所以这个变量也必须是指针变量;&用在赋值语句的右边一般表示取地址,取这个变量的地址,而声明变量时在赋值号左边用则表示引用,给这个变量起一个别名。以一个简单的小尝试结束本文:)
int main() {
int a=10;
int* p1; //声明int型指针
p1 = &a; //取int型变量a的地址赋给指针p1
int& b = a; //为a创建了一个别名b
printf("开始时的a: %d\n", a);
*p1 = 20; //将p1所指向处,即a的内容修改为20
printf("*p1 = 20;后的a: %d\n", a);
b = 30; //将别名b的内容修改为30
printf("b = 30;后的a: %d\n", a);
}
/*输出如下:
开始时的a: 10
*p1 = 20;后的a: 20
b = 30;后的a: 30
*/