news 2026/11/4 2:30:18

C语言中指针的理解(4)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言中指针的理解(4)

本节主要是为大家讲解一些之前欠考虑的地方,可以自行选择学习。

一.sizeof与strlen的区别

在初学阶段大家很容易将这两个东西搞混,不都是测量大小和长度用的吗?他俩究其根本有啥区别呢?

首先,sizeof是个操作符,只算占多大空间。而strlen是个库函数,只数到\0为止。

下面我们来具体说一说区别。

1.1 sizeof操作符

sizeof 是 C 语言的操作符,不是函数。它做的事非常纯粹:告诉你一个变量或者一个类型在内存里占多少字节,单位是字节。它只关心占多大地方,完全不管那块内存里装的是什么数据。在我看来,把 sizeof 理解为求大小而非长度比较好。

下面再来介绍一下用法:

int a = 10; printf("%d\n", sizeof(a)); // a 是 int printf("%d\n", sizeof a); // 括号可以省掉 printf("%d\n", sizeof(int)); // 直接写类型

在这里我们要注意一个细节:sizeof 括号里放的是类型时,括号不能省(sizeof(int));放变量时括号可以省(sizeof a)。

1.2 strlen库函数

strlen 是标准库函数,要包含头文件 string.h,它的功能是求字符串长度。它从你给的地址开始,一个字符一个字符往后数,直到碰到 \0 就停下,返回中间数过了多少个字符。在我看来,把 strlen 理解为求长度而非大小比较好。

重点是:它根本不看这块空间有多大,只关注哪里有 \0。如果一直找不到 \0,它就会一直往后越界找下去。

见以下代码:

char arr1[3] = {'a', 'b', 'c'}; // 没有 \0 char arr2[] = "abc"; // 自动带一个 \0 printf("%d\n", strlen(arr1)); // 随机值,越界找 \0 printf("%d\n", strlen(arr2)); // 3 printf("%d\n", sizeof(arr1)); // 3,占 3 字节 printf("%d\n", sizeof(arr2)); // 4,abc 加 \0 共 4 字节

我们来讲解一下:arr1 占 3 字节,但因为没有 \0,strlen 遍历它时根本不知道该在哪停,结果就是个随机值;arr2 虽然只看得到 abc,但字符串自带 \0,所以 sizeof 是 4、strlen 是 3。

1.3 小总结
名称sizeofstrlen
身份操作符库函数
作用求占内存的字节数,不关注里面放了什么求 \0 之前的字符个数

相信通过这次讲解,应该给大家彻底讲明白了 strlen 和 sizeof 的区别。

二.数组名的意义

这里先给大家简单提一下之前讲过的数组名的意义。

1. sizeof(数组名):这里的数组名代表整个数组,算的是整个数组的大小。

2. &数组名:这里的数组名代表整个数组,取出来的是整个数组的地址,它 +1 会跳过整整一个数组。

3. 除此之外的所有情况,数组名都代表“首元素的地址”,它 +1 只跳过一个元素。

2.1 一维整型数组名
int main() { int a[] = { 1,2,3,4 }; printf("%zu\n", sizeof(a)); printf("%zu\n", sizeof(a + 0)); printf("%zu\n", sizeof(*a)); printf("%zu\n", sizeof(a + 1)); printf("%zu\n", sizeof(a[1])); printf("%zu\n", sizeof(&a)); printf("%zu\n", sizeof(*&a)); printf("%zu\n", sizeof(&a + 1)); printf("%zu\n", sizeof(&a[0])); printf("%zu\n", sizeof(&a[0] + 1)); return 0; }

大家看看这些输出应该是啥?(x64 环境下)

这里最容易错的是最后一行:&a[0]+1 只是首元素地址往后跳一个 int,还是地址,所以是 8;而 &a+1 虽然也是地址(8 字节),但它一跳就跳过整个 16 字节的数组。大家不要只觉得自己做对了答案就是会了,一定要知道具体所代表的含义是什么。

