【重生之我要苦学C语言】深入理解指针6

深入理解指针6

sizeof和strlen的对比

sizeof

操作符
整型:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int a = 10;printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(int));printf("%zd\n", sizeof a );return 0;
}

在这里插入图片描述

字符串:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {char arr[] = "abcdef";//a b c d e f \0printf("%zd\n", sizeof(arr));return 0;
}

输出为 7

strlen

库函数
只能求字符串长度

size_t strlen(const char* str);

strlen统计的是str后,\0之前字符串的个数
strlen函数会一直向后找\0字符,直到找到为止,可能存在越界查找

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

输出为:

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {char arr[] = { 'a','b','c' };//a b c printf("%zd\n", sizeof(arr));printf("%zd\n", strlen(arr));return 0;
}

strlen越界访问

在这里插入图片描述

总结
  • sizeof是操作符
  • strlen是库函数,使用时需要包含string.h
  • sizeof计算操作数所占内存大小,单位是字节
  • strlen是求字符串长度的,统计的是\0之前字符的个数
  • sizeof不关注内存中存放什么数据
  • sizeof关注内存中是否有\0,如果没有\0,就会持续往后找,可能会越界

数组和指针中sizeof和strlen辨析

1

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int a[] = { 1,2,3,4 };printf("%zd\n", sizeof(a));//16printf("%zd\n", sizeof(a + 0));//X86——4 X64——8//a做为数组名,并未单独放在sizeof内部,a是数组首元素的地址,a+0是数组首元素的地址printf("%zd\n", sizeof(*a));//4//a是数组首元素的地址 *a首元素printf("%zd\n", sizeof(a + 1));//X86——4 X64——8//第二个元素的的地址printf("%zd\n", sizeof(a[1]));//4//a[1]第二个元素printf("%zd\n", sizeof(&a));//X86——4 X64——8//&a整个数组的地址,是地址,长度就是4/8个字节//&a+1跳过16个字节printf("%zd\n", sizeof(*&a));//16 sizeof(a)printf("%zd\n", sizeof(&a + 1));//X86——4 X64——8printf("%zd\n", sizeof(&a[0]));//X86——4 X64——8printf("%zd\n", sizeof(&a[0] + 1));//X86——4 X64——8return 0;
}

数组名的理解:
数组名是数组首元素的地址,但是有两个例外:
1.sizeof(数组名),数组名表示整个数组
2.&数组名,数组名表示整个数组

2

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {char arr[] = { 'a','b','c','d','e','f' };printf("%zd\n", sizeof(arr));//6//计算整个数组的大小printf("%zd\n", sizeof(arr+0));//X86——4 X64——8//首元素地址printf("%zd\n", sizeof(*arr));//1//首元素printf("%zd\n", sizeof(arr[1]));//1//第二个元素printf("%zd\n", sizeof(&arr));//X86——4 X64——8//数组的地址printf("%zd\n", sizeof(&arr+1));//X86——4 X64——8printf("%zd\n", sizeof(&arr[0]+1));//X86——4 X64——8return 0;
}

3

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", strlen(arr));//随机值 strlen找\0printf("%d\n", strlen(arr+0));//随机值printf("%d\n", strlen(*arr));//*arr——'a'——97//strlen把97当成地址,非法访问 errorprintf("%d\n", strlen(arr[1]));//errorprintf("%d\n", strlen(&arr));//随机值printf("%d\n", strlen(&arr+1));//随机值printf("%d\n", strlen(&arr[0]+1));//随机值return 0;
}

4

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {char arr[] = "abcdef";//a b c d e f \0printf("%zd\n", sizeof(arr));//7printf("%zd\n", sizeof(arr+0));//X86——4 X64——8printf("%zd\n", sizeof(*arr));//1printf("%zd\n", sizeof(arr[1]));//1printf("%zd\n", sizeof(&arr));//X86——4 X64——8printf("%zd\n", sizeof(&arr+1));//X86——4 X64——8printf("%zd\n", sizeof(&arr[0]+1));//X86——4 X64——8return 0;
}

