c++的精髓之一在指针, 可以做些很多方便的操作. 这里总结一下, 方便以后查看.
1.定义数组可通过指针访问
#define ll long long
//char* data = new char[4 * 1024]; 这里通过new定义的和直接通过数组定义的是一样的
char data[4 * 1024];
printf("0x%llx : %c, %c, %c\n", (ll*)(data),*(ll*)(data), *data, data[0]);
*data = 'a';
printf("0x%llx : %c, %c, %c\n", (ll*)(data),*(ll*)(data), *data, data[0]);
data[0] = '1';
printf("0x%llx : %c, %c, %c\n", (ll*)(data),*(ll*)(data), *data, data[0]);
char* b = data;
printf("0x%llx : %c, %c, %c\n", (ll*)(b), *(ll*)(b), *b, b[0]);
b[1] = 'b';
printf("0x%llx : %c, %c, %s\n", (ll*)(data), *(ll*)(data), *data, data);
printf("0x%llx : %c, %c, %s\n", (ll*)(b), *(ll*)(b), *b, b);
输出:
0x7681afe1a0 : , ,
0x7681afe1a0 : a, a, a
0x7681afe1a0 : 1, 1, 1
0x7681afe1a0 : 1, 1, 1
0x7681afe1a0 : 1, 1, 1b̠ᯁv
0x7681afe1a0 : 1, 1, 1b̠ᯁv
2. 定义的对象/结构体, 可通过指针修改
struct Node {
int m_a;
Node* m_nxt;
Node(int a = 1, Node* nxt = NULL) { m_a = a; m_nxt = nxt; }
};
int main() {
Node* head = new Node();
printf("0x%llx : %d, 0x%lld\n", head, head->m_a, head->m_nxt);
Node* tmp = head;
Node* second = new Node(2, NULL);
printf("0x%llx : %d, 0x%lld\n", second, second->m_a, second->m_nxt);
tmp->m_nxt = second;
printf("0x%llx : %d, 0x%lld\n", head, head->m_a, head->m_nxt);
}
输出
0x1e6b44ba8b0 : 1, 0x0
0x1e6b44ba860 : 2, 0x0
0x1e6b44ba8b0 : 1, 0x2090378963040
3. 参数通过取地址符&进行修改内容
这样,我们就可以在一个新的方法里面, 定义一个新指针去做一些事情了, 定义的一个新的指针变量指向原来的指针指向的地址,操作之后, 原来的变量会受到影响. 等价于在原变量上进行修改.
#include<stdio.h>
long fun(){
int a[2];
a[0] = 1; a[1] = 2;
printf("%lx\n", &a);
printf("%lx, %d, %d, %d\n", a, a[0], a[1], *a);
return a;
}
int main(){
unsigned int *p = fun();
printf("%lx\n", p);
printf("%d, %d\n", p[0], p[1]);
printf("%d, %d\n", *p, *(p + 1));
}
执行输出结果:
7fff62812210
7fff62812210, 1, 2, 1
7fff62812210
1, 2
1, 2
补充说明:
- 这里的unsigned int *p接收int型的地址, 这个int的标识表示之后的地址偏移的计算方式.
- 这里用int符号表示,所以能正确的对应起来, 如果用long符号,那*(p+1)就不会是int的偏移了.
4. 一级指针和二级指针
#include<stdio.h>
int main(){
int a = 1;
int* p = &a;
int **pp = &p;
printf("a: address=0x%llx, value=%d\n", &a, a);
printf("p: address=0x%llx, value=0x%llx|%lld, *p=%d\n", &p, p, p, *p);
printf("pp: address=0x%llx, value=0x%llx|%lld, *pp=%llx|%lld, **pp=%d\n", &pp, pp, pp, *pp, *pp, **pp);
}
执行的输出结果:
[root@localhost System_and_Linux]# gcc tmp.c
[root@localhost System_and_Linux]# ./a.out
a: address=0x7ffc34293b6c, value=1
p: address=0x7ffc34293b60, value=0x7ffc34293b6c|140721183603564, *p=1
pp: address=0x7ffc34293b58, value=0x7ffc34293b60|140721183603552, *pp=7ffc34293b6c|140721183603564, **pp=1
很清晰,二级指针是指针的指针,顾名思义。那么二级指针有什么用呢?
在单链表中,使用二级指针可以指向前驱的后继(本身),这样可以避免删除节点时需要从头遍历寻找前驱节点。
…以后想到什么了会继续补充