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了

目录
相关文章
|
2月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
52 0
|
15天前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
68 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
15天前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
42 9
|
15天前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
39 7
|
25天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
89 13
|
18天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
18天前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
58 3
|
19天前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
25天前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
48 11
|
18天前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
32 1