5

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {char arr[] = "abcdef";printf("%zd\n", strlen(arr));//6printf("%zd\n", strlen(arr+0));//6printf("%zd\n", strlen(*arr));//errorprintf("%zd\n", strlen(arr[1]));//errorprintf("%zd\n", strlen(&arr));//6//&arr——char(*)[7]//strlen(const char* str)警告printf("%zd\n", strlen(&arr+1));//随机值//&arr+1跳过整个数组printf("%zd\n", strlen(&arr[0]+1));//5return 0;
}

6

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {char* p = "abcdef";printf("%zd\n", sizeof(p));//X86——4 X64——8//计算的是p这个指针变量的大小printf("%zd\n", sizeof(p+1));//X86——4 X64——8//p+1是第二个元素的地址printf("%zd\n", sizeof(*p));//1printf("%zd\n", sizeof(p[0]));//X86——4 X64——8printf("%zd\n", sizeof(&p));//X86——4 X64——8printf("%zd\n", sizeof(&p+1));//X86——4 X64——8printf("%zd\n", sizeof(&p[0]+1));//X86——4 X64——8return 0;
}

7

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {char* p = "abcdef"printf("%zd\n", strlen(p));//6printf("%zd\n", strlen(p+1));//5printf("%zd\n", strlen(*p));//errorprintf("%zd\n", strlen(p[0]));//errorprintf("%zd\n", strlen(&p));//随机值printf("%zd\n", strlen(&p+1));//随机值printf("%zd\n", strlen(&p[0]+1));//5return 0;
}

二维数组中sizeof和strlen辨析

8

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int a[3][4] = { 0 };printf("%zd\n", sizeof(a));//48//a数组名,单独放在sizeof里,表示整个数组,计算的是整个数组的大小printf("%zd\n", sizeof(a[0][0]));//4//a[0][0]第一行第一个元素printf("%zd\n", sizeof(a[0]));.//16//a[0]第一行数组名,单独放在sizeof内部,计算的是第一行的大小printf("%zd\n", sizeof(a[0]+1));//X86——4 X64——8//a[0]不是单独放在sizeof内部,a[0]就是首元素的地址,a[0][0]的地址,a[0]+1第一行第二个元素的地址printf("%zd\n", sizeof(*(a[0]+1)));//4 //a[0]+1是a[0][1]的地址,*(a[0]+1)就是a[0][1]printf("%zd\n", sizeof(a+1));//X86——4 X64——8//a是二维数组第一行的地址 a+1是第二行的地址printf("%zd\n", sizeof(*(a+1)));//16//计算的是第二行的大小printf("%zd\n", sizeof(&a[0]+1));//X86——4 X64——8//&a[0]第一行的地址 &a[0]+1第二行的地址printf("%zd\n", sizeof(*(&a[0]+1)));//16printf("%zd\n", sizeof(*a));//16//a是二维数组第一行的的地址 *a就是行,计算的是第一行的大小printf("%zd\n", sizeof(a[3]));//16//sizeof在计算的时候是根据类型计算长度的,即使写的是一个表达式,编译器也会推算出最后的类型来计算长度return 0;
}

指针运用笔试题

例1

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int a[5] = { 1,2,3,4,5 };int* ptr = (int*)(&a + 1);printf("%d %d", *(a + 1), *(ptr - 1));//2 5return 0;
}

例2 指针+1

X86环境下

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}*p=(struct Test*)0x100000;
int main() {printf("%p\n", p + 0x1);//结构体指针+1跳过20个字节 0x100014printf("%p\n", (unsigned long)p+0x1);//0x100001printf("%p\n",(unsigned int*) p + 0x1);//跳过四个字节 0x100004return 0;
}

例3

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int a[3][2] = { (0,1),(2,3),(4,5) };//逗号表达式      1    3    //               5    0//               0    0int* p;p = a[0];printf("%d", p[0]);//1return 0;
}

例4 指针-指针

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int a[5][5];int(*p)[4];//数组指针,指向的数组里有四个int类型的元素p = a;printf("%p %d\n", &p[4][2]-&a[4][2],&p[4][2]-&a[4][2]);//FFFFFFFC -4return 0;
}

在这里插入图片描述

例5

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 };int* ptr1 = (int*)(&aa + 1);int* ptr2 = (int*)(*(aa + 1));//第二行地址printf("%d %d", *(ptr1 - 1), *(ptr2 - 1));//10 5return 0;
}

例6

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {char* a[] = { "work","at","c" };char** pa = a;pa++;printf("%s\n", *pa);//atreturn 0;
}

