C语言指针

1.指针的概念

1.内存地址的概念

  • 内存单元:计算机的内存由许多存储单元组成,每个存储单元都有一个编号,称为内存地址。
  • 地址与存储内容:内存地址用于标识存储单元的位置,而存储单元中存放的数据则是该单元的存储内容。

2.变量的地址和变量的值

  • 变量的地址:在程序中,变量的地址是指该变量在内存中所占存储单元的首地址。
  • 变量的值:变量的值是指存储在该变量所占用的存储单元中的数据。

3.指针的含义

  • 指针的定义:指针是一种变量,它存储的是另一个变量的地址。
  • 指针与变量的关系:通过指针,可以间接访问到它所指向的变量的值。

4.指针变量的定义

  • 定义形式:类型名 *指针变量名;,例如int *p;定义了一个指向整型变量的指针p
  • 注意事项:在定义指针变量时,需要注意指针变量的类型应与它所指向的变量类型一致。

2.指针变量

1.指针变量的赋值

  • 直接赋值:可以使用&运算符获取变量的地址,并将其赋给指针变量,例如p = &a;,其中a是一个整型变量。
  • 初始化:在定义指针变量时,可以同时进行初始化,例如int *p = &a;

2.指针变量的操作

  • 访问指针所指向的变量:通过指针变量可以访问它所指向的变量,例如*p表示指针p所指向的变量。
  • 指针的移动:指针可以进行加减运算,但需要注意指针移动的单位是其所指向的数据类型的大小。

3.空指针和野指针

  • 空指针:空指针是指指针的值为NULL的指针,NULL是一个在标准库中定义的常量,表示空地址。
  • 野指针:野指针是指指向未定义或非法内存区域的指针,使用野指针可能会导致程序出现错误。

4.指针的比较

  • 指针的相等性:可以比较两个指针是否相等,判断它们是否指向同一个内存地址。
  • 指针的大小比较:在某些情况下,也可以比较两个指针的大小,但这种比较的意义通常取决于具体的应用场景。

3.通过指针引用数组

1.数组元素的指针

  • 数组名与指针的关系:在C语言中,数组名可以看作是一个指针,它指向数组的首元素。
  • 通过指针访问数组元素:可以使用指针来访问数组元素,例如*(p + i)表示访问指针p指向的数组中第i个元素。

2.在引用数组元素时指针的运算

  • 指针的加减运算:指针可以进行加减运算,指针加上或减去一个整数n,表示指针向前或向后移动n个元素的位置。
  • 指针的关系运算:指针可以进行关系运算,用于比较两个指针的位置关系。

3.通过指针引用数组元素 

例如,通过以下代码可以使用指针来遍历数组元素:

4.字符串与指针

  • 字符串的存储与表示:字符串常量可以存储在字符数组中,也可存储在指针指向的内存空间中。
  • 指针操作字符串:可使用指针来操作字符串,如使用strcpy(字符串复制)、strcmp(字符串比较)等函数。
  • 注意事项:使用指针操作字符串时,要确保指针指向的内存空间合法,避免内存访问错误。

5.指向函数的指针

  1. 定义:指向函数的指针定义形式为返回值类型 (*指针变量名)(参数列表)。例如,int (*pf)(int, int);定义了一个指向函数的指针pf,该函数接受两个整数参数,并返回一个整数。
  2. 赋值:可以将函数的地址赋给指向函数的指针。例如,pf = 函数名;,其中函数名是与指针类型匹配的函数的名称。
  3. 调用:通过指向函数的指针来调用函数,使用的方式与直接调用函数类似,只是通过指针来进行。例如,pf(参数1, 参数2);
  4. 作用
    • 实现函数的回调:可以将指向函数的指针作为参数传递给其他函数,在适当的时候通过指针调用相应的函数,实现函数的回调机制,增加程序的灵活性。
    • 动态选择函数:根据不同的条件,使用指向不同函数的指针来执行不同的函数,实现动态选择函数的功能。
  5. 注意事项
    • 指向函数的指针在使用时要确保指针已经被正确赋值,指向了有效的函数。
    • 函数的参数列表和返回值类型必须与指针的定义相匹配,否则会导致编译错误或运行时错误。