2.2 字符数组名
int main() { char arr[] = { 'a','b','c','d','e','f' }; printf("%zu\n", sizeof(arr)); printf("%zu\n", sizeof(arr + 0)); printf("%zu\n", sizeof(*arr)); printf("%zu\n", sizeof(arr[1])); printf("%zu\n", sizeof(&arr)); printf("%zu\n", sizeof(&arr + 1)); printf("%zu\n", sizeof(&arr[0] + 1)); return 0; }

大家看看这些输出应该是啥?(x64 环境下)

如果换成 strlen 再看一遍就更清楚了:strlen(arr) 是随机值,因为这组字符没有 \0;而 sizeof(arr) 永远是 6,跟里面有没有 \0 一点关系都没有。

2.3 字符串指针
int main() { char* p = "abcdef"; printf("%zu\n", sizeof(p)); printf("%zu\n", sizeof(p + 1)); printf("%zu\n", sizeof(*p)); printf("%zu\n", sizeof(p[0])); printf("%zu\n", sizeof(&p)); printf("%zu\n", sizeof(&p + 1)); printf("%d\n", strlen(p)); printf("%d\n", strlen(p + 1)); printf("%d\n", strlen(*p)); printf("%d\n", strlen(p[0])); return 0; }

大家来看看这些输出应该是啥?(依旧 x64 环境)

我来给大家讲解一下:

sizeof(p) // 8,p 本身是个指针 sizeof(p+1) // 8,还是指针 sizeof(*p) // 1,*p 是字符 'a' sizeof(p[0]) // 1,等价于 *p sizeof(&p) // 8,指向指针的指针 sizeof(&p+1) // 8,地址 strlen(p) // 6 strlen(p+1) // 5,从 b 开始数 strlen(*p) // 报错,*p 是字符不是地址 strlen(p[0]) // 报错,p[0] 是字符不是地址

关键区别:char arr[] = “abcdef” 里,arr 是数组,sizeof 它是 7,含 \0;而 char *p = “abcdef” 里,p 是指针,sizeof 它只是 8 字节的地址,字符串常量本身才是 7 字节。

2.4 二维数组名
int main() { int a[3][4]; printf("%zu\n", sizeof(a)); printf("%zu\n", sizeof(a[0][0])); printf("%zu\n", sizeof(a[0])); printf("%zu\n", sizeof(a[0] + 1)); printf("%zu\n", sizeof(a + 1)); printf("%zu\n", sizeof(*(a + 1))); printf("%zu\n", sizeof(*a)); printf("%zu\n", sizeof(a[3])); return 0; }

大家来看看这些输出应该是啥?(依旧 x64 环境)

在这里我们要把每一行看成一个整体:a[0]、a[1] 分别就是第一行、第二行,它们的 sizeof 都是 16(一行的大小);而 a[0]+1 这种行地址加偏移,就退化成了普通元素地址,sizeof 就变成 8。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 2:30:14

本地桌面客户端入门开发

1、Electron框架 官网地址:简介 | Electron 2、创建项目并安装依赖 mkdir my-electron-app cd my-electron-app npm init -y npm install electron electron-builder --save-dev 3. 项目结构 my-electron-app/ ├── package.json ├── main.js └── inde…

作者头像 李华
网站建设 2026/11/4 2:29:39

自注意力机制------Transformer详细介绍

Transformer 是一种完全基于注意力机制(attention)构建的神经网络架构,由编码器和解码器两部分组成:编码器负责把输入序列的每个词元映射为融合全局上下文的表示,解码器则在此基础上逐步生成输出序列。它最核心的创新是…

作者头像 李华
网站建设 2026/11/4 2:27:15

员工调研如何判断无效问卷

摘要:答得快或连续选择同一选项,都不能单独证明员工没有认真作答。肯耐珂萨从问卷路径、质量信号和剔除影响分析有效性判断,帮助HR建立可解释的数据处理规则,避免把不方便理解的意见提前删掉。“答得最快的这些,要不要…

作者头像 李华
网站建设 2026/11/4 2:26:46

AI时代新风口:收藏!FDE工程师带你玩转大模型落地实战

本文介绍了AI领域新兴的FDE(前线部署工程师)岗位,该岗位要求工程师深入客户现场,利用AI技术解决实际问题,而非开发通用产品。文章强调业务理解、客户沟通和快速交付能力的重要性,并指出FDE工程师需要关注结…

作者头像 李华