深度剖析指针(下)——“C”
各位CSDN的uu们你们好呀,今天小雅兰的内容还是我们的指针呀,上两篇博客我们基本上已经把知识点过了一遍,这篇博客就让小雅兰来带大家看一些和指针有关的题目吧,现在,就让我们进入指针的世界吧
复习:
数组和指针
数组——能够存放一组相同类型的元素,数组的大小取决于数组的元素个数和元素类型
指针——地址/指针变量,大小是4or8个字节
数组是数组,指针是指针,二者不等价
数组名是数组首元素的地址,这个地址就可以存放在指针变量中
可以使用指针来遍历数组
数组名
大部分情况下数组名是数组首元素的地址
但是有两个例外:
- sizeof(数组名)——数组名表示整个数组,计算的是整个数组的大小
- &数组名——数组名表示整个数组,取出的是数组的地址
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{//一维数组int a[] = { 1,2,3,4 };printf("%d\n", sizeof(a));printf("%d\n", sizeof(a + 0));printf("%d\n", sizeof(*a));printf("%d\n", sizeof(a + 1));printf("%d\n", sizeof(a[1]));printf("%d\n", sizeof(&a));printf("%d\n", sizeof(*&a));printf("%d\n", sizeof(&a + 1));printf("%d\n", sizeof(&a[0]));printf("%d\n", sizeof(&a[0] + 1));
}
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16
//sizeof(a)就是数组名单独放在sizeof内部,计算的是数组的总大小,单位是字节
printf("%d\n", sizeof(a + 0));//4or8个字节
//a+0 其实是数组首元素的地址
printf("%d\n", sizeof(*a));//4
//a是数组首元素的地址——&a[0]
//*a-*&a[0]-a[0]
//那么就是一个整形元素的大小,就是4个字节
printf("%d\n", sizeof(a + 1));//4or8
//a是数组首元素的地址-&a[0] int *
//a+1 表示跳过一个整型,是第二个元素的地址
printf("%d\n", sizeof(a[1]));//4
//数组第二个元素
printf("%d\n", sizeof(&a));//4or8
//&a-取出的是数组的地址,但是数组的地址也是地址啊,是地址,大小就是4or8个字节
//int (*pa)[4]=&a;——数组指针
printf("%d\n", sizeof(*&a));//16
//*操作符和&操作符互相抵消,结果就是sizeof(a)
printf("%d\n", sizeof(&a + 1));//4or8
//&a-取出整个数组的地址 int (*)[4]
//&a+1-跳过一个数组
printf("%d\n", sizeof(&a[0]));//4or8
//取出首元素的地址
printf("%d\n", sizeof(&a[0] + 1));//4or8
//第二个元素的地址
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{//字符数组char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", sizeof(arr));printf("%d\n", sizeof(arr + 0));printf("%d\n", sizeof(*arr));printf("%d\n", sizeof(arr[1]));printf("%d\n", sizeof(&arr));printf("%d\n", sizeof(&arr + 1));printf("%d\n", sizeof(&arr[0] + 1));return 0;
}
- sizeof计算的是占用内存空间的大小,单位是字节,不关注内存中到底存放的是什么
- sizeof不是函数,是操作符
- strlen是函数
- strlen是针对字符串的,求的是字符串的长度,本质上统计的是\0之前出现的字符
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6
//数组的总大小
printf("%d\n", sizeof(arr + 0));//4or8
//数组名是首元素的地址
//arr+0 表示数组首元素的地址
printf("%d\n", sizeof(*arr));//1
//数组名表示数组首元素的地址-&arr[0]
//*arr就是数组的第一个元素,就是求首元素的大小
printf("%d\n", sizeof(arr[1]));//1
//数组的第二个元素
printf("%d\n", sizeof(&arr));//4or8
//&arr取出的是整个数组的地址
printf("%d\n", sizeof(&arr + 1));//4or8
//&arr+1-跳过一个数组
printf("%d\n", sizeof(&arr[0] + 1));//4or8
//数组第二个元素的地址
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{//字符数组char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", strlen(arr));printf("%d\n", strlen(arr + 0));printf("%d\n", strlen(*arr));printf("%d\n", strlen(arr[1]));printf("%d\n", strlen(&arr));printf("%d\n", strlen(&arr + 1));printf("%d\n", strlen(&arr[0] + 1));return 0;
}
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));//随机值
printf("%d\n", strlen(arr + 0));//随机值
printf("%d\n", strlen(*arr));//err
//*arr就表示字符a,字符a的ASCII码值是97
//就是说,把内存为97的地址访问了,这是一个非法访问
printf("%d\n", strlen(arr[1]));//err
//字符b的ASCII码值为98,把98当成了地址
//又非法访问了
printf("%d\n", strlen(&arr));//随机值
//取出的是整个数组的地址
printf("%d\n", strlen(&arr + 1));//随机值
//&arr+1-跳过一个数组
//这个随机值和上面的随机值比起来,应该是:随机值-6
printf("%d\n", strlen(&arr[0] + 1));//随机值
//从字符b往后数,还是一个随机值
//这个随机值和上面的随机值比起来,应该是:随机值-1
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{char arr[] = "abcdef";//a b c d e f \0printf("%d\n", sizeof(arr));printf("%d\n", sizeof(arr + 0));printf("%d\n", sizeof(*arr));printf("%d\n", sizeof(arr[1]));printf("%d\n", sizeof(&arr));printf("%d\n", sizeof(&arr + 1));printf("%d\n", sizeof(&arr[0] + 1));return 0;
}
char arr[] = "abcdef";
//a b c d e f \0
printf("%d\n", sizeof(arr));//7
//计算的是数组总元素的大小,\0也算
printf("%d\n", sizeof(arr + 0));//4or8
//计算的是数组首元素的地址
printf("%d\n", sizeof(*arr));//1
//*arr就是数组首元素,计算的是第一个元素的大小
//arr[0]——*(arr+0)
//求元素个数
//int sz=sizeof(arr)/sizeof(arr[0]);
//int sz=sizeof(arr)/sizeof(*arr);
printf("%d\n", sizeof(arr[1]));//1
//计算的是数组第二个元素的大小
printf("%d\n", sizeof(&arr));//4or8
//取出的是整个数组的地址,是地址就是4个或者8个字节
printf("%d\n", sizeof(&arr + 1));//4or8
//跳过一个数组,但还是地址
printf("%d\n", sizeof(&arr[0] + 1));//4or8
//数组第二个元素的地址
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "abcdef";printf("%d\n", strlen(arr));printf("%d\n", strlen(arr + 0));printf("%d\n", strlen(*arr));printf("%d\n", strlen(arr[1]));printf("%d\n", strlen(&arr));printf("%d\n", strlen(&arr + 1));printf("%d\n", strlen(&arr[0] + 1));return 0;
}
char arr[] = "abcdef";
//a b c d e f \0
printf("%d\n", strlen(arr));//6
//找\0
printf("%d\n", strlen(arr + 0));//6
printf("%d\n", strlen(*arr));//err
//求的是数组首元素,把首元素当成了地址,形成了非法访问
printf("%d\n", strlen(arr[1]));//err
//求的是数组第二个元素
printf("%d\n", strlen(&arr));//6
//&arr-char (*)[7]
//也是数到\0就停止了
printf("%d\n", strlen(&arr + 1));//随机值
printf("%d\n", strlen(&arr[0] + 1));//5
//从数组第二个元素开始数,数到\0
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{char* p = "abcdef";printf("%d\n", sizeof(p));printf("%d\n", sizeof(p + 1));printf("%d\n", sizeof(*p));printf("%d\n", sizeof(p[0]));printf("%d\n", sizeof(&p));printf("%d\n", sizeof(&p + 1));printf("%d\n", sizeof(&p[0] + 1));return 0;
}
char* p = "abcdef";
//把首字符a的地址放在p变量中,p是一个指针变量
printf("%d\n", sizeof(p));//4or8
//计算的是指针变量的大小,也就是计算a的地址的大小
printf("%d\n", sizeof(p + 1));//4or8
//计算的是字符b的地址的大小
printf("%d\n", sizeof(*p));//1
//p是一个指针变量,里面存放的是a的地址
//p解引用之后就是元素a,字符a的大小是一个字节
printf("%d\n", sizeof(p[0]));//1
//可以把p[0]理解为*(p+0)
//也就是字符a,字符a的大小是1个字节
printf("%d\n", sizeof(&p));//4or8
//取出的是p的地址
printf("%d\n", sizeof(&p + 1));//4or8
//p-char *
//&p-char **
//char * p;
//char * *pp=&p;
//&p+1跳过一个char*的元素
//反正还是地址
printf("%d\n", sizeof(&p[0] + 1));//4or8
//第二个元素的地址
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{char* p = "abcdef";printf("%d\n", strlen(p));printf("%d\n", strlen(p + 1));printf("%d\n", strlen(*p));printf("%d\n", strlen(p[0]));printf("%d\n", strlen(&p));printf("%d\n", strlen(&p + 1));printf("%d\n", strlen(&p[0] + 1));return 0;
}
char* p = "abcdef";
printf("%d\n", strlen(p));//6
//p是a的地址
printf("%d\n", strlen(p + 1));//5
//p+1是b的地址
printf("%d\n", strlen(*p));//err
//字符a 非法访问了
printf("%d\n", strlen(p[0]));//err
//字符a 非法访问了
printf("%d\n", strlen(&p));//随机值
//a的地址的地址,什么时候遇到\0完全是不可知的
printf("%d\n", strlen(&p + 1));//随机值
//跳过p变量
//这两个随机值是没有关系的
printf("%d\n", strlen(&p[0] + 1));//5
//从字符b往后数,数到\0
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{//二维数组int a[3][4] = { 0 };printf("%d\n", sizeof(a));printf("%d\n", sizeof(a[0][0]));printf("%d\n", sizeof(a[0]));printf("%d\n", sizeof(a[0] + 1));printf("%d\n", sizeof(*(a[0] + 1)));printf("%d\n", sizeof(a + 1));printf("%d\n", sizeof(*(a + 1)));printf("%d\n", sizeof(&a[0] + 1));printf("%d\n", sizeof(*(&a[0] + 1)));printf("%d\n", sizeof(*a));printf("%d\n", sizeof(a[3]));return 0;
}
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//48——3*4*4
//a这个二维数组的数组名单独放在sizeof内部,计算的是二维数组的总大小
printf("%d\n", sizeof(a[0][0]));//4
//第一行第一个元素
printf("%d\n", sizeof(a[0]));//16
//a[0]是第一行的数组名,这时数组名单独放在sizeof内部了
//计算的是数组的大小,单位是字节
//计算的是第一行的大小
printf("%d\n", sizeof(a[0] + 1));//4or8
//a[0]不是单独放在sizeof内部,a[0]表示首元素的地址
//也就是第一行第一个元素的地址,即&a[0][0]
//那么,a[0]+1就是第一行第二个元素的地址,也就是&a[0][1]
printf("%d\n", sizeof(*(a[0] + 1)));//4
//第一行第二个元素
printf("%d\n", sizeof(a + 1));//4or8
//a作为二维数组的数组名并非单独放在sizeof内部,所以表示首元素的地址
//二维数组的首元素是第一行,这里的a就是第一行的地址——int (*)[4]
//a+1是跳过第一行,指向了第二行
//所以是第二行的地址
printf("%d\n", sizeof(*(a + 1)));//16
//第二行的元素得大小 4*4
//*(a+1)——a[1]
printf("%d\n", sizeof(&a[0] + 1));//4or8
//取出第一行的地址,&a[0]+1是第二行的地址
printf("%d\n", sizeof(*(&a[0] + 1)));//16
//第二行的元素的大小
printf("%d\n", sizeof(*a));//16
//*a 数组名表示首元素的地址,a就表示二维数组第一行的地址
//解引用就是第一行的元素
printf("%d\n", sizeof(a[3]));//16
//第四行的数组名
//不存在越界
//因为,sizeof内部的表达式不会真的计算
//所以,编译器压根不会去访问第四行,而是直接根据类型属性判断
好啦,小雅兰今天的内容就到这里啦,指针系列的博客真的花了小雅兰超级多的时间,未来还要继续加油呀!!!
相关文章:

深度剖析指针(下)——“C”
各位CSDN的uu们你们好呀,今天小雅兰的内容还是我们的指针呀,上两篇博客我们基本上已经把知识点过了一遍,这篇博客就让小雅兰来带大家看一些和指针有关的题目吧,现在,就让我们进入指针的世界吧 复习: 数组和…...
爬虫与反爬虫技术简介
互联网的大数据时代的来临,网络爬虫也成了互联网中一个重要行业,它是一种自动获取网页数据信息的爬虫程序,是网站搜索引擎的重要组成部分。通过爬虫,可以获取自己想要的相关数据信息,让爬虫协助自己的工作,…...

Pag的2D渲染执行流程
Pag的渲染 背景 根据Pag文章里面说的,Pag之前长时间使用的Skia库作为底层渲染引擎。但由于Skia库体积过大,为了保证通用型(比如兼容CPU渲染)做了很多额外的事情。所以Pag的工程师们自己实现了一套2D图形框架替换掉Skiaÿ…...
k8s 概念说明,k8s面试题
什么是Kubernetes? Kubernetes是一种开源容器编排系统,可自动化应用程序的部署、扩展和管理。 Kubernetes 中的 Master 组件有哪些? Kubernetes 中的 Master 组件包括 API Server、etcd、Scheduler 和 Controller Manager。 Kubernetes 中的…...

