25.指针初阶

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>

指针:
标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,
但是不允许与指向第一个元素之前的那个内存位置的指针进行比较

一.指针是什么
内存编号 - 地址 - 指针
int main()
{
    int a = 10;                       //a占4个字节
    int* pa = &a;                   //拿到的是a的4个字节中第一个字节的地址
    return 0;
}

二.指针和指针类型
指针类型的意义:
指针类型决定了:①指针解引用的权限有多大
               ②指针走一步,能走多远(多长)
①:
int main()
{
                                    0 1 2 3 4 5 6 7 8 9 a b c d e f
                                    11111111
                                        8421   -  4个2进制位可以表示1个16进制位
    int a = 0x11223344;                //              1个字节就可以表示2个16进制位
    char* pc = &a;
    *pc = 0;                        //只有第一个字节变为0

    int* pa = &a;    
    *pa = 0;                        //四个字节都变为0

    return 0;
}
②:
int main()
{
    int arr[10] = { 0 };
    int* p = arr;
    char* pc = arr;
                                    不管放什么类型的指针都能存放地址

    printf("%p\n", p);
    printf("%p\n", p+1);              //加了4

    printf("%p\n", pc);
    printf("%p\n", pc+1);            //加了1
    return 0;
}

int main()
{
    int arr[10] = { 0 };
    int* p = arr;
    int i = 0;
    for (i = 0;i < 10;i++)
    {
        *(p + i) = 1;                // p + i 其实是下标位i的地址
    }
    return 0;
}

三.野指针
概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
成因:①指针未初始化
int main()
{
                            //这里的p就是一个野指针
    int* p;               //p是一个局部的指针变量,局部变量不初始化的话,默认是随机值
    *p = 20;           //非法访问内存了

    return 0;
}
②指针越界访问
int main()
{
    int  arr[10] = { 0 };
    int* p = arr;
    int i = 0;
    for (i = 0;i <= 10;i++)
    {
        *p = i;
        p++;
    }
    return 0;
}
③指针指向空间释放
int* test()
{
    int a = 10;
    return &a;
}
int main()
{
    int* p = test();
    *p = 20;

    return 0;
}

如何避免野指针?
1.指针初始化                    ps:当不知到指针初始话为什么地址的时候,直接初始化为NULL
2.小心指针越界                ps:C语言本身是不会检查数据的越界行为的
3.指针指向空间释放及时置NULL  ps:UNLL是不能直接使用它的
4.指针使用之前检查有效性        ps: if(p != NULL)来检查有效性

四.指针运算
1.指针 +- 整数
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int* p = arr;
    int* pend = arr + 9;
    while (p <= pend)
    {
        printf("%d\n", *p);
        p++;
    }
    return 0;
}
2.指针 - 指针    得到的两个指针之间的元素个数
指针和指针相减的前提:两个指针指向同一块空间
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    char c[5];

    printf("%d\n", &arr[9] - &arr[0]);
    return 0;
}

计数器的方法
int my_strlen(char* str)
{
    int count = 0;
    while (*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}
指针减指针的方法
int my_strlen(char* str)
{
    char* start = str;
    while (*str != '\0')
    {
        str++;
    }
    return str - start;
}
int main()
{
    //strlen(); - 求字符串长度
    //int len = strlen("abc");
    char arr[] = { "abc" };
    int len = my_strlen(arr);
    printf("%d\n", len);

    return 0;
}

五:指针和数组
int main()
{
    int arr[10] = { 0 };
    int* p = arr;                        //数组名
    //[ ] 是一个操作符 2和arr是两个操作数
    printf("%d\n", 2[arr]);
    printf("%d\n", arr[2]);
    printf("%d\n", p[2]);            //p[2] --> * (p + 2)

    //arr[2] --> * (arr + 2) --> * 2[arr]

    //arr[2] <==> * (p + 2) <==> * (2 + p) <==> * (2 + arr)
    //2[arr] <==> * (2 + arr)
    return 0;
}

六:二级指针
int main()
{
    int a = 10;
    int* pa = &a;              //pa是指针变量,一级指针
                                     //ppa就是一个二级指针变量
    int** ppa = &pa;        //pa也是个变量,&pa取出pa再内存中起始地址
    return 0;
}

指针数组 - 本质是数组
存放的是指针的数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值