C语言 指针

目录

什么是指针?

不同类型指针,访问权限不同

例 

指针类型和数据类型不能需保持统一 

指针和数组

模拟strlen方法求字符串长度

移位指针实现

指针 - 指针实现

&arr[i] == p + i

arr传参 arr[i] == *(arr+i);

二级指针

what?

指针数组

 指针创建二维数组        


什么是指针?

1. 指针是内存中一个最小单元的编号,也就是地址
2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
3. 本质上指针就是地址,口语中说的指针,其实就是指针变量,指针变量就是用来存放指针地址的
4. 我们可以通过&(取地址操作符)取出变量的内存起始地址,把地址可以存放到一个变量中,这个 变量就是指针变量
5. 指针变量存储指针时(如0x11223344)在32位是4个字节,64位字节是8位字节

指针变量的大小和指针类型没有关系,如下

    char *pc = NULL;
    int *pi = NULL;
    double *pd = NULL;
    short *ps = NULL;
    printf("%d\n", sizeof(char *)); // 8
    printf("%d\n", sizeof(pc));     // 8
    printf("%d\n", sizeof(pi));     // 8
    printf("%d\n", sizeof(pd));     // 8
    printf("%d\n", sizeof(ps));     // 8

不同类型指针,访问权限不同

  • 指针类型决定了指针被解引用的时候访问几个字节,如果是int*的指针,解引用访问4个字节,
  • 如果是char*的指针,解引用访问1个字节,其他类型同理
  • 不同类型指针,访问权限不同!

如下,在这段代码中,int A = 0x11223344; 定义了一个整数变量 A,其初始值为十六进制数 0x11223344。然后,char *PC = (char *)&A; 创建了一个指针 PC,指向变量 A 的地址。通过类型转换 (char *)&A,将整数指针转换为字符指针。接下来,*PC = 0; 对指针 PC 解引用并将其指向的内存位置赋值为 0。因为 PC 是字符指针,所以这个操作将字符型的 0 赋值给了 A 的最低字节,即将 0x11223344 修改为 0x11223300。

    int A = 0x11223344; // 16进制
    // int *PA = &A;
    // *PA = 0; // 0
    char *PC = (char *)&A;
    *PC = 0; // 0x11223300

例 

    int b = 0x11223344;
    int *Pb = &b;
    char *Pch = (char *)&b;
    printf("Pb = %p\n", Pb);   // 000000a178fffd24
    printf("Pch = %p\n", Pch); // 000000a178fffd24
    /* 
        *指针的类型决定了指针 +-1 操作的时候,跳过几个字节,决定了指针的步长, 例如double类型 + 1,跳过8个字节访问
        也就是不同类型的指针类型,所访问的权限不同
     */
    printf("Pb = %p\n", Pb + 1);   // 000000a178fffd28 跳过4个字节
    printf("Pch = %p\n", Pch + 1); // 000000a178fffd25 跳过1个字节

指针类型和数据类型不能需保持统一 

指针变量存放的是地址,他映射到变量的内存地址,然而指针变量根本不知道变量的类型,所以需要在指针变量中定义类型来决定变量的移动步进
 如下 int* 和 float* 不能通用 

    int d = 0;
    int *pi = &d;   // 解引用访问4个字节,pi+1也是跳过4个字节
    float *pn = &d; // 解引用访问4个字节,pf+1也是跳过4个字节
    // *pi = 100;
    *pn = 100.0; // 会有意向不到的结果,因为整形和浮点型在内存中存放的方式是不同的

指针和数组

int arr[10] = {0};
printf("%d\n", &arr[9] - &arr[0]); // 9, 就是指针之间的元素个数

模拟strlen方法求字符串长度

移位指针实现

int my_strlen1(char *str) // 传过来的实际是 a 字符的地址
{
    int count = 0;
    while (*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}


int len = my_strlen1("abcdef");
printf("%d\n", len); // 6

指针 - 指针实现

int my_strlen2(char *str)
{
    char *startStr = str;
    while (*str != '\0')
    {
        str++; // 最后一次执行后,str指针变量指向了 \0
    }
    return (str - startStr);
}


int len = my_strlen2("abcdef");
printf("%d\n", len); // 6

&arr[i] == p + i

    int arr[10] = {0};
    int *p = arr; // arr首元素的地址
    int sz = sizeof(arr) / sizeof(arr[0]);
    for (int i = 0; i < sz; i++)
    {
        printf("%p----%p\n", &arr[i], p + i); // 通过指针访问数组元素 (此处两个值一模一样)
    }

arr传参 arr[i] == *(arr+i);

int test(int arr[], int sz) // arr是arr首元素地址
{
    for (int i = 0; i < sz; i++)
    {
        printf("%d", arr[i]); // arr[i] == *(arr+i);
    }
}
   
 
int ary[10] = {0};
test(ary, 10);

二级指针

what?

二级指针变量,存放的是一级指针变量的地址

如下:

pa是一级指针变量,*代表后面是指针变量,int代表指针变量所指向的地址是int类型的数据,ppa是二级指针变量,存放一级指针变量pa的指针地址(指针变量为4个字节或8字节) 

    int a = 10;
    int *pa = &a; 
    int **ppa = &pa; 
    **ppa = 20;
    printf("%d\n", a); // 20

指针数组

——>存放指针的数组就是指针数组

    int b = 10;
    int c = 20;
    int d = 30;
    int *parr[10] = {&b, &c, &d}; // parr就是存放指针的数组
    for (int i = 0; i < 3; i++)
    {
        printf("%d\n", *(parr[i])); // 10 20 30
    }

 指针创建二维数组        

    int arr1[4] = {1, 2, 3, 4};
    int arr2[4] = {2, 3, 4, 5};
    int arr3[4] = {3, 4, 5, 6};
    int *parrCreate[3] = {arr1, arr2, arr3};
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 4; j++)

        {
             /* 
                1 2 3 4
                2 3 4 5
                3 4 5 6
             */
            printf("%d ", parrCreate[i][j]);
        }
        printf("\n");
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山楂树の

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值