【重生之我要苦学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.rhkb.cn/news/472008.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创建vue插件,发布npm

开发步骤&#xff1a;1.创建一个vue项目&#xff0c;2.开发一个组件。 3.注册成插件。 4.vite和package.json配置。5.发布到npm &#xff11;.创建一个vue项目 npm create vuelatest 生成了vue项目之后&#xff0c;得到了以下结构。 在src下创建个plugins目录。用于存放开发的…

Java垃圾回收算法

垃圾回收之标记算法 1、引用计数法 通过判断对象的引用数量来决定对象是否被回收每个对象实例都有一个引用计数器&#xff0c;被引用则1&#xff0c;完成引用则-1 优点&#xff1a; 执行效率高&#xff0c;程序执行受影响小 缺点&#xff1a; 无法检测出循环引用的情况&#…

文献阅读 | Nature Communications:使用自适应图注意自动编码器从空间解析的转录组学中解读空间域

文献介绍 文献题目&#xff1a; 使用自适应图注意自动编码器从空间解析的转录组学中解读空间域 研究团队&#xff1a; 张世华&#xff08;中国科学院数学与系统科学研究院&#xff09; 发表时间&#xff1a; 2022-04-01 发表期刊&#xff1a; Nature Communications 影响因子…

新手小白学习docker第八弹------实现MySQL主从复制搭建

目录 0 引言1 实操1.1 新建主服务器容器1.2 书写配置文件1.3 重启master实例1.4 进入mysql-master容器master容器实例内创建数据同步用户 1.5 新建从服务器容器1.6 书写配置文件1.7 重启slave实例1.8 查看主从同步状态1.9 进入mysql-slave容器1.9.1 配置主从复制1.9.2 查看主从…

学习threejs,使用TWEEN插件实现动画

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.PLYLoader PLY模型加…

HarmonyOS Next星河版笔记--界面开发(5)

1.字符串 1.1.字符串拼接 作用&#xff1a;把两个或多个字符串&#xff0c;拼成一个字符串。&#xff08;通常是用来拼接字符串和变量&#xff09; hello world > helloworld 加好作用&#xff1a;拼接 let name:string 小明 console.log(简介信息,名字是 name) …

24.11.13 机器学习 特征降维(主成份分析) KNN算法 交叉验证(K-Fold) 超参数搜索

导包小总结(不全面): from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.feature_extraction import DictVectorizer(字典数据集的划分) from sklearn.feature_extraction.text import CountVectorizer(特征提取…

基于SpringBoot+RabbitMQ完成应⽤通信

前言&#xff1a; 经过上面俩章学习&#xff0c;我们已经知道Rabbit的使用方式RabbitMQ 七种工作模式介绍_rabbitmq 工作模式-CSDN博客 RabbitMQ的工作队列在Spring Boot中实现&#xff08;详解常⽤的⼯作模式&#xff09;-CSDN博客作为⼀个消息队列,RabbitMQ也可以⽤作应⽤程…

react+hook+vite项目使用eletron打包成桌面应用+可以热更新

使用Hooks-Admin的架构 Hooks-Admin: &#x1f680;&#x1f680;&#x1f680; Hooks Admin&#xff0c;基于 React18、React-Router V6、React-Hooks、Redux、TypeScript、Vite2、Ant-Design 开源的一套后台管理框架。https://gitee.com/HalseySpicy/Hooks-Adminexe桌面应用…

【C++】string(一)

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C的string类&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 1. 标准库中的string类1.1 string类(了解)1.2 string类的常用接口说明(A) string类对象的…

新版Apache tomcat服务安装 Mac+Window双环境(笔记)

简介&#xff1a;Tomcat服务器器的下载和安装&#xff1a; 安装前提 1&#xff09;电脑需要有java环境&#xff0c;jdk8以上&#xff0c;否则启动不不成功 2&#xff09;已经安装Sublime⽂文件编辑软件 3&#xff09;window电脑需要显示⽂文件拓拓展名 官网&#xff08;https:…

see的本质是什么?

see的本质是什么&#xff1f;see的本质&#xff0c;就是一条蛇&#xff1a; see s蛇 e眼 e眼 ee是两只大眼睛&#xff0c;长在蛇的脑袋上&#xff0c;代表着蛇头和跟随性观察。 如果你喜欢看【龙虎斗】&#xff0c;看【猫蛇大战】相关的视频&#xff0c;你会发现&#xff0c…

0x00基础算法 -- 0x05 排序

1、离散化 排序算法的第一个应用&#xff1a;离散化。 “离散化”就是把无穷大&#xff08;无限&#xff09;的集合中的若干个&#xff08;有限&#xff09;元素映射为有限集合以便于统计的方法。 例如&#xff1a;问题的范围定义在整数集合&#xff0c;但是只涉及其中m个有限的…

深度学习在边缘检测中的应用及代码分析

摘要&#xff1a; 本文深入探讨了深度学习在边缘检测领域的应用。首先介绍了边缘检测的基本概念和传统方法的局限性&#xff0c;然后详细阐述了基于深度学习的边缘检测模型&#xff0c;包括其网络结构、训练方法和优势。文中分析了不同的深度学习架构在边缘检测中的性能表现&am…

博物馆实景复刻:开启沉浸式文化体验的新篇章

随着数字化技术的飞速发展&#xff0c;博物馆的展览形式正在经历一场前所未有的变革。3数字博物馆和3D线上展览&#xff0c;这种创新的展览方式不仅打破了时间和空间的限制&#xff0c;更让文化遗产的保护与传承迈上了一个新的台阶。 本文将深入探讨博物馆实景复刻虚拟展厅的兴…

服务器上安装Orcale数据库以及PL SQL工具(中文)

一、前期准备 1、oracle数据库安装包–>Oracle下载地址&#xff0c;版本根据当时情况就下最新的就行&#xff0c;下载时间可能有点长&#xff0c;耐心点。 2、PL SQL工具下载地址–>PL SQL下载地址&#xff0c;百度网盘可以共享【限速&#xff0c;没办法&#xff01;&am…

除了 TON, 哪些公链在争夺 Telegram 用户?数据表现如何?

作者&#xff1a;Stella L (stellafootprint.network) 在 2024 年&#xff0c;区块链游戏大规模采用迎来了一个意想不到的催化剂&#xff1a;Telegram。随着各大公链争相布局这个拥有海量用户基础的即时通讯平台&#xff0c;一个核心问题浮出水面&#xff1a;这种用户获取策略…

JSON.stringify的应用说明

前言 JSON.stringify() 方法将 JavaScript 对象转换为字符串,在日常开发中较常用&#xff0c;但JSON.stringify其实有三个参数&#xff0c;后两个参数&#xff0c;使用较少&#xff0c;今天来介绍一下后两个参数的使用场景和示例。 语法及参数说明 JSON.stringify()&#xf…

java:接口,抽象,多态的综合小练习

package 综合抽象接口练习;public class person {protected String name;protected int age;person(){}person(String name,int age){this.namename;this.ageage;}public void setName(String name){this.namename;}public String getName(){return name;}public void setAge(i…

<AI 学习> 下载 Stable Diffusions via Windows OS

注意&#xff1a; 不能使用 网络路径 不再支持 HTTPS 登录&#xff0c;需要 Token 1. 获得合法的授权 Stability AI License — Stability AI 上面的链接打开&#xff0c;去申请 许可 2. 拥有 HuggingFace 账号 注册&#xff1a;https://huggingface.co/ 3. 配置 Tok…