您的位置:首页 > 编程语言 > C语言/C++

[C++学习]剑指offer13题的学习笔记

2017-02-27 21:31 232 查看
问题描述:用O(1)时间删除链表中的指定结点。

  下面是学习遇到的困惑和解决方法:

1.  如何去引用结构体中的成员。

首先定义了一个结构体:

struct ListNode{int m_nValue;ListNode* m_pNext;};

利用->和.去引用结构体中的成员:

ListNode* p=new ListNode;
p->m_nValue = i;
p->m_pNext = NULL;

ListNode p;
p.m_nValue = i;
p.m_pNext = NULL;

其中“->“用于指针类型的类的实例,而“.“用于普通对象(非指针类型)的引用。

两者最大的区别是->前面放的是指针,而.前面跟的是结构体变量

例如:

struct A
{
int a;
int b;
};
A *point =malloc(sizeof(struct A));
cout<<point->a<<endl;//输出1
A object;
cout<<object.a <<endl;//输出1


2.  题目给出的函数是 voidDeleteNode(ListNode** pListHead,ListNode* pToBeDeleted);**代表指向指针的指针,该如何认识它?

参考文章(让你不再害怕指针——C指针详解(经典,非常详细))

将函数的传参写出:

ListNode** pListHead=& pNode1;
&: &a的运算结果是一个指针,指针的类型是a的类型加个*

*:*p简而言之是p所指向的东西。

了解指针需要了解指针的四个内容:

a.指针的类型:把指针的名字去掉

b.指针所指向的类型:去掉指针的名字+名字左边的*

c.指针本身所占的内存区

d.指针所指的内存区:

因此,可以看出ListNode是指向pNode1的指针的指针,也相当于:

ListNode* pListHead =pNode1;但前者在引用值:

(*pListHead)->m_nValue。后者在引用值:pListHead->m_nValue。

3. 为什么要指针和值分别赋值?不用直接将结点赋值?也就是说

pToBeDeleted->m_nValue =pToBeDeleted->m_pNext->m_nValue;
                                        pToBeDeleted->m_pNext =pToBeDeleted->m_pNext->m_pNext;
                                       //pToBeDeleted = pToBeDeleted->m_pNext;//为什么分开赋值可以成功,但是直接赋值就不可以?
我想应该函数值传参的原因,直接赋值,其实是把pToBeDelete转换到了next上,对实际的list未能产生影响。而逐个赋值涉及到了指针,由此改变了list

学习C++primer函数传参那节可以解决这个困惑。函数的参数传递分为两类,一是值传递,二是引用传递。值传递是对变量的改动,并不会改变实参值;而引用传递与变量初始化的机理一致,其实是一个对象的别名,可以通过改变其引用来改变实参值。通过下面的例子去理解它:

void reset(int *ip){	*ip = 0; //改变了指针ip所指对象的值	ip = 0;//ip的指向改变}reset(&i);//改变的是i的值,而非i的地址int i = 42;cout << i << endl; //输出为0
int* ip=&i;将ip指向i 
void reset(int &ip)
{
ip = 0;
}
int i = 42;
reset(i);//改变的是i的值,而非i的地址
cout << i << endl; //输出为0
int& ip=i;其实ip是i的别名,可以通过改变ip来改变i。
返回问题中来pToBeDeleted = pToBeDeleted->m_pNext;改变了形参所指的对象,未能对实参产生影响。pToBeDeleted->m_nValue =pToBeDeleted->m_pNext->m_nValue;改变了形参所指对象的值。

4.书上的参考答案为什么必须删除下个结点?

我试了一下不删除结点也对,没有报错。可能涉及到了空间释放、安全等问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: