【C语言进阶:指针的进阶】你真分得清sizeof和strlen?

news2024/10/6 6:46:16

本章重点内容:

  • 字符指针
  • 指针数组
  • 数组指针
  • 数组传参和指针传参
  • 函数指针
  • 函数指针数组
  • 指向函数指针数组的指针
  • 回调函数
  • 指针和数组面试题的解析

这篇博客 FLASH 将带大家一起来练习一些容易让人凌乱的题目,通过这些题目来进一步加深和巩固对数组,指针,sizeof() 和 strlen() 使用的熟练度。话不多说,开始今天的内容:

简单复习一下数组和指针:

数组:能够存放一组相同类型的元素,数组的大小取决于数组的元素个数和元素类型。

指针:地址/指针变量,大小是4/8个字节。

数组是数组,指针是指针,二者是不等价的。但又存在一定的联系:

数组名是数组首元素的地址,这个地址就可以存放在指针变量中;因此我们就可以使用指针来遍历数组。

数组名:

大部分情况下数组名是数组首元素的地址,但是有两个例外:

  1. sizeof(数组名):这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名:这里的数组名表示整个数组,取出的是整个数组的地址。

⚡指针和数组笔试题解析

一维数组:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//16
	//sizeof(数组名),计算的是数组总大小,单位是字节
	printf("%d\n", sizeof(a + 0));//4/8
	//+0不可以被忽略,因此 a+0 表示的是数组首元素的地址
	printf("%d\n", sizeof(*a));//4
	//a 表示的是数组首元素的地址,相当于 &a[0]
	//*a == *&a[0] == a[0]
	printf("%d\n", sizeof(a + 1));//4/8
	//a 是数组首元素的地址,类型是 int*
	//a+1 就是跳过一个 int* ,是第二个元素的地址
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));//4/8
	//&a 取出的是数组的地址,数组的地址也是地址,大小是4/8个字节
	// int (*pa)[4] = &a
	printf("%d\n", sizeof(*&a));//16
	//*&a == a,sizeof(a)计算的是数组总大小
	printf("%d\n", sizeof(&a + 1));//4/8
	//&a 取出的是整个数组的地址,类型是int (*)[4]
	//&a+1 就跳过整个数组,指向的是紧跟数组后的地址
	printf("%d\n", sizeof(&a[0]));//4/8
	//&a[0] 取出数组首元素的地址
	printf("%d\n", sizeof(&a[0] + 1));//4/8
	//&a[0]+1 取出数组第二个元素的地址
	return 0;
}

字符数组:

必备知识清单:

1. sizeof 计算的是占用内存空间的大小,单位是字节,不关注内存中到底存放的是什么。

2. sizeof 不是函数,是操作符。

3. strlen 是函数。

4. strlen 针对字符串,求的是字符串的长度,本质上统计的是 \0 之前出现的字符个数。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//6
	printf("%d\n", sizeof(arr + 0));//4/8
	//arr+0 是数组首元素的地址
	printf("%d\n", sizeof(*arr));//1
	//arr 数组首元素的地址,*arr 表示数组首元素 
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//4/8
	//&arr 取出的是数组的地址
	printf("%d\n", sizeof(&arr + 1));//4/8
	//&arr+1 跳过一个数组后的地址
	printf("%d\n", sizeof(&arr[0] + 1));//4/8
	//&arr[0] 数组首元素的地址,+1 数组第二个元素的地址

    printf("%d\n", strlen(arr));//随机值
	//arr 数组首元素地址
	printf("%d\n", strlen(arr + 0));//随机值
	//arr+0 数组首元素地址
	printf("%d\n", strlen(*arr));//非法访问
	//*arr 代表首元素,但是 strlen 函数需要的是地址,因此将字符的ASCLL吗作为地址给strlen传去
	printf("%d\n", strlen(arr[1]));//非法访问
	//arr[1] 代表数组第二个元素,但是 strlen 函数需要的是地址,因此将字符的ASCLL吗作为地址给strlen传去
	printf("%d\n", strlen(&arr));//随机值
	//&arr 数组的地址,传给strlen后从起始位置开始计算
	printf("%d\n", strlen(&arr + 1));//随机值-6
	//&arr+1 整个数组后的地址
	printf("%d\n", strlen(&arr[0] + 1));//随机值-1
	//&arr[0]+1 数组第二个元素的地址
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdef";// a,b,c,d,e,f,\0
	printf("%d\n", sizeof(arr));//7
	//sizeof(arr) 计算的是整个数组的大小
	printf("%d\n", sizeof(arr + 0));//4/8
	//arr+0 首元素的地址
	printf("%d\n", sizeof(*arr));//1
	//*arr 数组首元素
	printf("%d\n", sizeof(arr[1]));//1
	//arr[1] 数组第二个元素
	printf("%d\n", sizeof(&arr));//4/8
	//&arr 取出的是整个数组的地址
	printf("%d\n", sizeof(&arr + 1));//4/8
	//&arr+1 整个数组后的地址
	printf("%d\n", sizeof(&arr[0] + 1));//4/8
	//&arr[0]+1 数组第二个元素的地址


	printf("%d\n", strlen(arr));//6
	//arr 首元素的地址
	printf("%d\n", strlen(arr + 0));//6
	//arr+0 首元素的地址
	printf("%d\n", strlen(*arr));//非法访问
	//*arr 代表首元素,但是 strlen 函数需要的是地址,因此将字符的ASCLL吗作为地址给strlen传去
	printf("%d\n", strlen(arr[1]));//非法访问
	//arr[1] 代表数组第二个元素,但是 strlen 函数需要的是地址,因此将字符的ASCLL吗作为地址给strlen传去
	printf("%d\n", strlen(&arr));//6
	//&arr 表示整个数组的地址,从起始位置开始计算
	printf("%d\n", strlen(&arr + 1));//随机值
	//&arr+1 数组后的地址
	printf("%d\n", strlen(&arr[0] + 1));//5
	//&arr[0]+1 数组第二个元素的地址
	return 0;
}

