C语言学习记录——십팔 初始指针(1)

目录

一、指针是什么?

二、指针类型

第一个意义

第二个意义

野指针


一、指针是什么?

指针是一种特殊的数据类型,用于存储变量的内存地址。它们允许直接访问和操作存储在该地址上的数据。指针本身也有自己的内存地址,因为它们也是变量,但它们存储的是另一个变量的地址。

定义指针的方法是在类型前面加上*符号。例如,int* ptr声明了一个指向整数类型的指针变量。

#include <stdio.h>

int main()
{
    int a = 10;//在内存中开辟一块空间
    int* p = &a;//这里我们队变量a,取出它的地址,可以使用&操作符。将a的地址存放在p变量中,p就是一个指针变量
    return 0;
}

指针变量是一个用于存储指针的变量。它本质上是一个普通变量,但其值是另一个变量的内存地址。通过指针变量,我们可以间接访问和修改指向的变量的值。(存放在指针中的值都被当作地址处理)。比如int a = 7, int* pa = &a,此时pa就是一个指针变量。

一个内存单元是1个字节。如何编址?

32位的机器,假设有32跟地址线,那么假设每跟地址线在寻址时会产生一个电信号正电/负电(1或0)那么32根地址线产生的地址就会是:

00000000000000000000000000000000

00000000000000000000000000000001

...............................................................

111111111111111111111111111111111111

这里就有2的32次方个地址。每个地址标识一个字节,那么就可以给4g的空间进行编址。(2^32Byte == 2^32/1024kb==2^32/1024/1024mb==2^32/1024/1024/1024gb==4gb)64位就是8g空间。

所以:

指针是用来存放地址的,地址是唯一标示一块地址空间的,这句可以理解不了。

指针的大小在32位平台是4个字节,也就是32个比特位,所以32位机器这里的位就是指32个比特位,在64位平台是8个字节,也就是64个比特位。

二、指针类型

第一个意义

    printf("%d\n", sizeof(char*));
    printf("%d\n", sizeof(short*));
    printf("%d\n", sizeof(int*));
    printf("%d\n", sizeof(double*));

结果都是4。4个字节。但是不同类型仍有意义。

    int a = 0x11223344;
    int* pa = &a;
    *pa = 0;
    char* pc = &a;
    *pc = 0;
    //printf("%p\n", pa);
    //printf("%p\n", pc);

先屏蔽掉

  char* pc = &a;

  *pc = 0;

两个print打印的结果一样,同样的地址。

看int。如果开始调试,看内存地址,a变量的地址中四个字节会依次安排44 33 22 11。而类型为int*的pa,通过它改变a的值为0后,a变成了00 00 00 00。

如果是char*类型的pc,不改变前,a的地址中仍然是44 33 22 11。而*pc = 0后,内存中则变为00 33 22 11。这也就是不同类型的区别。

指针类型的意义:指针类型决定了指针进行解引用操作时能访问的空间的大小。比如char*只用访问一个字节,int*可访问4个字节,double则可访问8个字节,float则可访问4个字节,short可访问2个字节。

其实也可以这样考虑,char*类型的指针认为指向的是一个字符,所以只更改一个字节的值。

所以访问多少字节时需要对应合适的指针类型。

如果此时打印pa + 1, pc + 1。那么结果就是pa加了4个,而pc加了1个。指针类型决定了跳过几个字节。

第二个意义

野指针

成因一:指针未初始化

    int a;
    int* p;//局部变量不初始化,默认为随机值
    *p = 20;//局部的指针变量,就被初始化随机值

成因二:指针越界访问

    int arr[10] = { 0 };
    int* p = arr;
    int i = 0;
    for (i = 0; i < 12; i++)
    {
        *(p++) = i;
    }

指针持续访问,但是超过了10次,后来指向了自己不能管理的空间,也就成了野指针

成因三:指针指向的空间释放

int* test()
{
    int a = 10;
    return &a;
}

int main()
{
    int* p = test();
    *p = 20;
    return 0;
}

进入test函数后,创建了a这个变量,也创建了一个变量地址,随后返回这个地址,被*p接收。但是test函数结束后,a这个被创建的空间就会被释放,还给系统,*p虽然接收了地址,但当再次访问时,这个地址不再是指针能掌控的地方,所以成了野指针。

这个会联系到动态分配,以后再详细写。

结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值