C++修改参数和变量的方式

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

很清晰,二级指针是指针的指针,顾名思义。那么二级指针有什么用呢?
在单链表中,使用二级指针可以指向前驱的后继(本身),这样可以避免删除节点时需要从头遍历寻找前驱节点。

…以后想到什么了会继续补充

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值