C语言 ——深入理解指针(2)

目录

  • [1. 数组名的理解](#1. 数组名的理解)
  • [2. 二级指针](#2. 二级指针)
  • [3. 指针数组](#3. 指针数组)
  • [4. 字符指针变量](#4. 字符指针变量)
  • [5. 数组指针变量](#5. 数组指针变量)
  • [6. 函数指针变量](#6. 函数指针变量)
  • [7. 函数指针数组](#7. 函数指针数组)

1. 数组名的理解

这里我们使用 &arr[0] 的方式拿到了数组第一个元素的地址,但是其实数组名本来就是地址,而且是数组首元素的地址,我们来做个测试。

c 复制代码
#include <stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("&arr[0] = %p\n", &arr[0]);
	printf("arr = %p\n", arr);
	return 0;
}

输出结果:

我们发现数组名和数组首元素的地址打印出的结果一模一样,数组名就是数组首元素(第一个元素)的地址。

数组名如果是数组首元素的地址,那下面的代码怎么理解呢?

c 复制代码
#include <stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", sizeof(arr));
	return 0;
}

输出的结果是:40,如果arr是数组首元素的地址,那输出应该的应该是4/8才对。

其实数组名就是数组首元素(第一个元素)的地址是对的,但是有两个例外:

  • sizeof(数组名),sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,
    单位是字节
  • &数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素
    的地址是有区别的)

除此之外,任何地方使用数组名,数组名都表示首元素的地址。

2. 二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?

这就是二级指针。

对于二级指针的运算有:

  • *ppa 通过对ppa中的地址进行解引用,这样找到的是pa , *ppa 其实访问的就是pa .
c 复制代码
int b = 20;
*ppa = &b;//等价于pa = &b;
  • **ppa 先通过*ppa 找到pa ,然后对pa 进行解引用操作: *pa ,那找到的是a .
c 复制代码
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

3. 指针数组

指针数组,是存放指针的数组。

指针数组的每个元素都是用来存放地址(指针)的。


指针数组的每个元素是地址,又可以指向一块区域。

4. 字符指针变量

在指针的类型中我们知道有一种指针类型为字符指针char* ;

c 复制代码
int main()
{
	char ch = 'w';
	char *pc = &ch;
	*pc = 'w';
	return 0;
}

5. 数组指针变量

数组指针变量:存放的是数组的地址,能够指向数组的指针变量。

c 复制代码
int (*p)[10];

解释:p先和*结合,说明p是一个指针变量,然后指针指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫 数组指针

这里要注意:[]的优先级要高于号的,所以必须加上()来保证p先和结合。

数组指针类型解析:

c 复制代码
int (*p) [10] = &arr;
| | |
| | |
| | p指向数组的元素个数
| p是数组指针变量名
p指向的数组的元素类型

6. 函数指针变量

函数指针变量是用来存放函数地址的。

c 复制代码
#include <stdio.h>
void test()
{
	printf("hehe\n");
}
int main()
{
	printf("test: %p\n", test);
	printf("&test: %p\n", &test);
	return 0;
}

输出结果如下:

c 复制代码
test: 005913CA
&test: 005913CA

确实打印出来了地址,所以函数是有地址的,函数名就是函数的地址,当然也可以通过&函数名的方式获得函数的地址。

如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指针非常类似。如下:

c 复制代码
void test()
{
	printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)() = test;
int Add(int x, int y)
{
	return x + y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add;//x和y写上或者省略都是可以的

函数指针类型解析:

c 复制代码
int (*pf3) (int x, int y)
| | ------------
| | |
| | pf3指向函数的参数类型和个数的交代
| 函数指针变量名
pf3指向函数的返回类型
int (*) (int x, int y) //pf3函数指针变量的类型

7. 函数指针数组

函数指针数组是用来把函数的地址存到一个数组中

c 复制代码
int (*parr1[3])();

parr1 先和[] 结合,说明 parr1是数组,数组的内容是什么呢?

是int (*)() 类型的函数指针。

相关推荐
励志成为嵌入式工程师4 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
Peter_chq5 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
hikktn6 小时前
如何在 Rust 中实现内存安全:与 C/C++ 的对比分析
c语言·安全·rust
观音山保我别报错7 小时前
C语言扫雷小游戏
c语言·开发语言·算法
小林熬夜学编程9 小时前
【Linux系统编程】第四十一弹---线程深度解析:从地址空间到多线程实践
linux·c语言·开发语言·c++·算法
墨墨祺9 小时前
嵌入式之C语言(基础篇)
c语言·开发语言
躺不平的理查德9 小时前
数据结构-链表【chapter1】【c语言版】
c语言·开发语言·数据结构·链表·visual studio
幼儿园园霸柒柒11 小时前
第七章: 7.3求一个3*3的整型矩阵对角线元素之和
c语言·c++·算法·矩阵·c#·1024程序员节
好想有猫猫11 小时前
【51单片机】串口通信原理 + 使用
c语言·单片机·嵌入式硬件·51单片机·1024程序员节
摆烂小白敲代码12 小时前
背包九讲——背包问题求方案数
c语言·c++·算法·背包问题·背包问题求方案数