C语言:指针的讲解

指针的详细讲解(一)

1.什么是指针

1.1指针的定义:指针是C语言中一个非常重要的概念,也是C语言的特色之一。使用指针可以对复杂数据进行处理,能对计算机的内存分配进行控制,在函数调用中使用指针还可以返回多个值。

2.编制的理解

3.指针的变量和地址

3.1 取地址操作符(&)

3.1.1定义:顾名思义,就是获取当前变量的内存地址,想要获得那个变量的地址,就用&后面跟上那个变量。

3.1.2代码详解:

#include int main()
{
    int n= 7;
    int *p;
    p = &n;		//指针初始化,也可以写作 int *p = &n;
    printf("%d 的地址是 %p\n",n,p);
    return 0;
}

3.2解引用操作符(*)

3.2.1作用:*的作用是引用指针指向的变量值,引用其实就是引用该变量的地址,“解”就是把该地址对应的东西解开,解出来,就像打开一个包裹一样,那就是该变量的值了,所以称为“解引用”。 也就是说,解引用是返回内存地址中对应的对象。

3.3指针的解引用

int main()
{
 int a = 100;
 int* pa = &a;
 *pa = 0;
 return 0;

4.void*指针

4.1定义:void 指针可以指向任意类型的数据,就是说可以用任意类型的指针对 void 指针对 void 指针赋值。

注:void *可以接受不同类型的地址,但是无法直接计算。

5.指针运算

5.1指针+- 整数

#include int main
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 int *p = &arr[0];
 int i = 0;
 int sz = sizeof(arr)/sizeof(arr[0]);
 for(i=0; i 

5.2指针-指针

#include int my_strlen(char *s)
{
 char *p = s;
 while(*p != '\0' )
 p++;
 return p-s;
}
int main()
{
 printf("%d\n", my_strlen("abc"));
 return 0;
}

5.3指针的关系运算

int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 int *p = &arr[0];
 int i = 0;
 int sz = sizeof(arr)/sizeof(arr[0]);
 while(p

6.const

6.1const修饰变量

#include int main()
{
 int m = 0;
 m = 20;//m是可以修改的
 const int n = 0;
 n = 20;//n是不能被修改的
 return 0;
}

6.2const修饰指针变量

  • const int*p=&a;

  •     //当把 const 放最前面的时候,它修饰的就是 *p,那么 *p 就不可变。*p 表示的是指针变量 p 所指向的内存单元里面的内容,此时这个内容不可变。其他的都可变,如 p 中存放的是指向的内存单元的地址,这个地址可变,即 p 的指向可变。但指向谁,谁的内容就不可变。

  • int*const p=&a;

  •     //此时 const 修饰的是 p,所以 p 中存放的内存单元的地址不可变,而内存单元中的内容可变。即 p 的指向不可变,p 所指向的内存单元的内容可变。

  • const int*const p=&a;

  •     //此时 *p 和 p 都被修饰了,那么 p 中存放的内存单元的地址和内存单元中的内容都不可变。

    7.野指针

    7.1定义:

    野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。

    7.2野指针的规避:

    1、指针初始化 (如果没有就初始化为NULL)

    2、小心指针越界

    3、指针指向空间释放即使其置为NULL

    4、指针使用之前检查有效性   (例如:判断是否为NULL)

    8.assert断言

    8.1定义:C/C++ 中的 assert 是一个宏,用于在运行时检查一个条件是否为真,如果条件不满足,则运行时将终止程序的执行并输出一条错误信息。

    assert(p != NULL);

    指针的详细讲解(二)

    1.数组名

    1.1定义:数组名是一个表示整个数组的标识符,它通常会被解释为一个指向数组第一个元素的指针常量(类型为指向元素类型的指针)。数组名代表的内存地址是不可变的。数组名的值是数组首元素的指针常量。数组名存放的是数组的首地址,而从数据类型上理解数组,数组又有它的数据类型,即定义时的数据类型不同,所占用的内存空间也不相同。

    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int *p = &arr[0];

    2.一维数组传参的本质

    2.1本质:数组传参本质上传递的是数组⾸元素的地址。

    #include void test(int arr[])
    {
     int sz2 = sizeof(arr)/sizeof(arr[0]);
     printf("sz2 = %d\n", sz2);
    }
    int main()
    {
     int arr[10] = {1,2,3,4,5,6,7,8,9,10};
     int sz1 = sizeof(arr)/sizeof(arr[0]);
     printf("sz1 = %d\n", sz1);
     test(arr);
     return 0;
    }

    3.二级指针

    3.1定义:是一个指针变量,指向一个一级指针,并保存该一级指针的地址。

    int *p = &a;
    	int** s = &p;

    指针的详细讲解(三)

    1.字符指针变量

    1.1定义:字符指针:指向字符型数据的指针变量。每个字符串在内存中都占用一段连续的存储空间,并有唯一确定的首地址。即将字符串的首地址赋值给字符指针,可让字符指针指向一个字符串。

    int main()
    {
     const char* pstr = "hello bit.";
     printf("%s\n", pstr);
     return 0;
    }

    2.数组指针变量

    2.1定义:数组指针,顾名思义,就是指向数组的指针。

    我们是这样定义它的:int(* p)[n] = { }; (n为要定义的个数)

    int (*p)[10];

    3.函数指针变量

    3.1定义:所谓函数指针即定义一个指向函数的指针变量

    参照代码:

    int (*p)(int x, int y); //参数名可以去掉,并且通常都是去掉的。
    这样指针p就可以保存函数类型为两个整型参数,返回值是整型的函数地址了。

    希望大家看到这里已经有所收获,谢谢大家的观看,一键三连哦!!!!