明天继续更……


感谢大家能够看完这篇博客,创作时长,小伙伴们觉得我的博客对你有帮助,不妨留下你的点赞的收藏,关注我,带你了解不一样的C语言。

98b76a6f4a9c4ca88fd93da1188ac6f9.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/389945.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于注解@Transactional事务基本用法

关于概念性的放在最下面,熟读几遍 在使用时候也没多关注,总是加个Transactional 初识下 一般查询 Transactional(propagation Propagation.SUPPORTS) 增删改 Transactional(propagation Propagation.REQUIRED) 当然不能这么马虎 Spring中关于事务的传播 一个个测试,事…

计算机网络第八版——第一章课后题答案(超详细)

第一章 该答案为博主在网络上整理&#xff0c;排版不易&#xff0c;希望大家多多点赞支持。后续将会持续更新&#xff08;可以给博主点个关注~ 【1-01】计算机网络可以向用户提供哪些服务&#xff1f; 解答&#xff1a;这道题没有现成的标准答案&#xff0c;因为可以从不同的…

操作系统——15.FCFS、SJF、HRRN调度算法

这节我们来看一下进程调度的FCFS、SJF、HRRN调度算法 目录 1.概述 2.先来先服务算法&#xff08;FCFS&#xff0c;First Come First Serve&#xff09; 3.短作业优先算法&#xff08;SJF&#xff0c;Shortest Job First&#xff09; 4.高响应比优先算法&#xff08;HRRN&…

Jackson CVE-2018-5968 反序列化漏洞

0x00 前言 同CVE-2017-15095一样&#xff0c;是CVE-2017-7525黑名单绕过的漏洞&#xff0c;主要还是看一下绕过的调用链利用方式。 可以先看&#xff1a; Jackson 反序列化漏洞原理 或者直接看总结也可以&#xff1a; Jackson总结 影响版本&#xff1a;至2.8.11和2.9.x至…

【数据结构】AVL平衡二叉树底层原理以及二叉树的演进之多叉树

1.AVL平衡二叉树底层原理 背景 二叉查找树左右子树极度不平衡&#xff0c;退化成为链表时候&#xff0c;相当于全表扫描&#xff0c;时间复杂度就变为了O(n) 插入速度没影响&#xff0c;但是查询速度变慢&#xff0c;比单链表都慢&#xff0c;每次都要判断左右子树是否为空 需…

java Spring JdbcTemplate配合mysql实现数据批量修改

其实这个操作和批量添加挺像的 调的同一个方法 首先 我们看数据库结构 这是我本地的 mysql 里面有一个test数据库 里面有一张user_list表 然后创建一个java项目 然后 引入对应的JAR包 在src下创建 dao 目录 在下面创建一个接口 叫 BookDao 参考代码如下 package dao;impo…

进程控制~

进程控制 &#xff08;创建、终止&#xff0c;等待&#xff0c;程序替换&#xff09; 进程创建&#xff1a; pid_t fork();父子进程&#xff0c;数据独有&#xff0c;代码共享&#xff0c;各有各的地址 pit_t vfork();父进程阻塞&#xff0c;直到子进程exit退出或者程序替换之…

电力系统稳定性的定义与分类

1电力系统稳定性的定义与分类 IEEE给出电力系统稳定性定义&#xff1a;电力系统稳定性是指电力系统这样的一种能力—对于给定的初始运行状态&#xff0c;经历物理扰动后&#xff0c;系统能够重新获得运行平衡点的状态&#xff0c;同时绝大多数系统变量有界&#xff0c;因此整个…