例7

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {char* c[] = { "ENTER","NEW","POINT","FIRST"};char** cp[] = { c + 3,c + 2,c + 1,c };char*** cpp = cp;printf("%s\n", **++cpp);//POINTreturn 0;
}

在这里插入图片描述

	printf("%s\n", *-- * ++cpp + 3);//ER

在这里插入图片描述

	printf("%s\n", *cpp[-2] + 3);//ST//**(cpp-2)+3

在这里插入图片描述

printf("%s\n", cpp[-1][-1] + 1);//EW
//*(*cpp-1)-1)+1

在这里插入图片描述

END……

世界上有太多孤独的人,害怕先踏出第一步。
There are too many lonely people in the world who afraid to take the first step.
——《绿皮书》

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

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

相关文章

虚拟展厅赋能线上品牌发布会,打造沉浸式体验

线上品牌发布会与虚拟展厅的结合&#xff0c;为企业提供了一个全新的、高效的品牌展示和营销平台。视创云展巧妙融合了3D导览、720全景沉浸体验、虚拟数字人交互、音视频通话以及个性化的互动功能&#xff0c;打造极具沉浸感的线上虚拟品牌发布会&#xff0c;深度赋能体验经济时…

shell编程(3)脚本参数传递与数学运算

声明!!! 学习视频来自B站UP主泷羽sec&#xff0c;如涉及侵权马上删除文章 视频链接&#xff1a;泷羽sec 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 # 向脚本程序传参 脚本如下&#xff1a; echo 执行的文件名…

CTF-Crypto-affine

首页看描述 一个数学方程和一个flag&#xff0c;应该就是密文构成 y 17x-8 flag{szzyfimhyzd} e一下题目&#xff0c;字典给了一个线索&#xff0c;仿射&#xff0c;那应该就是仿射密码 e一下原理 简单来说&#xff0c;该加密方式&#xff0c;需要两个秘钥来进行加密和解密&a…

YOLOv8改进,YOLOv8结合DynamicConv(动态卷积),CVPR2024,二次创新C2f结构

摘要 大规模视觉预训练显著提高了大规模视觉模型的性能。现有的低 FLOPs 模型无法从大规模预训练中受益。在本文中,作者提出了一种新的设计原则,称为 ParameterNet,旨在通过最小化FLOPs的增加来增加大规模视觉预训练模型中的参数数量。利用 DynamicConv 动态卷积将额外的参…

【AI数字人整合包及教程】EchoMimic:开启数字人新纪元

在当今数字化转型的浪潮中&#xff0c;人工智能技术正以前所未有的速度重塑我们的生活方式。其中&#xff0c;阿里巴巴旗下蚂蚁集团推出的一款名为EchoMimic的开源AI数字人项目&#xff0c;正在引领一场前所未有的技术革命。本文将深入探讨EchoMimic的技术特点&#xff0c;与其…

linux逻辑卷练习

目录 知识点&#xff1a; 常用命令 题目&#xff1a; 解题&#xff1a; 1&#xff09;分区 2&#xff09;创建物理卷 3&#xff09;创建卷组 4&#xff09;生成逻辑卷 "要带参数 -n" 5&#xff09;扩容 6&#xff09;格式化(添加文件系统) 7&#xff09;挂…

【MySQL】SQL语言

【MySQL】SQL语言 文章目录 【MySQL】SQL语言前言一、SQL的通用语法二、SQL的分类三、SQLDDLDMLDQLDCL 总结 前言 本篇文章将讲到SQL语言&#xff0c;包括SQL的通用语法,SQL的分类,以及SQL语言的DDL,DML,DQL,DCL。 一、SQL的通用语法 在学习具体的SQL语句之前&#xff0c;先来…

51单片机基础04 LCD1602时序;Proteus仿真单片机、总线、网络标号等;

目录 一、LCD显示字符 1、写指令 &#xff08;1&#xff09;、LCD状态配置 &#xff08;2&#xff09;、显示开关与光标 2、写数据 &#xff08;1&#xff09;、设置地址 &#xff08;2&#xff09;、设置数据 3、初始化代码 &#xff08;1&#xff09;、初始化流程 …

性能优化(二):ANR

