C和C++难知识点,简单记

一、数组指针和指针数组:

独家记忆:可以在这两个名字的中间都加上“的”,即“数组的指针”“指针的数组”。这样就好理解了,因为“数组的指针”,那肯定是一个指针,指向了一个数组;而“指针的数组”,就是一个数组,而数组中的元素的类型就是指针。

例子:区分  int *p1[10]   和   int (*p2)[10];

分析:第一个int 后面直接有*,所以它是一个指针,是一个指向了一个数组的指针,所以是“数组的指针”,即数组指针。

第二个int后面没有直接的*,所以它是一个数组,而这个数组中存放的是指针,所以是“指针的数组”,即指针数组。(如果进一步探究,每个元素即指针的类型,则可以由int得到指针是整型指针)


难点:第一种不可以进行加以操作,即不存在p1++。原因是p1不是元素的名字。而第二种可以进行加一操作,即存在p2++,原因是p2可以看成是指向第一个元素的指针。

二、函数指针和指针函数:

独家记忆:都加上一个“的”,变成“函数的指针”和“指针的函数”,“函数的指针”比较好理解,就是一个指针指向了一个函数;“指针的函数”就要换一种说法,再加几个字变成“返回值是指针的函数”,这样就好理解了。

例子:int *f(int,int)int (*f)(int, int)

分析:第一个函数名是f,返回值是int*,也就是返回值是一个指针,所以是返回值是指针的函数,即指针函数。

第二个*f是指针,这个指针是一个函数的指针,这个函数参数是两个int,返回值是int,所以是函数的指针,即函数指针。


三、指针常量和常量指针:

独家记忆:都加上一个“的”,变成“指针的常量和“常量的指针”,“指针的常量”也不是很好理解,再加两个字“指针修饰的常量”,这样就好理解了,它是一个常量,这个常量用指针修饰。“常量的指针”也就是“指向常量的指针”。

例子: int const* pconst int* pint* const p

分析:这个相对简单一点,先不用管int的位置,只需要把const翻译成常量,然后按照const和*的顺序从左向右读出来即可。比方说,第一个:整型常量指针;第二个,常量整型指针;第三个,整型指针常量。

难点:

//-------常量指针-------
	const int *p1 = &a;
	a = 300;     //OK,仍然可以通过原来的声明修改值,
	//*p1 = 56;  //Error,*p1是const int的,不可修改,即常量指针不可修改其指向地址
	p1 = &b;     //OK,指针还可以指向别处,因为指针只是个变量,可以随意指向;

//-------指针常量-------//
	int*  const p2 = &a;
	a = 500;     //OK,仍然可以通过原来的声明修改值,
	*p2 = 400;   //OK,指针是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化
	//p2 = &b;     //Error,因为p2是const 指针,因此不能改变p2指向的内容

//-------指向常量的常量指针-------//
	const int* const p3 = &a;
	//*p3 = 1;    //Error
	//p3 = &b;    //Error
	a = 5000;    //OK,仍然可以通过原来的声明修改值

四、空指针,野指针和内存泄露:

独家记忆:空指针就是保存地址为空的指针,使用指针时必须先判断是否空指针,很多问题都是这一步导致的。野指针是在delete掉指针之后,没有置0,导致指针随意指向了一个内存地址,如果继续使用,会造成不可预知的内存错误。

//-------空指针-------//
	int *p4 = NULL;
	//printf("%d",*p4); //运行Error,使用指针时必须先判断是否空指针
	
//-------野指针(悬浮、迷途指针)-------//
	int *p5 = new int(5);
	delete p5;
	p5 = NULL; //一定要有这一步
	printf("%d", *p5);  //隐藏bug,delete掉指针后一定要置0,不然指针指向位置不可控,运行中可导致系统挂掉
	
//-------指针的内存泄漏-------//
	int *p6 = new int(6);
	p6 = new int(7); //p6原本指向的那块内存尚未释放,结果p6又指向了别处,原来new的内存无法访问,也无法delete了,造成memory leak

五、数组和指针的区别:

1、数组要么在静态存储区被创建(如全局数组),要么在上被创建。指针可以随时指向任意类型的内存块
2、数组对应着一块内存区域,而指针是指向一块内存区域。其地址和容量在生命期里不会改变,只有数组的内容可以改变;而指针却不同,它指向的内存区域的大小可以随时改变,而且当指针指向常量字符串时,它的内容是不可以被修改的,否则在运行时会报错。 
3、用运算符sizeof可以计算出数组的容量(字节数),而用sizeof却无法计算指针所指内存的容量,用sizeof(p)得到的结果永远是4或者2(即指针变量所占内存单元的字节数,一般情况下指针变量占2个或4个字节的内存单元)。在进行参数传递时,数组会自动退化为同类型的指针。

六、指针和引用的区别:

1、 引用必须被初始化,指针不必。
2、引用初始化以后不能被改变,指针可以改变所指的对象。
3、不存在指向空值的引用,但是存在指向空值的指针。

七、结构体和联合的区别:

1、结构和联合都是由多个不同的数据类型成员组成但在任何同一时刻联合中只存放了一个被选中的成员(所有成员共用一块地址空间)而结构的所有成员都存在(不同成员的存放地址不同)。 
2、 对于联合的不同成员赋值将会对其它成员重写原来成员的值就不存在了而对于结构的不同成员赋值是互不影响的。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值