当前位置: 首页 > article >正文

指针的介绍2前

1.数组名的理解

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };

	printf("&arr[0] = %p\n", &arr[0]);
	printf("arr     = %p\n", arr);
	return 0;
}

观察得到,数组名就是数组首元素的地址

但有2个例外:

1.

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	printf("%d\n", sizeof(arr));
	return 0;
}

如果在这段代码中,arr还是数组首元素的地址的话

那么打印结果就应该是48

但打印结果是36

注意到数组一共有 9 个 int型 的元素

数组的大小正好是36个字节

所以:sizeof(数组名)中,数组名代表的是整个数组

2.

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	printf("&arr[0] = %p\n", &arr[0]);
	printf("arr     = % p\n", arr);
	printf("&arr    = %p\n", &arr);

	printf("&arr[0]+1 = %p\n", &arr[0]+1);
	printf("arr    +1 = %p\n", arr+1);
	printf("&arr   +1 = %p\n", &arr+1);
	return 0;
}

 

上面的代码示意图如下:

 &arr[0] 、arr、&arr 拿到的地址相同

进行+1操作之后,

&arr[0] 、arr 都跳过4个字节,即跳过一个 int 型d的数组元素

说明它俩的指针类型相同

&arr 跳过 36 个字节,即跳过了一个数组

所以:&数组名 中, 数组名代表的是整个数组

总结:

(1)sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩, 单位是字节

(2)&数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素 的地址是有区别的)

(3)除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址

2.[]下标引用操作符

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

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

	for (int i = 0; i < sz; ++i)
		printf("%d", arr[i]);
	return 0;
}

打印数组元素时,使用了 [] 操作符

实际上,arr[i] 的本质是 *(arr + i)

所以就是用数组首元素的地址的移动来遍历数组

(arr + i) 与 (i + arr) 一致

所以

arr[i] == *(arr + i) == *(i + arr) == i[arr]

上述等式验证如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

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

	for (int i = 0; i < sz; ++i)
		printf("%d ", arr[i]);
	printf("\n");
	for (int i = 0; i < sz; ++i)
		printf("%d ", *(arr+i));
	printf("\n");
	for (int i = 0; i < sz; ++i)
		printf("%d ", *(arr+i));
	printf("\n");
	for (int i = 0; i < sz; ++i)
		printf("%d ", i[arr]);
	return 0;
}

总结:

arr[i] 的本质是 *(arr + i)

数组元素的访问在编译器处理的时候,

是转换成⾸元素的地址+偏移量求出元素的地址,

然后解引⽤来访问的。

 3.一维数组传参的本质

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

void test(int arr[])
{
	int sz2 = sizeof(arr) / sizeof(arr[0]);
	printf("%d\n", sz2);
}

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

	test(arr);

	return 0;
}

x86平台运行下:

x64环境下:

main函数中,sz1,毋庸置疑,是数组元素的个数

test 函数中, 我的初心也是求传入数组的元素个数

可不管是x64还是x86环境下,结果都不正确

仔细分析:

sz2 = sizeof(arr) / sizeof(arr[0])

sizeof(arr[0]) == 4

x86环境下

sz2 == 1,所以sizeof(arr) == 4

如果arr代表的是整个数组,那么sizeof(arr) == 36

显然arr代表的是数组首元素的地址,此时sizeof(arr) == 4

x64环境下

sz2 == 2,所以sizeof(arr) == 8

如果arr代表的是整个数组,那么sizeof(arr) == 36

显然arr代表的是数组首元素的地址,此时sizeof(arr) == 8

总结:

本质上,数组传参传递的是数组⾸元素的地址


http://www.kler.cn/a/522738.html

相关文章:

  • SpringBoot 中的测试jar包knife4j(实现效果非常简单)
  • DeepSeek--通向通用人工智能的深度探索者
  • 基于SpringBoot的高校一体化服务平台的设计与实现(源码+SQL脚本+LW+部署讲解等)
  • Luzmo 专为SaaS公司设计的嵌入式数据分析平台
  • 穿心莲内酯(andrographolide)生物合成CYP72-文献精读106
  • A星算法两元障碍物矩阵转化为rrt算法四元障碍物矩阵
  • 【JavaEE进阶】应用分层
  • 使用Ollama 在Ubuntu运行deepseek大模型:以DeepSeek-coder为例
  • 包管理工具随记
  • 构建1688自动代采系统:PHP开发实战指南
  • 深度学习|表示学习|卷积神经网络|输出维度公式如何理解?|16
  • 宝塔中运行java项目 报权限不足
  • 14-6-2C++STL的list
  • mysql统计每个表行数、大小以及数据库总行数、大小
  • 洛谷题目 P5994 [PA 2014] Kuglarz 题解 (本题较难)
  • 深入浅出 Rust 的强大 match 表达式
  • 怎么样把pdf转成图片模式(不能复制文字)
  • PyCharm介绍
  • 宝塔面板SSL加密访问设置教程
  • 自助设备系统设置——对接POS支付
  • 《程序人生》工作2年感悟
  • 蓝桥杯python语言基础(1)——编程基础
  • (2025 年最新)MacOS Redis Desktop Manager中文版下载,附详细图文
  • 【BQ3568HM开发板】如何在OpenHarmony上通过校园网的上网认证
  • USB鼠标的数据格式
  • React 封装高阶组件 做路由权限控制