第六章-指针

一、指针是什么

指针是内存中一个最小单元的编号,也就是地址

平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

指针就是地址,口语中说的指针通常指的是指针变量

指针变量,用来存放地址的变量。

指针是用来存放地址的,地址是唯一标示一块地址空间的。

指针的大小在32位平台是4个字节,在64位平台是8个字节。

#include <stdio.h>
int main()
{
 int a = 10;//在内存中开辟一块空间
 int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
    //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
中,p就是一个之指针变量。
 return 0;
}

二、 指针和指针类型

针的类型决定了指针走多远

指针的类型决定了能操作几个字节。

#include<stdio.h>
int main()
{
    //printf("%d\n", sizeof(char*));//4
    //printf("%d\n", sizeof(short*));//4
    //printf("%d\n", sizeof(int*));//4
    //printf("%d\n", sizeof(double*));//4
    int a = 0x11223344;
    int* pa = &a;
    char* pc = &a;
    printf("%p\n", pa);//0096F718
    printf("%p\n", pc);//0096F718
    return 0;
}
#include <stdio.h>
int main()
{
    int a = 0x11223344;
    int* pa = &a;
    char* pc =&a;
    printf("%p\n", pa);
    printf("%p\n", pa+1);//+4
    printf("%p\n", pc);
    printf("%p\n", pc + 1);//+1
    //指针的类型决定了指针走多远
    //int* p;p+1-->4
    //char* p;p+1-->1
    //double* p; p + 1-- > 8;
    return 0;
}
#include<stdio.h>
int main()
{
    int arr[10] = { 0 };
    int* p = arr;//数组名-首元素地址
    //char* p=arr;只能改10个字节
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        *(p + i) = 1;//把数组全改成1
    }
    printf("%p\n", p);
    return 0;
}

三、野指针

1.原因

(1) 指针未初始化

#include <stdio.h>
int main()
{
    //未初始化的指针变量
    int* p;//局部变量指针未初始化,默认为随机值
    *p = 20;
    return 0;
}

(2) 指针越界访问

#include <stdio.h>
int main()
{
    //数组越界
    int a[10] = { 0 };
    int i = 0;
    int* p = a;
    for (i = 0; i <= 12; i++)
    {
        //当指针指向的范围超出数组arr的范围时,p就是野指针
        *p = i;
        p++;
        //*p++=i;
    }
    return 0;
}

(3)指针指向的空间释放

#include<stdio.h>
int* test()
{
    int a = 10;//局部变量,仅局部使用
    return &a;
}
int main()
{
    int* p=test();
    printf("%d\n",*p);//再次访问非法
    return 0;
}

2.规避野指针

(1)指针初始化或赋值(NULL)

(2) 小心指针越界

(3) 指针指向空间释放即使置NULL

(4) 避免返回局部变量的地址

(5) 指针使用之前检查有效性(指针不为空)

四、 指针运算

1.指针+- 整数

#include<stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int i = 0;
    int sz = sizeof(arr) / sizeof(arr[0]);
    int* p = arr;
    for (i = 0; i < sz; i++)
    {
        printf("%d", *p);
        p = p + 1;
        //p++;
    }
    return 0;
}

 2.指针-指针

两个指针需要位于同一个空间

#include<stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    printf("%d\n", &arr[9] - &arr[0]);
    //9,求的是中间元素个数
    return 0;
}
#include<stdio.h>
int my_strlen(char* str)
{
    char* start = str;
    char* end = str;
    while (*end != '\0')
    {
        end++;
    }
    return end - start;
}
int main()
{
    char arr[] = "bit";
    int len = my_strlen(arr);
    printf("%d\n", len);
    return 0;
}

3.指针的关系运算

五、 指针和数组

#include <stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
    printf("%p\n", arr);//地址--首元素的地址
    printf("%p\n", arr+1);//加4

    printf("%p\n", &arr);
    printf("%p\n", &arr+1);//加40
    //&arr-&数组名
    //数组名不是首元素的地址-数组名表示整个数组
    //&数组名取出的是整个数组的地址
    //sizeof(arr)-sizeof(数组名)计算整个数组大小

    printf("%p\n", &arr[0]);
    printf("%p\n", &arr[0]+1);//加4
    return 0;
}
#include <stdio.h>
int main()
{
    int arr[10] = { 0 };
    int* p = arr; //指针存放数组首元素的地址
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("&arr[%d] = %p   <====> p+%d = %p\n", i, &arr[i], i, p + i);
    }
    return 0;
}

六、 二级指针

#include<stdio.h>
int main()
{
    int a = 10;
    int * pa = &a;
    int* * ppa = &pa;//ppa为二级指针
    //*ppa 通过对ppa中的地址解引用,找pa, *ppa 访问的是pa
    int** * pppa = &ppa;//pppa为三级指针
    return 0;
}

七、指针数组

是存放指针的数组

#include<stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    int c = 30;
    int* arr2[3] = { &a, &b, &c };
    int i = 0;
    for (i = 0; i < 3; i++)
    {
        printf("%d", *(arr2[i]));
    }
    return 0;
}

 

posted @ 2021-10-31 20:40  mljrm  阅读(48)  评论(0)    收藏  举报