介绍 ANR全称Application Not Responding&#xff0c;意思就是程序未响应。如果一个应用无法响应用户的输入&#xff0c;系统就会弹出一个ANR对话框&#xff0c;用户可以自行选择继续等待亦或者是停止当前程序。 Android系统会监控程序的响应状况&#xff0c;一旦出现下面情况…

哑光电影人像自拍风景摄影后期Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 哑光电影人像自拍风景摄影后期调色旨在通过 Lightroom 软件为照片营造出一种具有电影质感的哑光效果&#xff0c;同时突出人像与风景的融合之美。 预设信息 调色风格&#xff1a;电影风格预设适合类型&#xff1a;人像&#xff0c;风光&#xff0c;自拍&#xff0c;…

二五、pxe自动装机

pxe自动装机 pxe------------------------------自动安装系统必要的运行环境 无人值守--------------------为系统定制化的安装需要的软件 pxe的优点&#xff1a; 1、规模化&#xff1a;同时装配多台服务器&#xff08;20-30&#xff09; 2、自动化&#xff1a;系统安装和…

Cadence安装

记录一下安装过程&#xff0c;方便以后安装使用Cadence。 去吴川斌的博客下载安装包&#xff0c;吴川斌博客&#xff1a; https://www.mr-wu.cn/cadence-orcad-allegro-resource-downloads/ 下载阿狸狗破戒大师 我这边下载的是版本V3.2.6&#xff0c;同样在吴川斌的博客下载安装…

VScode-Java开发常用插件

中文——界面易读 字体主题——代码可观 头注释——项目信息明了 java开发包——java必备 git协作开发——版本控制

19.UE5道具掉落

2-21 道具掉落&#xff0c;回血、回蓝、升级提升伤害_哔哩哔哩_bilibili 目录 1.道具的创建&#xff0c;道具功能的实现 2.随机掉落 1.道具的创建&#xff0c;道具功能的实现 新建Actor蓝图&#xff0c;并命名为道具总类&#xff0c;添加一个Niagara粒子组件和一个碰撞箱bo…

算法--分解数字

#分解5位整数 12345# 定义一个函数x&#xff0c;用于将一个整数n转换为一个列表&#xff0c;列表中的元素是n的每一位数字 def x(n):# 如果n小于10&#xff0c;说明n是一个一位数&#xff0c;直接创建一个包含n的列表并返回if n < 10:list1 [] # 创建一个空列表list1.appe…

protobuf序列化

Protocol Buffers (protobuf) 是一种由 Google 开发的轻便、高效的结构化数据序列化格式&#xff0c;常用于数据存储或在应用程序之间传输数据。它可以将数据结构&#xff08;如对象、消息&#xff09;转换为字节流&#xff0c;以便在网络上进行传输或存储。 Protobuf序列化基…

M-LAG 技术笔记

M-LAG 简介 M-LAG&#xff08;Multichassis link aggregation&#xff0c;跨设备链路聚合&#xff09;将两台物理设备在聚合层面虚拟成一台设备来实现跨设备链路聚合&#xff0c;从而提供设备级冗余保护和流量负载分担。 M-LAG 基础概念 如 图1-1 所示&#xff0c;Device A …

【政策】正文关键词提取总结

附&#xff1a;样本构建流程&#xff1a; 候选样本圈选&#xff0c;这一步的目的是选出潜在的高质量样本&#xff0c;找到一部分高难度样本&#xff0c;并过滤掉可能的意图不明或无意义数据。样本圈选的方法见下文。 对圈选出的样本随机抽样一小部分进行人工标注。 利用少量的…

Vue3 虚拟列表组件库 virtual-list-vue3 的使用

Vue3 虚拟列表组件库 virtual-list-vue3 的基本使用 分享个人写的一个基于 Vue3 的虚拟列表组件库&#xff0c;欢迎各位来进行使用与给予一些更好的建议&#x1f60a; 概述&#xff1a;该组件组件库用于提供虚拟化列表能力的组件&#xff0c;用于解决展示大量数据渲染时首屏渲…

特征缩放的学习

两边同时除以最大范围&#xff0c;除了除以最大值以外&#xff0c;你还可以执行所谓的均值归一化。这看起来是&#xff0c;你从原始特征开始&#xff0c;然后你重新缩放他们&#xff0c;使两者其中以零为中心。以前它们只有大于零的值&#xff0c;现在他们既有负值又有正值这通…