6.返回指针值的函数

  1. 特点
    • 函数的返回类型是指针类型,例如int *char *等。
    • 在函数内部,通常会进行动态内存分配或其他操作,以获取一个指针所指向的内存空间。
  2. 作用
    • 动态分配内存:可以在函数中使用malloccalloc等函数动态分配内存,并返回指向该内存空间的指针。这样,调用者可以通过该指针访问和操作动态分配的内存。
    • 返回数据结构的指针:函数可以构建复杂的数据结构(如链表、树等),并返回指向该数据结构的指针,使得调用者可以进一步处理和使用这些数据结构。
    • 实现数据的共享和传递:通过返回指针,多个函数或模块可以共享和访问同一块内存区域,实现数据的传递和共享。
  3. 注意事项
    • 内存管理:由于返回的指针指向的是动态分配的内存,调用者在使用完后需要及时使用free等函数释放内存,以避免内存泄漏。
    • 指针的有效性:调用者在使用返回的指针时,需要确保指针的有效性,避免访问无效的内存区域。
    • 函数的接口设计:在设计返回指针值的函数时,需要清晰地说明指针的含义、指向的内存区域的生命周期以及使用时的注意事项,以便调用者正确使用。

7.指针数组和指向指针的指针

1.指针数组

  1. 定义:指针数组是元素为指针的数组,即数组中的每个元素都是一个指针。
  2. 示例int *ptrArray[10]; 定义了一个包含 10 个指向整数指针的数组。
  3. 作用
    • 用于存储多个字符串的首地址,方便对多个字符串进行操作。
    • 可以指向不同的内存空间,用于管理多个相关或不相关的数据对象。
  4. 特点
    • 每个元素都是一个指针,可以独立地指向不同的内存地址。
    • 指针数组的元素可以动态地分配和释放内存。

2.指向指针的指针

  1. 定义:指向指针的指针是指一个指针变量,它存储的是另一个指针的地址。
  2. 示例int **ptrToPtr; 定义了一个指向指针的指针。
  3. 作用
    • 用于多级指针的操作,特别是在处理复杂的数据结构时,如链表、树等。
    • 可以通过间接寻址的方式,更灵活地访问和修改数据。
  4. 特点
    • 增加了指针的层次,使对数据的访问更加灵活,但也增加了程序的复杂性。
    • 需要注意指针的解引用和内存管理,以避免出现错误。

8.有关指针的数据类型和指针运算

1.指针的数据类型

  1. 指针的基本类型:指针是一种特殊的数据类型,它存储的是另一个变量的地址。指针的基本类型取决于它所指向的变量的类型,例如指向整数的指针类型为int *,指向字符的指针类型为char *等。
  2. void指针类型void指针类型可以指向任何类型的数据,它是一种通用的指针类型。当使用void指针时,需要进行类型转换,将其转换为具体的指针类型,才能进行相应的操作。
  3. 指针数组类型:指针数组是元素为指针的数组,例如int *ptrArray[10];表示一个包含10个指向整数指针的数组。
  4. 指向指针的指针类型:指向指针的指针是指一个指针变量,它存储的是另一个指针的地址,例如int **ptrToPtr;

2.指针运算

  1. 取地址运算(&):用于获取变量的地址,例如int a; int *p = &a;,这里的&a就是获取变量a的地址,并将其赋值给指针p
  2. 解引用运算(*):通过指针访问它所指向的变量的值,例如int a = 10; int *p = &a; printf("%d", *p);,这里的*p就是访问指针p所指向的变量a的值。
  3. 指针加减运算:指针的加减运算以它所指向的数据类型的大小为单位。例如,对于指向整数的指针,加1表示指针向后移动一个整数的大小。
  4. 指针关系运算:指针可以进行关系运算,如比较两个指针的大小或判断它们是否相等。但需要注意的是,指针的比较通常是基于它们所指向的内存地址。
  5. 其他运算:指针还可以进行一些其他运算,如指针的赋值运算、指针的递增递减运算等。但在使用时需要谨慎,确保运算的合法性和正确性。

9.void指针类型

  • 通用性:void指针类型可以指向任何类型的数据,是一种通用的指针类型,也称万能指针。
  • 类型转换:当使用void指针时,需要进行类型转换,将其转换为具体的指针类型,才能进行相应的操作。
  • 应用场景:void指针在一些情况下非常有用,例如在函数中需要返回不同类型的数据时,可以使用void指针来实现,void 指针不能进行指针运算。
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值