【C、C++基础】什么时候用 “.” 什么时候用“->”(3个实例搞懂)
从堆栈的角度来说:
从堆栈的角度来说:
对象放在堆上,就要用指针,也就是对象指针->函数;
放在栈上,就对象.函数
那么如何判断对象放在堆上还是栈上?
从我的另一篇笔记【C++ grammar】C++简化内存模型可知:
stack(栈)编译器自动分配内存(函数内部定义得局部变量、形参)
堆(Heap)一般由程序员分配释放
int *p ; char *p;
应该是在栈区分配
如果是这样p=(int *)malloc(sizeof(int))
在C++中则是使用了new
是在堆区
用个具体的例子说明:
假设有一个类: ClassA
1、如果声明的是一个对象: ClassA A
则用 A.function
2、如果声明的是一个对象指针:ClassA* A=new A;
则用 A->function
注意一点:
C++中如果声明一个对象指针时没有分配内存,那么不会调用构造函数
一个指针在内存中也是有内存空间的。
在现在大多数机器上指针都是32位的,也就是4个字节。
如果你声明指针。例如,假设A是一个类A *pa;
这内存中会分配4个字节的空间存储一个地址。只不过地址是不可以用的,因为它没有有效的指向某一个有用的内存空间。这和你声明一个int类型是一样的。int p;
内存中也会分配4个字节空间给p来存储一个整形值,只不过这个整形值不是可用的,或者是垃圾的。
但是对应你说的调用构造函数。其实指的是A *pa=new A;
这个时候,就会调用A的默认构造函数。它会在内存中分配内存,别且把这个有效的内存地址存储到指针变量pa的4个字节空间中。
从指针和对象的角度来说:
从指针和对象的角度来说:
具体实例1:
p是指针,指向Coordinate类型数组中的第一个元素的地址,即首地址
p[0]表示是数组中第一个元素,是以Coordinate类型对象。
对象访问自己的数据成员或者成员函数,必须用 . ;
p指针指向的元素是p[0],属于使用指针访问数据成员和成员函数,应该用->
总结:
如果是指针访问数据成员或成员函数,用->;
如果是某个数据类型的对象,访问自己的数据成员和成员函数用 . ;
进阶实例2:leetcode 206
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head ==NULL || head->next == NULL)
{
return head;
}
ListNode* cur = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return cur;
}
};
head->next->next = head;
head的类型是指针,所以引用的时候用->;
head->next的类型也是指针,所以引用的时候也用的->;
进进阶实例3:实现一个链队列
再来最后一个例子,实现一个链队列
具体可以先看一下我的另一篇笔记:
【数据结构基础笔记】【队列】
typedef char ElemType ;
//队列元素类,队列中的每个元素都是QNode类
typedef struct QNode{
ElemType data; //队列结点的数据域
struct QNode* next; //队列结点的指针域
}QNode, *QueuePtr;
typedef struct {
QueuePtr front; //队头指针,用来存放队头元素的地址
QueuePtr rear; //队尾指针,用来存放队尾元素的地址
}LinkQueue;
//这里定义得队列是一个链队列,队列之间的元素由指针相连,所以只要掌握了队列的队头指针和队尾指针,就可以对队列进行各种
再看下面代码,注意q对成员的引用方式
//创建一个空队列
void InitQueue(LinkQueue* q)
{
q->front = q->rear = (QueuePtr)malloc(sizeof(QNode)); //初始化一个队列指针大小的空间,并将地址传给头指针和尾指针
if (!q->front)
{
printf("内存分配失败");
exit(0);
}
q->front->next = NULL; //头结点指针域指向空
}
q是指向LinkQueue类型数据的指针;
LinkQueue类型数据有两个成员front、rear,都是QueuePtr 类型的数据。
QueuePtr是指向QNode类型数据的指针。
q->front,属于指针访问LinkQueue类型数据的成员,所以使用->
q->front->next,q->front属于QueuePtr 类型,是指向QNode数据类型的指针,且next是QNode类型的数据对象。
所以q->front与next之间使用 - >;
感觉自己把自己讲懂了[doge]