C语言基础-指针

1.指针是什么?

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

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

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

C语言基础-指针_第1张图片

C语言基础-指针_第2张图片

// 指针是什么?
// 1.指针是内存中一个最小单元的编号,也就是地址
// 2.平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
// 总结:指针就是地址,口语中说的指针通常指的是指针变量
int main()
{
    int a = 100;  //在内存中开辟一块空间
    int * pa = &a;  //pa是专门来存放地址(指针)的,pa在这里就被称为指针变量
    //这里我们对变量a,取出它的地址,可以使用&操作符
    //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,p就是一个指针变量
    // int arr[10];
    // printf("%p\n",&a);
    printf("%p\n",pa);


    return 0;

}

2.指针和指针类型

C语言基础-指针_第3张图片

int* 的指针解引用访问4个字节

char* 的指针解引用访问1个字节

结论:指针类型可以决定指针解引用的时候访问多少个字节(指针的权限)

int* 4个字节  char* 1个字节  short* 2个字节  float* 4个字节   double* 8个字节

//指针类型的意义
int main()
{
    int a = 0x11223344; //0x开头是16进制数字
    
    //int * pa = &a;    
    char * pa = &a;
    // int* 的指针解引用访问4个字节
    // char* 的指针解引用访问1个字节
    // 结论:指针类型可以决定指针解引用的时候访问多少个字节(指针的权限)
    *pa = 0;

    return 0;
} 
//type * p     *说明p是指针变量
//1. p指向的对象的类型
//2. p解引用的时候访问的对象大小是sizeof(type)

int main()
{
    int a = 0x11223344; //0x开头是16进制数字
    
    int* pa = &a;    
    char* pc = &a;
    printf("%p\n",pa); //0x16d207388
    printf("%p\n",pc);//0x16d207388

    //int * 增加4个字节,char * 增加1个字节
    printf("%p\n",pa+1); //0x16d20738c
    printf("%p\n",pc+1);//0x16d207389
    //指针类型决定指针+1/-1操作时的步长
    //整形指针+1跳过4个字节
    //字符指针+1跳过1个字节

    return 0;
}

3.野指针

//野指针
// int main()
// {
//     int a = 10;
//     int* pa = &a;
//     *pa = 20;
//     printf("%d\n",a);

//     return 0;
// }


//p是野指针   野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
// int main()
// {
//     int* p; //局部变量不初始化的时候,内容是随机值
//     *p = 20;
//     printf("%d\n",*p);

//     return 0;
// }

//指针越界访问
// int main()
// {
//     int arr[10] = {0};
//     int* p = arr;
//     int i = 0;
//     for(i = 0; i<= 11;i++)
//     {
//         //当指针指向的范围超出数组arr的范围时,p就是野指针
//         *(p++) = i;
//     }
//     return 0;
// }

//指针释放
int* test()
{
    int a = 110;
    return &a;
}
int main()
{
    int* p = test();
    printf("%d\n",*p);


    return 0;
}

如何规避野指针:

1指针初始化

2小心指针越界

3指针指向的空间释放,及时置NULL

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

5指针使用之前检查有效性

// 如何规避野指针:
// 1指针初始化
int main()
{
    int a = 0;
    int* p = &a;

    int* ptr = NULL; //告诉你ptr是一个空指针,没有指向任何有效的空间,这个指针不能直接使用
    int* ptr2; //野指针

    if (ptr != NULL)
    {
        //使用
    }
    

    return 0;
}
// 2小心指针越界
// 3指针指向的空间释放,及时置NULL
// 4避免返回局部变量的地址
// 5指针使用之前检查有效性

4.指针运算

C语言基础-指针_第4张图片

指针+ - 整数

//指针运算
// int main()
// {
//     int arr[10] = {0};
//     //不使用下标访问数组
//     int* p = &arr[0];
//     int i = 0;
//     int sz = sizeof(arr)/sizeof(arr[0]);
//     for (int i = 0; i < sz; i++)
//     {
//         *p = i;
//         p++; // p = p+1
//     }
//     p = arr;

//     for (i = 0; i < sz; i++)
//     {
//         printf("%d ",*(p+i)); // p+i
//     }

//     // for (i = 0; i < 10; i++)
//     // {
//     //     printf("%d",arr[i]);
//     // }

//     return 0;
// }

//int arr[10];
//int* p = arr;
//*(p+i) ==  arr[i]
//*(arr+i) == arr[i]
//数组名是首元素的地址 -- 指针
//arr[i] == *(arr+i) == *(i+arr) == i[arr]

int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int i = 0;
    int *p = arr;
    for(i = 0;i < 10; i++)
    {
        printf("%d ",i[arr]); //[]操作符
        printf("%d ",*(p+i)); //[]操作符
    }

    //arr[i] --> i[arr]


    return 0;

}

// int my_strlen(char* s)
// {
//     int count = 0;
//     while (*s != '\0')
//     {
//         count++;
//         s++;
//     }

//     return count;
// }

//递归实现
// int my_strlen(char* s)
// {
//     if (*s == '\0')
//     {
//         return 0;
//     } else
//     {
//         return 1 + my_strlen(s + 1);
//     }
//    return 0;
// }
int my_strlen(char* s)
{
    char* start = s;
    while (*s != '\0')  //(*s)
    {
        s++;
    }
    // while (*s++); //err
    //while (*s++);   return s -start-1; //true

    return s -start;
    
}

int main()
{
    char arr[] = "abcdef"; // a b c d e f \0
    int len = my_strlen(arr);
    printf("%d\n",len);

    return 0;
}

5.指针和数组

6.二级指针

7.指针数组

你可能感兴趣的:(c语言,开发语言)