Docker--(四)--搭建私有仓库(registry、harbor)
私有仓库----registry官方提供registry仓库管理(推送、删除、下载)私有仓库----harbor私有镜像仓库1.私有仓库----registry官方提供 Docker hub官方已提供容器镜像registry,用于搭建私有仓库 1.1 镜像拉取、运行、查看信息、测试 (一) 拉取镜像 # dock…...

Invalid <url-pattern> [sso.action] in filter mapping
Tomcat 8.5.86版本启动web项目报错Caused by: java.lang.IllegalArgumentException: Invalid <url-pattern> [sso.action] in filter mapping 查看项目的web.xml文件相关片段 <filter-mapping><filter-name>SSOFilter</filter-name><url-pattern&g…...

【11】linux命令每日分享——useradd添加用户
大家好,这里是sdust-vrlab,Linux是一种免费使用和自由传播的类UNIX操作系统,Linux的基本思想有两点:一切都是文件;每个文件都有确定的用途;linux涉及到IT行业的方方面面,在我们日常的学习中&…...

Newman+Jenkins实现接口自动化测试
一、是什么Newman Newman就是纽曼手机这个经典牌子,哈哈,开玩笑啦。。。别当真,简单地说Newman就是命令行版的Postman,查看官网地址。 Newman可以使用Postman导出的collection文件直接在命令行运行,把Postman界面化运…...
MySQL:事务+@Transactional注解
事务 本章从了解为什么需要事务到讲述事务的四大特性和概念,最后讲述MySQL中的事务使用语法以及一些需要注意的性质。 再额外讲述一点Springboot中Transactional注解的使用。 1.为什么需要事务? 我们以用户转账为例,假设用户A和用户B的银行账…...

