C[7] 指针(pointer)

C[7] 指针(pointer)

1、概念

对于指针的描述,很多资料描述的摸棱两可,理解起来过于的复杂,这里加上自己对指针概念的理解,

指针(pointer)是指向对象变量的内存地址,是内存地址,是变量的内存地址,是函数的入口地址。计算机按变量的地址取出其内容,并按变量的地址将计算结果存入到变量占据的内存中。

指针变量 是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。 
指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。

这里重点理解一下:指针即指向的变量和指针变量,两个概念。

2、示例:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
 
int main()
{
    //滔Roy 2021.11.05
    //测试环境:win10 64
    int i = 10;  //编译器为i分配一个变量地址,这个变量地址代表一个存储空间,空间中存储的数据的类型是int ,存储空间写入变量的值10
    int *p;   // 定义指针   Delphi写法: var p:^Interger; 
    p = &i;   // 将i的内存地址分配给指针变量p    Delphi写法:p:=@i
    //以上两句,也可以写成: int *p=&i;
 
    //16 进制输出
    printf("i 变量的值: %p\n", i);       //000000000000000A      //i的内存值
    printf("i 变量的地址: %p\n", &i);    //000000000061FE1C      //i的内存值地址,这个地址根据系统运行分配可能不一样,它仅代表分配的一个内存地址        printf("i 变量的地址: %x\n", &i);   //61fe14     //i的内存值地址
    printf("p 变量的值: %p\n", p);       //000000000061FE1C      //p变量的值指向(等于)i的内存值地址
    printf("p 变量的地址: %p\n", &p);    //000000000061FE10      //p变量也有一个内存值地址 , 这个一般不用,不用理会,只是输出对比
    printf("p 变量的指针值*p: %p\n", *p);//000000000000000A      //p变量的指针值等于i的值,  即*p等同于i
 
    //10 进制输出
    printf("i 变量的值: %d\n", i);      //10 = A (16进制)         //i存储空间的值=10
    printf("i 变量的地址: %d\n", &i);   //6422044 = 61FE1C
    printf("p 变量的值: %d\n", p);      //6422044 = 61FE1C         //p存储空间的值是 i的变量地址
    printf("p 变量的地址: %d\n", &p);   //6422032 = 61FE10
    printf("p 变量的指针值: %d\n", *p);   //10 = A
 
    *p=*p+1;   //改变指针的值,即改变了i的值
    printf("*p 变量的值: %d\n", *p);   //11
    printf("i 变量的值: %d\n", i);     //11
    printf("p 变量的值: %d\n", p);     //6422044 = 61FE1C    指针变量的值不变
 
    i=i+1;  //改变i的值,指针的值也改变,因为指针指向了这个地址,这个地址的值改变,它也改变
    printf("i 变量的值: %d\n", i);     //12
    printf("*p 变量的值: %d\n", *p);   //12
    printf("p 变量的值: %d\n", p);     //6422044 = 61FE1C    指针变量的值不变
 
    p=p+1;
    printf("p 变量的值: %d\n", p);   //6422048=61FE20      //指针变量的值改变
    printf("i 变量的值: %d\n", i);   //12                  //改变指针变量的值,不会改变i的值,因为指针变量存储的是变量的地址。
    printf("*p 变量的值: %d\n", *p);   //12854240  //改变指针变量,即指针的值也改变. 应该是个随机值,每次运行都一样 ,也可能是 0
 
    //sizeof()  返回变量的大小。 注意:C语言中的sizeof() 不是函数,相当于运算符。
    printf("i 变量的大小: %d\n", sizeof(i));   //4   i是int类型,值占用4个字节
    printf("i 变量的大小: %d\n", sizeof(&i));  //8
 
    printf("p 变量的大小: %d\n", sizeof(p));    //8  //同一CPU下,不同类型的指针变量所占用的存储单元长度是相同的
    printf("*p 变量的大小: %d\n", sizeof(*p));  //4   指针指向i的值,大小与i一致。存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。
    printf("&p 变量的大小: %d\n", sizeof(&p));  //8
 
}  

3、空指针和判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
int main()
{
// 滔Roy 2021.11.05
    int *p;  p=NULL;  //可以写成: int *p=NULL;    //指针设置成空值,不会改变原来指针变量p的内存地址
 
    printf("p 的地址是 %p\n", p );  //0000000000000000
    printf("*p 指针的大小 %d \n", sizeof(*p));  //4
    printf("p 变量的大小 %d \n", sizeof(p));   //8
 
    if (p)   //注意:这里的判断相当于 p是否等于1 ,即不为空,  如果是: if (!p)  即不等于1 ,即为0 ,即为空
    {
        printf("p指针不为空");
    } else
    {
        printf("p指针为空");
    }
}

 

 

 

 

创建时间:2021.11.04  更新时间:

posted on   滔Roy  阅读(858)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报

导航

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