malloc函数的使用,c++“&”引用的用法,以及“*&”是什么意思

............接着上节初始化问题

1.malloc函数的使用:

不知道有没有同学会想,为什么要用mallc初始化,直接用别的变量的地址来初始化它不就好了。

那么不知道你有没有想过,那别的变量哪里啊?难道需要指针的时候先申请一个普通变量,然后再拿来初始化指针?

上章我们讲malloc可以用来初始化指针,它也可以用来动态申请空间,需要指针的时候先申请一个同类型的变量多不方便,

当然是需要多少直接申请多少好啊,所以当你需要更新的指针(或者为指针申请空间)的时候就可以用malloc函数。

我们拿比较常见的带有头节点的单连边解释一下:

#include<iostream>
#include<cstring>
using namespace std;
struct node{
	int data;
	struct node *next; 
};
int main()
{
	node *head,*q;
	head=(node*)malloc(sizeof(node));//申请头部节点 
	head->data=0;
	head->next=NULL;//为next域指向空 
	q=head;
	int  n=0;
	scanf("%d",&n);
	while(n--){
		int temp=0;;
		scanf("%d",&temp);
		node *p=(node*)malloc(sizeof(node));//更新指针地址,分配新的空间 
		p->data=temp;
		p->next=NULL;
		q->next=p;//主要算法区 
		q=p;// 主要算法区 
	}
	node *t=head->next;
	while(t!=NULL){
		printf("%d\n",t->data);
		t=t->next;
	}
} 
 

作者也尝试不用malloc,而是采用需要时,先申请一个node型常变量(我们在这里指的是非指针变量),然后再用指针指向它,

发现并不可行。因为在while循环区域内,每次申请的node常变量的地址都是统一个地方,这就使得计算机一直没有为新变量

分配新的区域,那么在进行下来的算法操作的时候,q->next一直指向同一个地址。这里希望读者能够自行测试一遍,以验证其

是否可行。

2.c++ "&"引用符号的用法

初学c指针的时候,老师一定会讲这么一个函数:

void swap(int *a,int *b){
	int temp;
	temp=*a;
	*a=*b;
	*b=temp;
}

老师会说,我们如果在函数参数中定义普通变量,即int a,int b,那么传进来的参数是不会进行交换的,但是定义为指针就可以。

我们都知道函数的生命周期,在函数调用结束后,其内部申请的变量即会销毁。

变量被销毁了,函数又没有返回值,自然不会进行数值交换

有些同学可能会下意识的认为常变量会被销毁(至少我曾经这样认为哈),而指针变量不会。

当然这种想法是严重错误的,指针变量同样会被销毁,没有被销毁的什么呢?!

地址!

这就是指针的思想,指针是通过地址来对那个空间上的值进行操作的,而普通变量直接对应的是空间上的值

我们想一下,上面这个swap函数,调用的时候,传进来的是什么?

	int i=3,j=9;
	swap(&i,&j);
	printf("i:%d j:%d\n",i,j);

没错,是地址!,如果你还是不很懂,那么我想一下,函数调用的每一步是怎么实现的。

假如我们使用的是下面这组

程序1:

void swap(int a,int b){
	int t=a;
	a=b;
	b=t;
}
int main(){
	int i=3,j=9;
	swap(i,j);
	printf("i:%d   j:%d",i,j);
	return 0;
}
 

main函数讲i = 3,j = 9传入swap函数,swap函数声明了两个变量,并将a初始化为3,b初始化为9,下来进行了交换操作,

当然我们最后输出的i  ,   j   结果并没有交换。我们可以把这个函数写在函数里面看看,不知道会不会帮助你理解。

程序2:

int main(){
	int i=3,j=9;
//	swap(i,j);
	{
		int a=i,b=j;
		int t=a;
		a=b;
		b=t;
	}
	printf("i:%d   j:%d",i,j);
	return 0;
}

这两个程序执行的过程差不多是一样的,

不过swap函数中定义的变量在函数调用结束后就销毁了,

而程序2中的变量要在程序结束后才销毁。

 

然后我们再看传地址的swap程序:

void swap(int *a,int *b){
	int temp;
	temp=*a;
	*a=*b;
	*b=temp;
}
int main(){
	int i=3,j=9;
	swap(&i,&j);
	printf("i:%d   j:%d\n",i,j);
	return 0;
} 

 地址是存在计算机当中的,自然是不会被销毁,指针是通过这些地址进行的操作,所以传的是地址的时候

函数中的指针也是对这个地址上的值进行操作,地址对应空间上的值是不会随函数中指针的销毁而销毁的。

 

讲到这里你应该对函数传参有了一定的了解,现在我们在考虑c++ '& '引用的用法

引用是什么意思,我想大家应该都有一定了解,简单的说就是为变量赋了一个新的名字:

