C语言 - 指针 | 多级指针 | 指针作参

指针

1 -  字节是最⼩的存储单元,为了正确访问内存单元系统会使每个内存单元都有一个编号,这个编号称作地址。指针就是内存地址,习惯上把内存地址叫做指针。存放内存地址的变量称为指针变量。指针变量所占的字节数跟指针变量的类型无关,它是跟系统位数有关:32 位下占 4 字节;64 位下占 8 字节

:指针变量只有加减运算并且在运算时指针类型决定着指针变量所移动的字节数

2 - 如果出现 * 的地方前面有类型修饰符,此时 * 仅仅是修饰作用,告诉编译器:老子是一个指针;如果出现 * 的地方前面没有类型修饰符,此时 * 代表取值操作符,会把指针指向区域中的内容取出来

int a = 10; // 这是一个变量
int *p;     // 这是一个指针
*p;         // 取值:访问指针变量 p 指向的存储空间
p = &a;     // 指针变量 p 指向了变量 a 的地址
*p = 20;    // 使用指针修改变量 a 的值

3 - 代码示例

① 交换两个变量的值:指针用作参数

复制代码
 1 #include <stdio.h>
 2 void change(int *a,int *b){
 3     
 4     int temp = 0;
 5     temp = *a;
 6     *a = *b;
 7     *b = temp;
 8 }
 9 
10 int main(int argc, const char * argv[]) {
11     
12     int a = 100;
13     int b = 200;
14     printf("交换前:\na = %d b = %d\n", a,b);
15     change(&a, &b);
16     printf("交换后:\na = %d b = %d\n", a,b);
17     
18     return 0;
19 }
复制代码

② 使用指针可以实现让一个函数处理多个值。如下函数不仅返回了两数之和,还能够得到两数之差

复制代码
 1 #include <stdio.h>
 2 
 3 int SumAndMinus(int n1,int n2,int *n3){
 4     
 5     *n3 = n1-n2;
 6     return n1+n2;
 7 }
 8 
 9 int main(int argc, const char *argv[]) {
10     
11     int a = 10;
12     int b = 11;
13     int sum;  //
14     int minus;//
15     
16     sum = SumAndMinus(a,b,&minus);// 把地址作为参数传出
17     printf("和 = %d,差 = %d\n",sum,minus);
18     
19     return 0;
20 }
复制代码

4 - 指针变量只能存储地址,而不是具体值

int *p2;
p2 = 200;// 错误

5 - 野指针:指针变量未经初始化就不要拿来间接访问它的存储空间

int *p3; // 未初始化的指针
printf("%p\n",*p3);// crash
int *p1;// 你当然可以这样搞,不过很危险
int d = 10.0;
p1 = &d;  
// 改正 
int *p1 = &d;
int d = 10;
int *p4 = &d;// &*p 和 &d 等价;  *&d 和 d 等价

多级指针

1 - 其实就是指向指针的指针的指针的指针......

① 先看一段代码

int a = 10;
int *p = &a;    // 一级指针:p 就是个指针
int **p1 = &p;  // 二级指针:p1 是指向 p 指针的指针
int ***p2 = &p1;// 三级指针:p2 是指向 p1 指针的指针

说明:*p 访问 a;  *p1 访问 p;  *p2 访问 p1

② * p1   相当于访问指针变量 p,而 ** p1 相当于访问 a

    ** p2 相当于访问指针变量 p,而 *** p2 相当于访问 a

  注:n 级指针需要 n 个 * 才能访问到最终的内存地址      

 ③ int **p 可以把它分为两部分看:int* 和  *p。 *p 中的 * 表示 p 是一个指针变量,int* 表示指针变量 p 只能存放 int* 型变量地址

     对于二级指针甚至多级指针都可以把它拆成两部分,不论它是几级指针它实质上就是一个指针变量,指针变量就是一个 *,其余的 * 表示的是这个指针变量只能存放什么类型变量的地址。比如 int ****a 表示指针变量 a 只能存放 int*** 型变量地址

值传递 | 地址传递

1 - 代码示例

复制代码
 1 #include <stdio.h>
 2 
 3 // 值传递
 4 void newValue(int a){
 5     
 6     a++;// 形参发生变化
 7 }
 8 
 9 // 地址传递
10 void test_str(char s[]){
11     
12     s[0] ='w';// 形参指向的是实参的地址
13 }
14 
15 int main(int argc, const char * argv[]) {
16     
17     int x = 555;
18     newValue(x);
19     printf("%d\n",x);// 555  实参不会发生变化
20     
21     char c[] = "me";
22     test_str(c);// 传入地址
23     printf("%s\n",c);// we   实参发生变化
24     
25     return 0;
26 }
复制代码

指针类型

1 - 任何类型的指针都只和系统位数有关,那么为什么还要为指针加上类型呢。对下面一段代码进行内存分析就可以大致了解到因指针类型不正确而带来的严重后果

1 int i = 2;
2 char c = 1;
3 int *p = &c;// int 型指针指向 char 型变量地址
4 printf("%d\n",*p); // 513
5 printf("%d\n",c);  // 1 

指针 p 访问的本应该是 1 个字节空间的数据,但因指针类型是 int,所以程序自然地从指向地址 0x0a 开始读取 4 个字节的数据,访问的数据从 1 变成了 513

posted on   低头捡石頭  阅读(23)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示