程序员成长之旅——引用和指针

程序员成长之旅——引用和指针

指针和引用有什么区别
(1)初始化要求不同。引用在创建的同时必须初始化,而指针在定义的时候不必初始化,可以在定义后面重新赋值。
(2)可修改性不同。引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用;而指针可以。
(3)不存在NULL引用,引用不能使用指向NULL的引用,它必须是指向某个对象,而指针可以,因此指针更加灵活,当然也容易出错。
(4)测试需要的区别。由于引用不会指向空值,这意味着在使用引用之前不需要测试它的合法性;而指针则需要经常进行测试。因此引用的代码效率要比指针高。
(5)应用的区别。如果指一旦指向一个对象后就不会改变指向,那么使用引用。如果有存在指向NULL或在不同时刻指向不同对象的需求,则使用指针。

为什么传引用比传指针安全
由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用安全。
对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全,const指针仍然存在空指针,并且有可能产生野指针。
指针比较

#include<iostream>
using namespace std;

int main()
{
	char str1[] = "abc";
	char str2[] = "abc";
	const char str3[] = "abc";
	const char str4[] = "abc";
	const char* str5 = "abc";
	const char* str6 = "abc";
	char* str1 = "abc";
	char* str2 = "abc";
}

数组str1、str2、str3、str4都是在栈中分配的,内存中的内容都为"abc"加一个’\0’,但是它们的位置是不同的。
指针str5、str6、str7、str8也是在栈中分配的,它们都指向"abc"字符串,注意"abc"存放在数据区,所以它们指向同一块数据区的内存。
看代码找错误(内存访问违规)

#include<iostream>
using namespace std;

int main()
{
	char a;
	char *str1 = &a;
	char* str2 = "AAA";

	strcpy(str1,"hello");
	cout << str1 << endl;
	str2[0] = 'B';
	cout << str2 << endl;
	return 0;
}

str1指向一个字节大小的内存区。由于复制"hello"字符串最少需要6个字节,显然内存大小不够。因此会因为越界进行内存读写而导致程序崩溃。
str2指向"AAA"这个字符串常量。因为是常量,所以对str2[0]的赋值操作是不合法的,也会导致程序崩溃。
指针常量与常量指针的区别
常量指针就是指向常量的指针,它所指向的地址的内容是不可修改的。
指针常量就是指针的常量,它是不可以改变地址的指针,但是它指向的内容是可以修改的。
指针的区别

char* const p1;
char const* p2;
const char *p3;
const char* const p4;

如果const位于号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于
号的右侧,const就是修饰指针本身,即指针本身是常量。

p1是指针常量,它本身不能被修改,指向的内容可以被修改。
p2和p3是常量指针,它本身可以被修改,指向的内容不可以被修改。
p4本身是常量,并且它指向的内容也不可被修改。
this指针的正确叙述
下列关于this指针的叙述中,正确的是(D)
A.任何与类相关的函数都有this指针
B.类的成员函数都有this指针
C.类的友元函数都有this指针
D.类的非静态成员函数才有this指针

A错误。类的非静态成员函数是属于类的对象,含有this指针。而类的static函数属于类本身,不含this指针。
static叫静态方法,也叫类方法,就是在程序启动的时候,就会为这个方法分配一块内存空间,所以什么时候都可以调用这个方法。
没有static的其他方法,非静态方法,必须在类实例化时,才有内存空间,所以在类实例化之前是无法调用的。
所以,静态方法里不能调用非静态方法,除非你先实例化那个类。
什么是野指针
野指针不是NULL指针,而是指向“垃圾”内存的指针。
(1)指针的变量没有初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的默认值是随机的,它会乱指一气。所以,指针变量在创建的同时应该被初识化,要么将它指向NULL,要么让他指向合法的内存。
(2)指针p被free或者delete之后,没有置为NULL,让人误以为p是一个合法的指针。
有了malloc/free,为什么还要new/delete
对于非内部数据类型的对象而言,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数不是运算符,不在编译器控制权限之内,不能把执行构造函数和析构函数的任务强加于malloc/free,因此只有使用new/delete运算符。
各种内存分配和释放的函数的联系和区别
malloc的调用形式是(类型*)malloc(size):在内存的动态存储区中分配一块长度为size字节的连续区域,返回该区域的首地址,此时内存的值没有被初始化,是个随机数。
calloc的调用形式是(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为size字节的连续区域,返回首地址,此时内存的值都被初始化为0。
realloc的调用形式为(类型*)realloc(ptr,size):将ptr内存大小增大到size,新增加的内存块没有初始化。
free的调用形式为free(void
ptr):释放ptr所指向的一块内存空间。
C++中,new/delete函数可以调用构造函数和析构函数。
内存的分配方式有几种
(1)从静态存储区域分配。内存在程序编译的时候已经分配好,这块内存在程序的整个运行期间都存在,例如全局变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元自动释放。处理器的指令集中有关于栈内存的分配运算,因此效率很高,但是分配的内存容量有限。
(3)从堆上分配,也称为动态内存分配。程序在运行的时候用malloc或new申请任意多大的内存,程序员自己负责用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从零出发——

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值