C 语 言 --- 指 针 4(习 题)

发布于:2025-04-19 ⋅ 阅读:(44) ⋅ 点赞:(0)

💻作 者 简 介:曾 与 你 一 样 迷 茫,现 以 经 验 助 你 入 门 C 语 言
💡个 人 主 页:@笑 口 常 开 xpr 的 个 人 主 页
📚系 列 专 栏:C 启 新 程
✨代 码 趣 语:欲 速 则 不 达,在 编 程 中,耐 心 和 细 心 是 比 速 度 更 重 要 的 品 质。
💪代 码 千 行,始 于 坚 持,每 日 敲 码,进 阶 编 程 之 路。
📦gitee 链 接:gitee

在这里插入图片描述

         在 编 程 的 世 界 里,每 一 行 代 码 都 可 能 隐 藏 着 无 限 的 可 能 性 。你 是 否 想 过,一 个 小 小 的 程 序 究 竟 能 改 变 什 么?它 可 以 是 解 决 复 杂 问 题 的 工 具 ,也 可 以 是 实 现 梦 想 的 桥 梁。今 天,就 让 我 们 一 起 走 进 C 语 言 的 世 界,探 索 它 的 无 限 潜 力。

sizeof

定 义

         sizeof 是 C 语 言 里 的 一 个 运 算 符,并 非 函 数,它 的 作 用 是 计 算 数 据 类 型 或 者 变 量 所 占 内 存 的 字 节 数。

使 用 方 法

计 算 数 据 类 型 的 大 小

sizeof(数据类型);

计 算 变 量 的 大 小

sizeof(变量名);

省 略 括 号

sizeof 变量名;

注 意

sizeof 是 在 编 译 时 计 算 的,所 以 它 不 会 对 表 达 式 进 行 求 值。

strlen

定 义

         strlen 是 C 语 言 标 准 库<string.h> 中 的 一 个 函 数,它 的 主 要 功 能 是 计 算 字 符 串 的 长 度。

函 数 原 型

size_t strlen(const char *str);

参 数:str 是 一 个 指 向 以 ‘\0’( 空 字 符 )结 尾 的 字 符 串 的 指 针。
返 回 值:函 数 返 回 一 个 size_t 类 型 的 值,该 值 表 示 字 符 串 str 中 字 符 的 数 量,不 包 含 字 符 串 结 束 符 ‘\0’。

功 能

         strlen 函 数 会 从 传 入 的 字 符 串 指 针 开 始,逐 个 字 符 地 计 数,直 到 遇 到 字 符 串 结 束 符 ‘\0’ 为 止,然 后 返 回 所 计 的 字 符 数。

注 意

字 符 串 必 须 以 ‘\0’ 结 尾

         strlen 函 数 依 赖 于 字 符 串 结 束 符 ‘\0’ 来 确 定 字 符 串 的 结 束 位 置。如 果 传 入 的 字 符 串 没 有 以 ‘\0’ 结 尾,strlen 函 数 会 继 续 向 后 计 数,直 到 遇 到 内 存 中 的 某 个 ‘\0’ 为 止,这 可 能 会 导 致 未 定 义 行 为。

返 回 值 类 型

         strlen 函 数 的 返 回 值 类 型 是 size_t,这 是 一 个 无 符 号 整 数 类 型。在 进 行 比 较 或 算 术 运 算 时,要 注 意 避 免 有 符 号 整 数 和 无 符 号 整 数 之 间 的 隐 式 转 换 可 能 带 来 的 问 题。

整 型 数 组 - - - int a[ ]

指 针 的 大 小

         指 针 的 大 小 与 指 针 的 类 型 无 关在 32 位 系 统 中 指 针 大 小 一 般 是 4 字 节,在 64 位 系 统 中 指 针 大 小 一 般 是 8 字 节。本 篇 博 客 的 代 码 均 以 64 位 的 系 统 为 例 计 算 指 针 的 大 小。

修 改 32 位 和 64 位 的 系 统

         以 VS2022 为 例,点 击 如 图 所 示 的 方 框,选 择 X64 即 是 64 位 的 系 统,选 择 X86 即 是 32 位 的 系 统。

在这里插入图片描述

下 面 展 示代 码 示 例

#include<stdio.h>
int main()
{
	int a[] = { 1,2,3,4 };
	printf("sizeof(a)         = %zu\n", sizeof(a));      
	printf("sizeof(a + 0)     = %zu\n", sizeof(a + 0));  
	printf("sizeof(*a)        = %zu\n", sizeof(*a));     
	printf("sizeof(a + 1)     = %zu\n", sizeof(a + 1));  
	printf("sizeof(a[1])      = %zu\n", sizeof(a[1]));  
	printf("sizeof(&a)        = %zu\n", sizeof(&a));     
	printf("sizeof(*&a)       = %zu\n", sizeof(*&a));    
	printf("sizeof(&a + 1)    = %zu\n", sizeof(&a + 1)); 
	printf("sizeof(&a[0])     = %zu\n", sizeof(&a[0])); 
	printf("sizeof(&a[0] + 1) = %zu\n", sizeof(&a[0] + 1));
	return 0;
}

温 馨 提 示:读 者 们 ,先 自 己 计 算 结 果,这 是 提 升 编 程 能 力 的 好 机 会。若 未 达 要 求 ,别 气 馁 ,参 考 下 文 解 释 会 有 新 收 获。

在这里插入图片描述

代 码 解 析

sizeof(a)

         a 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。sizeof(a) 计 算 的 是 整 个 数 组 所 占 用 的 内 存 字 节 数。因 为 数 组 a 里 有 4 个 int 类 型 的 元 素,int 类 型 占 4 个 字 节,所 以 sizeof(a) 的 结 果 为 4 * 4 = 16 字节。

sizeof(a + 0)

         a 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。a + 0 实 际 上 就 是 数 组 a 首 元 素 向 后 偏 移 0 * 4 个 字 节 的 指 针,也 就 是 指 向 数 组 首 元 素 的 指 针,是 指 针,所 以 sizeof(a + 0) 是 4 或 者 8 个 字 节。

*sizeof(a)

         a 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。*a 等 同 于 a[0],也 就 是 数 组 a 的 首 元 素。由 于 数 组 元 素 的 类 型 是 int,所 以 sizeof(*a) 计 算 的 是 一 个 int 类 型 变 量 的 大 小,通 常 为 4 个 字 节。

sizeof(a + 1)

         a 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。a + 1 实 际 上 就 是 数 组 a 首 元 素 向 后 偏 移 1 * 4 个 字 节 的 指 针,也 就 是 指 向 数 组 第 二 个 元 素 的 指 针,所 以 sizeof(a + 1) 是 4 或 者 8 个 字 节。

sizeof(a[1])

         a[1] 表 示 数 组 a 的 第 二 个 元 素,其 类 型 为 int。所 以 sizeof(a[1]) 计 算 的 是 一 个 int 类 型 变 量 的 大 小,为 4 个 字 节。

sizeof(&a)

         a 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。&a 是 取 出 整 个 数 组 的 地 址,它 的 类 型 是 int (*)[4]。所 以 sizeof(&a) 是 4 或 者 8 个 字 节。

sizeof(*&a)

         &a 是 指 向 整 个 数 组 的 指 针,对 其 进 行 解 引 用 * &a 得 到 的 就 是 整 个 数 组。所以 sizeof(*&a) 计 算 的 结 果 是 数 组 的 大 小,即 4 * 4 = 16 个 字 节。

sizeof(&a + 1)

         &a 是 指 向 整 个 数 组 的 指 针,&a + 1 跳 过 整 个 数 组 指 向 的 是 数 组 a 后 面 的 空 间,此 时 没 有 越 界 访 问。所 以 sizeof(&a+1) 是 4 或 者 8 个 字 节。

** sizeof(&a[0])**

&a[0] 是 指 向 数 组 a 首 元 素 的 指 针。所 以 sizeof(&a[0]) 是 4 或 者 8 个 字 节。

sizeof(&a[0]+1)

         &a[0] 是 指 向 数 组 a 首 元 素 的 指 针,&a[0] + 1 是 指 向 数 组 a 第 二 个 元 素 的 指 针。sizeof(&a[0]+1) 是 4 或 者 8 个 字 节。

字 符 数 组 - - - char arr[ ]

下 面 展 示代 码 示 例

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("sizeof(arr)         = %zu\n", sizeof(arr));
	printf("sizeof(arr + 0)     = %zu\n", sizeof(arr + 0));
	printf("sizeof(*arr)        = %zu\n", sizeof(*arr));
	printf("sizeof(arr + 1)     = %zu\n", sizeof(arr + 1));
	printf("sizeof(arr[1])      = %zu\n", sizeof(arr[1]));
	printf("sizeof(&arr)        = %zu\n", sizeof(&arr));
	printf("sizeof(&arr + 1)    = %zu\n", sizeof(&arr + 1));
	printf("sizeof(&arr[0] + 1) = %zu\n", sizeof(&arr[0] + 1));
	printf("strlen(arr)         = %zd\n", strlen(arr));
	printf("strlen(arr + 0)     = %zd\n", strlen(arr + 0));
	printf("strlen(*arr)        = %zd\n", strlen(*arr));
	printf("strlen(arr[1])      = %zd\n", strlen(arr[1]));
	printf("strlen(&arr)        = %zd\n", strlen(&arr));
	printf("strlen(&arr + 1)    = %zd\n", strlen(&arr + 1));
	printf("strlen(&arr[0] + 1) = %zd\n", strlen(&arr[0] + 1));
	return 0;
}

温 馨 提 示:读 者 们 ,先 自 己 计 算 结 果,这 是 提 升 编 程 能 力 的 好 机 会。若 未 达 要 求 ,别 气 馁 ,参 考 下 文 解 释 会 有 新 收 获。

在这里插入图片描述

代 码 解 析

sizeof(arr)

         arr 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。sizeof(arr) 计 算 的 是 整 个 数 组 所 占 用 的 内 存 字 节 数。因 为 字 符 数 组 a 里 有 6 个 char 类 型 的 元 素,char 类 型 占 4 个 字 节,所 以 sizeof(arr) 的 结 果 为 6 * 1 = 6 字节。

sizeof(arr + 0)

         arr 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。arr + 0 实 际 上 就 是 数 组 arr 首 元 素 向 后 偏 移 1 * 0 个 字 节 的 指 针,也 就 是 指 向 数 组 首 元 素 的 指 针,是 指 针,所 以 sizeof(a + 0) 是 4 或 者 8 个 字 节。

*sizeof(arr)

         arr 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。*arr 等 同 于 arr[0],也 就 是 数 组 arr 的 首 元 素。由 于 数 组 元 素 的 类 型 是 char,所 以 sizeof(*arr) 计 算 的 是 一 个 char 类 型 变 量 的 大 小,通 常 为 1 个 字 节。

sizeof(arr + 1)

         arr 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。arr + 1 实 际 上 就 是 数 组 arr 首 元 素 向 后 偏 移 1 * 1 个 字 节 的 指 针,也 就 是 指 向 数 组 第 二 个 元 素 的 指 针,所 以 sizeof(arr + 1) 是 4 或 者 8 个 字 节。

sizeof(arr[1])

         arr[1] 表 示 数 组 arr 的 第 二 个 元 素,其 类 型 为 char。所 以 sizeof(arr[1]) 计 算 的 是 一 个 char 类 型 变 量 的 大 小,为 1 个 字 节。

sizeof(&arr)

         arr 是 数 组 名,数 组 名 是 数 组 首 元 素 的 地 址。&arr 是 取 出 整 个 数 组 的 地 址,它 的 类 型 是 char (*)[6]。所 以 sizeof(&arr) 是 4 或 者 8 个 字 节。

sizeof(&arr + 1)

         &arr 是 指 向 整 个 数 组 的 指 针,&arr + 1 跳 过 整 个 数 组 指 向 的 是 数 组 arr 后 面 的 空 间,此 时 没 有 越 界 访 问。所 以 sizeof(&arr+1) 是 4 或 者 8 个 字 节。

sizeof(&arr[0]+1)

         &arr[0] 是 指 向 数 组 arr 首 元 素 的 指 针,&arr[0] + 1 是 指 向 数 组 arr 第 二 个 元 素 的 指 针。sizeof(&arr[0]+1) 是 4 或 者 8 个 字 节。

strlen(arr)

         strlen 用 于 计 算 字 符 串 的 长 度,它 会 从 传 入 的 指 针 所 指 向 的 位 置 开 始,一 直 向 后 查 找 直 到 遇 到 字 符 串 结 束 符 ‘\0’。由 于 arr 数 组 中 没 有 ‘\0’,所 以 它 会 继 续 向 后 查 找,直 到 找 到 ‘\0’ 为 止,所 以 代 码 中 的 结 果 是 随 机 值。

strlen(arr + 0)

         arr + 0 意 味 着 从 数 组 首 元 素 开 始,向 后 偏 移 0 * 1 个 字 节,也 就 是 指 向 数 组 的 首 元 素。strlen(arr + 0) 会 以 该 指 针 所 指 向 的 位 置 作 为 起 始 点,持 续 向 后 查 找,直 至 碰 到 字 符 串 结 束 符 ‘\0’。但 由 于 数 组 arr 里 并 未 包 含 ‘\0’,所 以 该 函 数 会 持 续 在 内 存 中 向 后 查 找,直 至 找 到 ‘\0’ 才 会 停 止。这 就 导 致 代 码 运 行 时,strlen(arr + 0) 的 结 果 是 随 机 的。

*strlen(arr)

         *arr 是 数 组 的 首 元 素 ‘a’,它 是 一 个 字 符,而 strlen 函 数 期 望 的 参 数 是 一 个 指 针,这 里 会 把 字 符 ‘a’ 的 ASCII 值(97)当 作 地 址 传 递 给 strlen 函 数,这 会 导 致 未 定 义 行 为,所 以 导 致 程 序 崩 溃。

strlen(arr[1])

         arr[1] 是 数 组 的 第 二 个 元 素 ‘b’,同 样 是 一 个 字 符,把 字 符 ‘b’ 的 ASCII 值(98)当 作 地 址 传 递 给 strlen 函 数,会 导 致 未 定 义 行 为,所 以 导 致 程 序 崩 溃。

strlen(&arr)

         &arr 是 指 向 整 个 数 组 的 指 针,strlen 函 数 期 望 的 是 指 向 字 符 的 指 针,这 里 会 把 指 向 数 组 的 指 针 当 作 指 向 字 符 的 指 针 处 理,会 导 致 未 定 义 行 为。

strlen(&arr+1)

         &arr + 1 是 将 指 向 整 个 数 组 的 指 针 向 后 移 动 一 个 数 组 的 长 度,然 后 把 这 个 指 针 当 作 指 向 字 符 的 指 针 传 递 给 strlen 函 数,会 导 致 未 定 义 行 为。

strlen(&arr[0]+1)

         &arr[0] + 1 是 指 向 数 组 第 二 个 元 素 的 指 针,由 于 数 组 中 没 有 ‘\0’,会 导 致 未 定 义 行 为,它 会 继 续 向 后 查 找 直 到 找 到 ‘\0’ 为 止。

下 面 展 示修 改 后 的 代 码

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f','\0'};
	printf("sizeof(arr)         = %zu\n", sizeof(arr));
	printf("sizeof(arr + 0)     = %zu\n", sizeof(arr + 0));
	printf("sizeof(*arr)        = %zu\n", sizeof(*arr));
	printf("sizeof(arr + 1)     = %zu\n", sizeof(arr + 1));
	printf("sizeof(arr[1])      = %zu\n", sizeof(arr[1]));
	printf("sizeof(&arr)        = %zu\n", sizeof(&arr));
	printf("sizeof(&arr + 1)    = %zu\n", sizeof(&arr + 1));
	printf("sizeof(&arr[0] + 1) = %zu\n", sizeof(&arr[0] + 1));
	printf("strlen(arr)         = %zd\n", strlen(arr));
	printf("strlen(arr + 0)     = %zd\n", strlen(arr + 0));
	//printf("strlen(*arr)        = %zd\n", strlen(*arr));
	//printf("strlen(arr[1])      = %zd\n", strlen(arr[1]));
	printf("strlen(&arr)        = %zd\n", strlen(&arr));
	printf("strlen(&arr + 1)    = %zd\n", strlen(&arr + 1));
	printf("strlen(&arr[0] + 1) = %zd\n", strlen(&arr[0] + 1));
	return 0;
}

在这里插入图片描述

字 符 数 组 - - - char arr1[ ]

下 面 展 示代 码 示 例

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcdef";
	printf("sizeof(arr1)         = %zu\n", sizeof(arr1));
	printf("sizeof(arr1 + 0)     = %zu\n", sizeof(arr1 + 0));
	printf("sizeof(*arr1)        = %zu\n", sizeof(*arr1));
	printf("sizeof(arr1[1])      = %zu\n", sizeof(arr1[1]));
	printf("sizeof(&arr1)        = %zu\n", sizeof(&arr1));
	printf("sizeof(&arr1 + 1)    = %zu\n", sizeof(&arr1 + 1));
	printf("sizeof(&arr1[0] + 1) = %zu\n", sizeof(&arr1[0] + 1));
	printf("strlen(arr1)         = %zd\n", strlen(arr1));
	printf("strlen(arr1 + 0)     = %zd\n", strlen(arr1 + 0));
	//printf("strlen(*arr1)        = %zd\n", strlen(*arr1));
	//printf("strlen(arr1[1])      = %zd\n", strlen(arr1[1]));
	printf("strlen(&arr1)        = %zd\n", strlen(&arr1));
	printf("strlen(&arr1 + 1)    = %zd\n", strlen(&arr1 + 1));
	printf("strlen(&arr1[0] + 1) = %zd\n", strlen(&arr1[0] + 1));
	return 0;
}

温 馨 提 示:读 者 们 ,先 自 己 计 算 结 果,这 是 提 升 编 程 能 力 的 好 机 会。若 未 达 要 求 ,别 气 馁 ,参 考 下 文 解 释 会 有 新 收 获。

在这里插入图片描述

         需 要 注 意 的 是,与 arr 相 比,arr1 的 末 尾 包 含 ‘\0’,而 arr 末 尾 没 有 ‘\0’。由 于 arr1 和 arr 的 分 析 方 法 相 似,此 处 不 再 重 复 说 明

字 符 串 常 量 指 针 - - - char arr[ ]

下 面 展 示代 码 示 例

#include<stdio.h>
#include<string.h>
int main()
{
	const char* p = "abcdef";
	printf("sizeof(p)         = %zu\n", sizeof(p));
	printf("sizeof(p + 1)     = %zu\n", sizeof(p + 1));
	printf("sizeof(*p)        = %zu\n", sizeof(*p));
	printf("sizeof(p[0])      = %zu\n", sizeof(p[0]));
	printf("sizeof(&p)        = %zu\n", sizeof(&p));
	printf("sizeof(&p + 1)    = %zu\n", sizeof(&p + 1));
	printf("sizeof(&p[0] + 1) = %zu\n", sizeof(&p[0] + 1));
	printf("strlen(p)         = %zd\n", strlen(p));
	printf("strlen(p + 1)     = %zd\n", strlen(p + 1));
	printf("strlen(*p)        = %zd\n", strlen(*p));
	printf("strlen(p[0])      = %zd\n", strlen(p[0]));
	printf("strlen(&p)        = %zd\n", strlen(&p));
	printf("strlen(&p + 1)    = %zd\n", strlen(&p + 1));
	printf("strlen(&p[0] + 1) = %zd\n", strlen(&p[0] + 1));
	return 0;
}

温 馨 提 示:读 者 们 ,先 自 己 计 算 结 果,这 是 提 升 编 程 能 力 的 好 机 会。若 未 达 要 求 ,别 气 馁 ,参 考 下 文 解 释 会 有 新 收 获。

在这里插入图片描述

代 码 解 析

下 面 展 示代 码 解 析

#include<stdio.h>
#include<string.h>
int main()
{
    const char* p = "abcdef";
    //定义一个指向字符串常量"abcdef"的指针 p
    printf("sizeof(p)         = %zu\n", sizeof(p));
    //sizeof(p)
    //p是一个指针,在64位系统中,指针的大小通常是8字节,在32位系统中是4字节
    //sizeof操作符计算的是指针本身所占的内存大小,而不是指针所指向的内容的大小
    printf("sizeof(p + 1)     = %zu\n", sizeof(p + 1));
    //sizeof(p + 1)
    //p + 1是指针运算,它会让指针p向后移动一个字符的位置,但它仍然是一个指针
    //所以sizeof(p + 1)同样是计算指针的大小,结果和sizeof(p)一样
    printf("sizeof(*p)        = %zu\n", sizeof(*p));
    //sizeof(*p)
    //*p是对指针p进行解引用操作,得到的是指针p所指向的第一个字符'a'
    //字符类型在C语言中占1字节,所以sizeof(*p)的结果是 1
    printf("sizeof(p[0])      = %zu\n", sizeof(p[0]));
    //sizeof(p[0])
    //p[0]等价于*(p + 0),也就是指针p所指向的第一个字符'a'
    //字符类型占1字节,所以sizeof(p[0])的结果是1
    printf("sizeof(&p)        = %zu\n", sizeof(&p));
    //sizeof(&p)
    //&p是取指针p的地址,它是一个指向指针的指针
    //但无论是什么类型的指针,在64位系统中大小通常是8字节,32位系统中是4字节
    printf("sizeof(&p + 1)    = %zu\n", sizeof(&p + 1));
    //sizeof(&p + 1)
    //&p + 1是将指向指针p的指针向后移动一个指针大小的位置
    //它仍然是一个指针,所以sizeof(&p + 1)计算的还是指针的大小
    printf("sizeof(&p[0] + 1) = %zu\n", sizeof(&p[0] + 1));
    //sizeof(&p[0] + 1)
    //&p[0]是取指针p所指向的第一个字符的地址,&p[0] + 1是将该地址向后移动一个字符的位置
    //它还是一个指针,因此sizeof(&p[0] + 1)计算的也是指针的大小
    printf("strlen(p)         = %zd\n", strlen(p));
    //strlen(p)
    //strlen函数用于计算字符串的长度,它从指针p所指向的位置开始
    //一直向后查找直到遇到字符串结束符'\0'
    //这里字符串"abcdef"的长度是6,所以strlen(p)的结果是6
    printf("strlen(p + 1)     = %zd\n", strlen(p + 1));
    //strlen(p + 1)
    //p + 1让指针p向后移动一个字符的位置,指向'b'
    //从'b'开始到字符串结束符'\0'的长度是5,所以strlen(p + 1)的结果是5
    printf("strlen(*p)        = %zd\n", strlen(*p));
    //strlen(*p)
    //*p是字符'a',而strlen函数期望的参数是一个指针
    //这里会把字符'a'的ASCII值(97)当作地址传递给strlen函数
    //这会导致未定义行为,会使程序崩溃
    printf("strlen(p[0])      = %zd\n", strlen(p[0]));
    //strlen(p[0])
    //p[0]等价于'a',和strlen(*p)一样,把字符'a'的ASCII值当作地址传递给strlen函数,
    //会导致未定义行为
    printf("strlen(&p)        = %zd\n", strlen(&p));
    //strlen(&p)
    //&p是指向指针p的指针,strlen函数期望的是指向字符的指针
    //把指向指针的指针传递给strlen函数会导致未定义行为
    printf("strlen(&p + 1)    = %zd\n", strlen(&p + 1));
    //strlen(&p + 1)
    //&p + 1是将指向指针p的指针向后移动一个指针大小的位置
    //同样把它传递给strlen函数会导致未定义行为
    printf("strlen(&p[0] + 1) = %zd\n", strlen(&p[0] + 1));
    //strlen(&p[0] + 1)
    //&p[0] + 1指向字符串"abcdef"中的'b'
    //从'b'开始到字符串结束符'\0'的长度是5,所以strlen(&p[0] + 1)的结果是5
    return 0;
}

         与 字 符 数 组 不 同,字 符 常 量 数 组 中 的 值 不 允 许 被 修 改,因 此 通 常 需 要 用 const 关 键 字 修 饰 以 确 保 程 序 的 严 谨 性

二 维 数 组 - - - char arr[3][4]

下 面 展 示代 码 示 例

#include<stdio.h>
int main()
{
	int a[3][4] = { 0 };
	printf("sizeof(a)            = %zu\n", sizeof(a));
	printf("sizeof(a[0][0])      = %zu\n", sizeof(a[0][0]));
	printf("sizeof(a[0])         = %zu\n", sizeof(a[0]));
	printf("sizeof(a[0] + 1)     = %zu\n", sizeof(a[0] + 1));
	printf("sizeof(*(a[0] + 1))  = %zu\n", sizeof(*(a[0] + 1)));
	printf("sizeof(a + 1)        = %zu\n", sizeof(a + 1));
	printf("sizeof(*(a + 1))     = %zu\n", sizeof(*(a + 1)));
	printf("sizeof(&a[0] + 1)    = %zu\n", sizeof(&a[0] + 1));
	printf("sizeof(*(&a[0] + 1)) = %zu\n", sizeof(*(&a[0] + 1)));
	printf("sizeof(*a)           = %zu\n", sizeof(*a));
	printf("sizeof(a[3])         = %zu\n", sizeof(a[3]));
	return 0;
}

温 馨 提 示:读 者 们 ,先 自 己 计 算 结 果,这 是 提 升 编 程 能 力 的 好 机 会。若 未 达 要 求 ,别 气 馁 ,参 考 下 文 解 释 会 有 新 收 获。

在这里插入图片描述

代 码 解 析

下 面 展 示代 码 解 析

#include<stdio.h>
int main()
{
    int a[3][4] = { 0 };
    //定义一个3行4列的二维整型数组a,并初始化为全 0
    printf("sizeof(a)            = %zu\n", sizeof(a));
    //sizeof(a)
    //a代表整个二维数组。二维数组在内存中是连续存储的
    //这里数组有3行4列,每个元素是int类型,假设int占4字节
    //那么整个数组的大小就是3 * 4 * 4 = 48字节
    printf("sizeof(a[0][0])      = %zu\n", sizeof(a[0][0]));
    //sizeof(a[0][0])
    //a[0][0]表示二维数组的第一个元素,也就是数组中第一行第一列的元素
    //它是int类型,int类型占4字节,所以结果是 4
    printf("sizeof(a[0])         = %zu\n", sizeof(a[0]));
    //sizeof(a[0])
    //a[0]可以看作是二维数组第一行的一维数组名。
    //这一行有4个int类型的元素,所以这一行的大小是4 * 4 = 16 字节
    printf("sizeof(a[0] + 1)     = %zu\n", sizeof(a[0] + 1));
    //sizeof(a[0] + 1)
    //a[0]作为一维数组名,是指向第一行第一个元素的指针。
    //a[0] + 1就是将这个指针向后移动一个int类型的位置,指向第一行的第二个元素。
    //但它本质还是一个指针,在64位系统中指针大小通常是8字节,所以结果是8
    printf("sizeof(*(a[0] + 1))  = %zu\n", sizeof(*(a[0] + 1)));
    //sizeof(*(a[0] + 1))
    //*(a[0] + 1)是对a[0] + 1这个指针进行解引用操作,得到的是第一行的第二个元素。
    //它是int类型,所以大小是4字节
    printf("sizeof(a + 1)        = %zu\n", sizeof(a + 1));
    //sizeof(a + 1)
    //a作为二维数组名,在这里隐式转换为指向第一行的指针。
    //a + 1就是将这个指针向后移动一行(也就是4个int元素的位置),指向第二行。
    //它仍然是一个指针,所以大小是8字节(64位系统)
    printf("sizeof(*(a + 1))     = %zu\n", sizeof(*(a + 1)));
    //sizeof(*(a + 1))
    //*(a + 1)是对a + 1这个指针进行解引用操作,得到的是第二行的一维数组。
    //这一行有4个int类型的元素,所以大小是4 * 4 = 16字节
    printf("sizeof(&a[0] + 1)    = %zu\n", sizeof(&a[0] + 1));
    //sizeof(&a[0] + 1)
    //&a[0]是取第一行的地址,它是一个指向包含4个int元素的一维数组的指针。
    //&a[0] + 1就是将这个指针向后移动一行,指向第二行。
    //它还是一个指针,所以大小是8字节(64位系统)
    printf("sizeof(*(&a[0] + 1)) = %zu\n", sizeof(*(&a[0] + 1)));
    //sizeof(*(&a[0] + 1))
    //*(&a[0] + 1)是对&a[0] + 1这个指针进行解引用操作,得到的是第二行的一维数组。
    //这一行有4个int 类型的元素,所以大小是4 * 4 = 16字节
    printf("sizeof(*a)           = %zu\n", sizeof(*a));
    //sizeof(*a)
    //a为指向第一行的指针,*a就是对这个指针进行解引用操作,得到的是第一行的一维数组。
    //这一行有4个int类型的元素,所以大小是4 * 4 = 16字节
    printf("sizeof(a[3])         = %zu\n", sizeof(a[3]));
    //sizeof(a[3])
    //虽然数组a只有3行(索引从0到2),但sizeof是在编译时计算的
    //它只关心a[3]的类型,a[3]从类型上来说和a[0]、a[1]、a[2]一样
    //都是包含4个int元素的一维数组,所以大小是4 * 4 = 16字节
    return 0;
}

总 结

数 组 名 的 意 义

  • sizeof(数组名),这 里 的 数 组 名 表 示 整 个 数 组,计 算 的 是 整 个 数 组 的 大 小。
  • &数组名,这 里 的 数 组 名 表 示 整 个 数 组,取 出 的 是 整 个 数 组 的 地 址。
  • 除 此 之 外 所 有 的 数 组 名 都 表 示 首 元 素 的 地 址 。

在这里插入图片描述

总结

       至 此,关 于 C 语 言 指 针 的 探 索 暂 告 一 段 落,但 你 的 编 程 征 程 才 刚 刚 启 航。写 代 码 是 与 机 器 深 度 对 话,过 程 中 虽 会 在 语 法、算 法 困 境 里 挣 扎,但 这 些 磨 砺 加 深 了 对 代 码 的 理 解。愿 你 合 上 电 脑 后,灵 感 不 断,在 C 语 言 的 世 界 里 持 续 深 耕,书 写 属 于 自 己 的 编 程 传 奇,下 一 次 开 启 ,定 有 全 新 的 精 彩 等 待。小 编 期 待 重 逢,盼 下 次 阅 读 见 你 们 更 大 进 步,共 赴 代 码 之 约!


网站公告

今日签到

点亮在社区的每一天
去签到