一.问题解释
我们定义一个指针后,指针的内存大小为8个字节(64x)(在32x中指针为4字节),定义的这个指针会优先存放在栈内存中,而指针解引用的数据真实值存放在堆内存中。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
(这就是类似数组等数据结构的指针会指向头节点的原理)
我们在传输参数时,因为C++/C语言是进行值传递的语言,所以,CPU在收到指令后发出信号,常量区的要传参的值进行拷贝出它的地址,然后把地址值从常量区传到栈帧(栈帧(stack frame)是在程序执行过程中用于管理函数调用和返回的一种数据结构。它通常存储在栈(stack)中,而不是代码区(code segment)。)中的函数参数内,再在函数内进行解引用,获取堆内的真实值。
同时这里引申出一个问题就是值传递和引用传递(指针传递)的区别:
值传递是在函数的传参数时,把要传的参数拷贝一份然后再,传到函数体中,但是这个过程因为要进行拷贝所以,传送大内存数据的时候会降低效率。但是在函数体内进行修改拷贝后数据类型中的数据,原函数中的数据不会被修改。
然而,我们在传输指针的时候,只需要拷贝地址,就可以快速传输,同时修改函数内的数据,可以使原函数中的数据修改。
二.删除链表中的所有值为x的节点
具体代码:
#include<iostream>
using namespace std;
typedef struct Node
{
char ch;
Node* next;
}*LinkList, node;
void initList(LinkList* head)
{
(*head) = new node;
(*head)->ch = '\0';
(*head)->next = NULL;
}
void BuildUpNode(LinkList* head)
{
node* p = (*head);
char charecter = '\0';
while (true)
{
node* q = new node;
cout << "Please input charecter : " << endl; cin >> charecter;
if (charecter == '#')
{
break;
}
q->ch = charecter;
p->next = q;
p = q;
p->next = NULL;
}
}
void outputCh(LinkList head)
{
node* p = head->next;
while (p != NULL)
{
cout << p->ch << " "; p = p->next;
}
}
void DelData(LinkList& head, char e)
{
Node* p = head, * tmp;
while (p->next != NULL) //检测 p->next 这个结点的值是否为元素 e
{
if (p->next->ch == e)
{
tmp = p->next;
p->next = tmp->next;
free(tmp);
}
else
p = p->next;
}
}
int main()
{
LinkList head = NULL;
initList(&head);
BuildUpNode(&head);
DelData(head,'x');
outputCh(head);
return 0;
}
图片展示;
void DelData(LinkList& head)
{
Node* pre = head;
Node* p = NULL;
while (pre->next != NULL)
{
if (pre->next->ch == 'x')
{
p = pre->next;
pre->next = p->next;
}
else
{
pre = pre->next;
}
}
}
为了方便控制,我们这里只使用一个指针,指向头节点pre = head,使用pre->next来控制循环的结束,可以防止我们遇到NULL,带来不便。