C语言指针详解

简介: 指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。

一、什么是指针


指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体

二、指针变量和指针类型

1.指针变量

指针变量是变量。定义一个指针变量,是在内存中开辟一个空间,该空间里面存放地址。

int* pa; // 定义一个指向整型数据的指针变量
int a = 10;
int* pa = &a; // 将a的地址赋值给pa

通过指针变量可以进行间接访问和修改所指向的数据,例如:

1.int a = 10;
int* pa = &a;
*pa = 30; // 修改pa所指向的数据为30,即修改了a的值


2.指针类型

char  *pc = NULL;
short *ps = NULL;
int   *pi = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

char*类型的指针是为了存放 char类型变量的地址。 long* 类型的指针是为了存放long类型变量的地址。int*类型的指针是为了存放int 类型变量的地址等等。


三、野指针


野指针就是指针指向的位置是不可知的、随机的、不正确的、没有明确限制的


造成野指针的原因


1.指针未初始化

 int *pa;//指针未初始化,默认为随机值
 *pa = 30;

2.指针访问越界

int main()
{
    int arr[3][4] = { 0 };
    printf("%d", arr[3][4]);
    return 0;
}

3.指针指向的空间释放

int main()
{
  int* p = (int*)malloc(sizeof(int));
  free(p);
  p = NULL;  //此处做置空处理或作重新赋值处理,否则会成为野指针
}

四、指针的运算


1.指针加减整数

#include <stdio.h>
int main()
{
  int a = 100;
  int* pa = &a;
  printf("%p\n", &a);      //00AFFADC
  printf("%p\n", pa);      //00AFFADC
  printf("%p\n", pa + 1);  //00AFFAE0
 
  return  0;
}

2.指针-指针

两个指针相减代表指针之间所经历的元素数

int My_strlen(const char* a)
{
  char* pa = a;
  while (*pa != '\0')
  {
    pa++;
  }
  return pa - a;
}

五、指针数组和数组指针


数组指针:是指针,指向数组。例:int (*arr)[10]

指针数组:是数组,数组内容存放的是指针。例:int *arr[10]

1.指针数组

int main(void)
{
  int arr1[3] = { 51,10,1 };
  int arr2[4] = { 4,1,6,14 };
    int arr3[5] = { 9,9 };
    int arr4[2] = { 5,20 };
    int* parr[4] = { arr1,arr2,arr3,arr4 };
    printf("%d\n", *(parr[0] + 1));//10
    printf("%d\n", *(parr[1] + 1));//1
    printf("%d\n", *(parr[2] + 1));//9
    printf("%d\n", *(parr[3] + 1));//20
    return 0;
}

int*parr[4],因为[ ]的优先级要比*要高,所以 parr先与[ ]结合,构成一个数组的定义,数组名为 parr,而int*修饰的是数组的内容,即数组的每个元素。也就是说,该数组包含 4 个指向int*类型数据的指针

2.数组指针

#include<stdio.h>
int main()
{
    int arr[3][4] = { {89,65,32,12},{88,65,11,1},{86,51,32,1} };
    int(*parr)[4] = &arr;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            printf("parr[%d][%d]=%d  ", i, j, arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

对于int(*parr)[4]“( )”的优先级比[ ]高,*号和 parr 构成一个指针的定义,指针变量名为arr,而int 修饰的是数组的内容,即数组的每个元素。也就是说,parr 是一个指针,它指向一个包含 4 个int类型数据的数组

六、函数指针和指针函数


1.函数指针

函数指针,其本质是一个指针变量,该指针指向这个函数。总结来说,函数指针就是指向函数的指针。 类型说明符 (*函数名) (参数)

#include<stdio.h>
int add(int x,int y)
{
    return x + y;
}
int (*padd) (int,int);      //声明函数指针
int main()
{
    padd = &add;          //padd函数指针指向add函数 
    printf("%d",(*padd)(5,1));
    return 0;
}


2.指针函数

指针函数是返回指针的函数主体是函数,返回值是一个指针

#include<stdio.h>
int* Fu(int* i)    //传入指针  
{
  int* pi = i;    //指针pi指向i
    return pi;       //返回pi指向的地址
}
int main()
{
    int a = 10;      
    int* pa = &a;   //pa指向a的地址
    printf("%d",*fun(pa));//输出pa指向的地址的值
    return 0;
}

七、二级指针


指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里? 这就是二级指针,有了指针变量pa,下面就可以定义二级指针,并对其进行初始化了;定义了二级指针ppa,并通过取地址符获取指针变量pa的内存地址,将其初始化给二级指针ppa

int a = 10;
int *pa = &a;
int **ppa = &pa;

二级指针的解引用

*ppa
**ppa

在ppa前面有两个解引用运算符,第一次解引用后,可访问到指针变量pa,第二次解引用后,便可以访问到变量a了

目录
相关文章
|
15天前
|
C语言
C语言指针带代码
C语言指针带代码
21 3
|
1天前
|
C语言
【C语言基础】:深入理解指针(终篇)
【C语言基础】:深入理解指针(终篇)
|
1天前
|
存储 C语言 C++
【C语言基础】:深入理解指针(三)
【C语言基础】:深入理解指针(三)
|
1天前
|
安全 程序员 编译器
【C语言基础】:深入理解指针(二)
【C语言基础】:深入理解指针(二)
【C语言基础】:深入理解指针(二)
|
1天前
|
存储 编译器 C语言
【C语言基础】:深入理解指针(一)
【C语言基础】:深入理解指针(一)
|
2天前
|
C语言
C语言的灵魂---指针(进阶)
C语言的灵魂---指针(进阶)
|
2天前
|
C语言
|
2天前
|
存储 C语言
C语言的灵魂---指针(基础)
C语言的灵魂---指针(基础)
|
9天前
|
存储 C语言
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)二
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)二
12 1
|
9天前
|
存储 C语言
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)一
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)一
9 1