数字IC手撕代码--低功耗设计 Clock Gating
背景介绍芯片功耗组成中,有高达 40%甚至更多是由时钟树消耗掉的。这个结果的原因也很直观,因 为这些时钟树在系统中具有最高的切换频率,而且有很多时钟 buffer,而且为了最小化时钟 延时,它们通常具有很高的驱动强度。 …...

易基因|m6A RNA甲基化研究的数据挖掘思路:干货系列
大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。关于m6A甲基化研究思路(1)整体把握m6A甲基化图谱特征:m6A peak数量变化、m6A修饰基因数量变化、单个基因m6A peak数量分析、m6A peak在基因元件上的分布…...

【微信小程序】-- 页面配置(十八)
💌 所属专栏:【微信小程序开发教程】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &…...
玩好 StarRocks,大厂 offer 接不完!|字节跳动、小红书、京东物流、唯品会、腾讯音乐要的就是你!
求职黄金季即将到来,你准备好迎接你的 dream offer 了吗?StarRocks 自创立以来,一直主张为用户创造极速统一的数据分析新范式,让数据驱动创新,而优秀的大数据人才对推动创新有着至关重要的作用。因此,我们推…...

C# IoC控制反转学习笔记
一、什么是IOC IoC-Invertion of Control,即控制反转,是一种程序设计思想。 先初步了解几个概念: 依赖(Dependency):就是有联系,表示一个类依赖于另一个类。 依赖倒置原则(DIP&a…...
Python解题 - CSDN周赛第33期
本期四道题全考过,题解在网上也都搜得到。。。没有想法,顺手水一份题解吧。 第一题:奇偶排序 给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。 输入描述:第一行输入整数n。(1<n<…...
Session攻击
Session攻击Session攻击简介主要攻击方式会话预测会话劫持中间人攻击会话固定Session攻击简介 Session对于Web应用是最重要的,也是最复杂的。对于Web应用程序来说,加强安全性的首要原则就是:不要信任来自客户端的数据,一定要进行数据验证以及…...

【Linux】Shell详解
😊😊作者简介😊😊 : 大家好,我是南瓜籽,一个在校大二学生,我将会持续分享Java相关知识。 🎉🎉个人主页🎉🎉 : 南瓜籽的主页…...
汉字找不同隐私协议
本隐私信息保护政策版本:2021 V1 一、重要提示 请您(以下亦称“用户”)在使用本平台App时仔细阅读本协议之全部条款,并确认您已完全理解本协议之规定,尤其是涉及您的重大权益及义务的加粗或划线条款。如您对协议有任…...

CEC2017:斑马优化算法(Zebra Optimization Algorithm,ZOA)求解cec2017(提供MATLAB代码)
一、斑马优化算法 斑马优化算法(Zebra Optimization Algorithm,ZOA)Eva Trojovsk等人于2022年提出,其模拟斑马的觅食和对捕食者攻击的防御行为。 斑马因身上有起保护作用的斑纹而得名。没有任何动物比斑马的皮毛更与众不同。斑…...

【Linux要笑着学】进程创建 | 进程终止 | slab分派器
爆笑教程《看表情包学Linux》👈 猛戳订阅!💭 写在前面:本章我们主要讲解进程的创建与终止。首先讲解进程创建,fork 函数是我们早在讲解 "进程的概念" 章节就提到过的一个函数&#…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

C++--string的模拟实现
一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现,其目的是加强对string的底层了解,以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量,…...