int a;       ->

                       &a (a的地址)->    num( a对应的值)

int &b=a;->  

下面给个简单示例:

 int main()
 {
 	int a=9;
 	int &b=a;
 	printf("%d\n",b);
 	return 0;
 }

不知道有没有同学会想,这不就是两个变量名,指向同一个地址嘛,那我用指针不就可以了

确实,很多时候,引用确实可以用指针来代替

但是,当引用变量所指的地址发生改变的时候就不可以用简单的指针来代替了

 举个简单,且常见的例子:

程序1:

 void change(int *p){
 	printf("传进来的地址:%p\n",p);
 	p=(int *)malloc(sizeof(int));
 	printf("malloc更新后:%p\n",p);
 }
 int main(){
 	int a=9;
 	int *q;
 	q=&a;
 	printf("未传时地址:%p\n",q);
 	change(q);
 	printf("传出后地址:%p\n",q);
 	return 0;
 }

运行结果如下:

很明显,我们看到,只有在malloc更新时,函数内的指针地址发生了变化,但并没有将更新后的地址带出change函数。

因为函数内声明的指针已经随着函数调用的结束销毁了,malloc更新的是函数内p的指针地址,而不是传进去的q的地址。

 

如果我们用引用传递呢?我们只需要在函数声明的时候,在变量名前加上&

程序2:

 void change(int *&p){
 	printf("传进来的地址:%p\n",p);
 	p=(int *)malloc(sizeof(int));
 	printf("malloc更新后:%p\n",p);
 }

运行结果如下:

我们发现,奇妙的,更新后的地址随着函数调用结束也带了出来!

这就是引用的妙用了,引用声明的变量名可以和用来对进行它初始化的变量当作同一个变量使用。

在程序2中,我们可以看作一直在对同一个变量进行操作;

而程序1,我们是在对两个变量进行操作。

不知道您是否理解了呢?

 

3.”   *&   “这是什么意思呢?

我第一次看到这个符号也是很蒙逼,以为是什么没学过的东西,其实还是引用变量,不过是一个指针类型的,仅此而已,哈哈。

 int main()
 {
 	int &a;指向整型引用 
 	double &b;指向浮点型引用 
 	struct node &c;指向结构体类型引用 
 	
 	int *&p;指向整型指针的引用 
 	struct node *&q;指向结构体指针的引用 
 }
 

能力有限,若有错误或者不足的地方,望大家指出,谢谢!

 

 

 

 

 

 

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 对于您的问题,我可以回答。C++ 中的 new 操作符底层实现是使用 malloc 函数来实现的,但 new 操作符还会进行一些额外的工作,如调用构造函数,对于内置类型和非内置类型, new 操作符的行为也有所不同。需要注意的是,对于内存分配和释放,应该始终使用匹配的 new 和 delete 操作符。 ### 回答2: C语言中的`new`操作符并不是标准C语言的一部分,它通常是C++语言中用来申请动态内存的运算符。在C++中,`new`操作符在底层使用的是由C++标准库提供的`malloc`函数来实现动态内存的申请。 虽然`new`操作符和`malloc`函数都可以用来申请动态内存,但它们的行为有一些不同之处。其中一个主要区别是`new`操作符可以自动调用对象的构造函数,而`malloc`函数仅仅是分配内存而已,不会执行构造函数。另外,`new`操作符还可以根据需要动态调整分配的内存大小,并且在内存不足时抛出`std::bad_alloc`异常。 当使用`new`操作符申请内存时,它首先会根据所需的内存大小调用全局的`operator new`函数(也是由C++标准库提供),然后再在分配的内存区域上调用对象的构造函数。因此,`new`操作符底层使用的是`malloc`函数来分配内存,然后再调用构造函数。 需要注意的是,在C语言中使用`malloc`函数分配内存时,不会自动调用构造函数。如果要在C语言中模拟`new`操作符的功能,需要手动调用构造函数来初始化对象。 ### 回答3: 在C语言中,使用new操作符进行内存分配时,并非底层使用malloc函数来实现的。事实上,new操作符是C++语言中用于动态分配内存的关键字,而不是C语言中的关键字。 在C语言中,我们通常使用malloc函数来进行动态内存分配。这个函数用于在堆内存(heap)中分配一块指定大小的内存空间,并返回一个void类型的指针。malloc函数的底层实现是由C标准库提供的。 C++语言中的new操作符与C语言的malloc函数类似,用于动态分配内存。但与malloc函数不同的是,new操作符在底层实现时会调用malloc函数来获取内存空间。此后,new操作符还会调用构造函数来初始化分配的内存。 总结来说,C语言中使用malloc函数进行内存分配,而C++语言中使用new操作符进行内存分配。虽然new操作符在底层实现时使用malloc函数,但从语法和用法上来看,它们是不同的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值