自己写一个简单的IOC

什么是SpringIOC&#xff1f; 答&#xff1a;IOC即控制反转&#xff0c;就是我们不在手动的去new一个对象&#xff0c;而是将创建对象的权力交给Spring去管理&#xff0c;我们想要一个User类型的对象&#xff0c;就只需要定义一个User类型的变量user1&#xff0c;然后让Spring去…

蓝桥杯-刷题统计

蓝桥杯-刷题统计1、问题描述2、解题思路3、代码实现3.1 方案一&#xff1a;累加方法(超时)3.2 方案二1、问题描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a 道题目, 周六和周日每天做 b 道题目。请你帮小明计算, 按照计划他将在 第几天实现做题数…

KNN学习报告

原理 KNN算法就是在其表征空间中&#xff0c;求K个最邻近的点。根据已知的这几个点对其进行分类。如果其特征参数只有一个&#xff0c;那么就是一维空间。如果其特征参数只有两个&#xff0c;那么就是二维空间。如果其特征参数只有三个&#xff0c;那么就是三维空间。如果其特征…

软件设计师教程(七)计算机系统知识-操作系统知识

软件设计师教程 软件设计师教程&#xff08;一&#xff09;计算机系统知识-计算机系统基础知识 软件设计师教程&#xff08;二&#xff09;计算机系统知识-计算机体系结构 软件设计师教程&#xff08;三&#xff09;计算机系统知识-计算机体系结构 软件设计师教程&#xff08;…

Redis十大类型——Hash常见操作

Redis十大类型——Hash常见操作命令操作简列存放及获取获取健值对长度元素查找列出健值对对数字进行操作赋值hsetnx很明显咯它也是以健值对方式存在的&#xff0c;只不过value也就是值&#xff0c;在这里也变成了一组简直对。 &#x1f34a;个&#x1f330;&#xff1a; 想必多…

【Linux】P3 用户与用户组

用户与用户组root 超级管理员设置超级管理员密码切换到超级管理员sudo 临时使用超级权限用户与用户组用户组管理用户管理getentroot 超级管理员 设置超级管理员密码 登陆后不会自动开启 root 访问权限&#xff0c;需要首先执行如下步骤设定 root 超级管理员密码 1、解除 roo…

【C++】string的使用及其模拟实现

文章目录1. STL的介绍1.1 STL的六大组件1.2 STL的版本1.3 STL的缺陷2. string的使用2.1 为什么要学习string类&#xff1f;2.2 常见构造2.3 Iterator迭代器2.4 Capacity2.5 Modifiers2.6 String operations3. string的模拟实现3.1 构造函数3.2 拷贝构造函数3.3 赋值运算符重载和…

DevOps实战50讲-(2)Jenkins配置

1. Docker镜像方式安装拉取Jenkins镜像docker pull jenkins/jenkins编写docker-compose.ymlversion: "3.1" services:jenkins:image: jenkins/jenkinscontainer_name: jenkinsports:- 8080:8080- 50000:50000volumes:- ./data/:/var/jenkins_home/首次启动会因为数据…

iis之web服务器搭建、部署(详细)~千锋

目录 Web服务器 部署web服务器 实验一 发布一个静态网站 实验二 一台服务器同时发布多个web站点 网站类型 Web服务器 也叫网页服务或HTTP服务器web服务器使用的协议是HTTPHTTP协议端口号&#xff1a;TCP 80、HTTPS协议端口号&#xff1a;TCP 443Web服务器发布软件&…

【备战面试】每日10道面试题打卡-Day4

本篇总结的是Java集合知识相关的面试题&#xff0c;后续也会更新其他相关内容 文章目录1、HashMap在JDK1.7和JDK1.8中有哪些不同&#xff1f;2、HashMap 的长度为什么是2的幂次方&#xff1f;3、HashMap的扩容操作是怎么实现的&#xff1f;4、HashMap是怎么解决哈希冲突的&…

Android 基础知识4-3.5 RadioButton(单选按钮)Checkbox(复选框)详解

一、RadioButton&#xff08;单选按钮&#xff09; 1.1、简介 RadioButton表示单选按钮&#xff0c;是button的子类&#xff0c;每一个按钮都有选择和未选中两种状态&#xff0c;经常与RadioGroup一起使用&#xff0c;否则不能实现其单选功能。RadioGroup继承自LinearLayout&a…

滚动升级回滚

滚动升级回滚 ReplicationController 资源文件 apiVersion: v1 kind: ReplicationController metadata:name: kubia-v1labels:app: kubia spec:replicas: 3template:metadata:name: kubialabels:app: kubiaspec:containers:- image: luksa/kubia:v1name: nodejes --- apiVer…