指针的学习5
目录
sizeof和strlen的区别
sizeof
strlen
数组和指针笔试题解析
一维数组
字符数组
二维数组
指针运算笔试题解析
题目1:
题目2:
题目3:
题目4:
题目5:
题目6:
题目7:
sizeof和strlen的区别
sizeof
sizeof计算变量所占内存空间的大小,单位是字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小
sizeof只关注占用内存空间的大小,不在乎内存中存放什么数据
sizeof是单目操作符,不是函数!!!
#include <stdio.h>
int main()
{int a = 0;printf("%zd\n", sizeof(a));//4printf("%zd\n", sizeof(int));//4printf("%zd\n", sizeof a);//4——侧面证明了sizeof不是函数!函数调用要有括号return 0;
}
sizeof后面的()不进行计算!
int b = 8;short s = 4;printf("%d\n", sizeof(s = b + 2));//2printf("%d\n", s);//4
C语言是编译型语言:test.c->编译->链接->test.exe->运行
strlen
strlen是C语言库函数(头文件是<string.h>),功能是求字符串长度,函数原型如下:
size_t strlen(const char* str);
统计的是从strlen函数的参数str中这个地址开始向后,\0之前字符串中字符的个数(不算\0)
strlen函数会一直向后找\0字符,直到找到为止,所以可能存在越界查找
size_t len = strlen("abc\0ef");printf("%zd\n", len);//3
const char* str = "abcdef";printf("%zd\n", strlen(str));//6
char arr[] = { 'a','b','c' };printf("%zd\n", strlen(arr));//随机值——找到\0
数组和指针笔试题解析
一维数组
#include <stdio.h>
int main()
{//数组名的理解://数组名是数组首元素的地址,但是有两个例外://sizeof(数组名)——数组名表示整个数组,计算的是整个数组的大小,单位是字节//&数组名——数组名表示整个数组,取出的是整个数组的地址int a[] = { 1,2,3,4 };//数组有4个元素printf("%zd\n", sizeof(a));//16=4*4printf("%zd\n", sizeof(a + 0));//4或8——a表示首元素地址,类型是int*, a+0还是首元素地址printf("%zd\n", sizeof(*a));//4——a是首元素的地址,*a就是首元素,大小是4个字节,*a==a[0]=*(a+0)printf("%zd\n", sizeof(a + 1));//4或8——a表示首元素地址,类型是int*,a+1就是第二个元素的地址printf("%zd\n", sizeof(a[1]));//4——第二个元素printf("%zd\n", sizeof(&a));//4或8——整个数组的地址,是地址就是4或8printf("%zd\n", sizeof(*&a));//16——数组a的大小,*和&相抵消//&a是数组的地址,类型是int(*)[4],对数组指针解引用访问的是数组printf("%zd\n", sizeof(&a + 1));//4或8——&a+1是跳过整个数组后的那个位置的地址,是地址就是4/8,是野指针printf("%zd\n", sizeof(&a[0]));//4或8printf("%zd\n", sizeof(&a[0] + 1));//4或8——数组第二个元素的地址return 0;
}
字符数组
代码1:
#include <stdio.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", sizeof(arr));//6=6*1——计算数组大小printf("%d\n", sizeof(arr + 0));//4或8——数组首元素的地址,是地址就是4或8printf("%d\n", sizeof(*arr));//1——arr是首元素地址,*arr就是首元素,大小就是a的大小//*arr=arr[0]=*(arr+0)printf("%d\n", sizeof(arr[1]));//1——第二个元素的大小printf("%d\n", sizeof(&arr));//4或8——数组的地址printf("%d\n", sizeof(&arr + 1));//4或8——跳过整个数组得到的地址,指向数组后面的空间//&arr--char (*)[6]printf("%d\n", sizeof(&arr[0] + 1));//4或8——第二个元素的地址return 0;
}
代码2:
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", strlen(arr));//数组中没有\0,导致越界访问,结果是随机的printf("%d\n", strlen(arr + 0));//arr+0是数组首元素地址,数组中没有\0,导致越界访问,结果是随机的//printf("%d\n", strlen(*arr));这个代码有问题//err——首元素a的地址,'a'的ASCII码值是97,相当于把97作为地址传递给了strlen,strlen得到的就是野指针//printf("%d\n", strlen(arr[1]));//err——b的ASCII码值是98,同上printf("%d\n", strlen(&arr));//数组的地址,起始位置是数组的第一个元素的位置,结束位置随机xprintf("%d\n", strlen(&arr + 1));//跳过整个数组得到的地址,指向数组后面的空间,随机值x-6printf("%d\n", strlen(&arr[0] + 1));//从第二个元素开始向后统计,随机值x-1return 0;
}
代码3:
#include <stdio.h>
int main()
{char arr[] = "abcdef";printf("%d\n", sizeof(arr));//7printf("%d\n", sizeof(arr + 0));//4或8——arr表示数组首元素地址,arr+0还是数组首元素地址,是地址就是4或8printf("%d\n", sizeof(*arr));//1——arr是首元素地址,*arr就是首元素,大小就是a的大小//*arr=arr[0]=*(arr+0)printf("%d\n", sizeof(arr[1]));//1——第二个元素的大小printf("%d\n", sizeof(&arr));//4或8——数组的地址printf("%d\n", sizeof(&arr + 1));//4或8——跳过整个数组得到的地址,指向数组后面的空间//&arr--char (*)[6]printf("%d\n", sizeof(&arr[0] + 1));//4或8——第二个元素的地址return 0;
}
代码4:
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcdef";printf("%d\n", strlen(arr));//6printf("%d\n", strlen(arr + 0));//6——arr首元素的地址,arr+0还是首元素的地址,向后在\0之前有6个字符//printf("%d\n", strlen(*arr));//err——首元素a的地址,'a'的ASCII码值是97,相当于把97作为地址传递给了strlen,strlen得到的就是野指针//printf("%d\n", strlen(arr[1]));//err——b的ASCII码值是98,同上printf("%d\n", strlen(&arr));//6——数组的地址,起始位置是数组的第一个元素的位置printf("%d\n", strlen(&arr + 1));//跳过整个数组得到的地址,指向数组后面的空间,随机值printf("%d\n", strlen(&arr[0] + 1));//5return 0;
}
代码5:
#include <stdio.h>
int main()
{const char* p = "abcdef";printf("%d\n", sizeof(p));//4或8——p是指针变量,指针变量的大小printf("%d\n", sizeof(p + 1));//4或8——p+1是b的地址,是地址就是4或8//printf("%d\n", sizeof(*p));//1——p的类型是const char*,*p就是char类型printf("%d\n", sizeof(p[0]));//1——第一个元素的大小printf("%d\n", sizeof(&p));//4或8——数组的地址printf("%d\n", sizeof(&p + 1));//4或8——跳过p指针变量后的地址,是地址就是4或8printf("%d\n", sizeof(&p[0] + 1));//4或8——第二个元素的地址return 0;
}
代码6:
#include <stdio.h>
#include <string.h>
int main()
{char* p = "abcdef";printf("%d\n", strlen(p));//6printf("%d\n", strlen(p + 1));//5//printf("%d\n", strlen(*p));//err——首元素a的地址,'a'的ASCII码值是97,相当于把97作为地址传递给了strlen,strlen得到的就是野指针//printf("%d\n", strlen(p[0]));//err——b的ASCII码值是98,同上printf("%d\n", strlen(&p));//&p是指针变量p的地址,与字符串无关//从p这个指针变量的起始位置开始向后数,p变量存放的地址是什么,不知道,所以答案是随机值printf("%d\n", strlen(&p + 1));//跳过整个数组得到的地址,指向数组后面的空间,随机值(与上句无关,因为有可能存在\0)printf("%d\n", strlen(&p[0] + 1));//5return 0;
}
二维数组
#include <stdio.h>
int main()
{int a[3][4] = { 0 };printf("%d\n", sizeof(a));//48——a是数组名,单独放在sizeof内部,计算的是整个数组的大小,单位是字节48=3*4*4printf("%d\n", sizeof(a[0][0]));//4——第一行第一个元素的大小printf("%d\n", sizeof(a[0]));//16——a[0]第一行的数组名,数组名单独放在sizeof内部了,计算的是数组的总大小16个字节printf("%d\n", sizeof(a[0] + 1));//4或8——a[0]第一行的数组名,但是a[0]并没有单独放在sizeof内部//a[0]就是数组首元素的地址,就是&a[0][0],a[0]+1即第一行第二个元素a[0][1],大小是4或8个字节printf("%d\n", sizeof(*(a[0] + 1)));//4——a[0][1]的大小printf("%d\n", sizeof(a + 1));//4或8——第二行地址的大小,a+1是数组指针,是地址大小就是4或8printf("%d\n", sizeof(*(a + 1)));//16——第二行的大小16=4*4printf("%d\n", sizeof(&a[0] + 1));//4或8——第一行第二个元素的地址,&a[0]就是数组第一行的地址,&a[0]+1就是第二行的地址printf("%d\n", sizeof(*(&a[0] + 1)));//16——第二行的大小printf("%d\n", sizeof(*a));//16——数组第一行的大小;*a==*(a+0)==a[0]printf("%d\n", sizeof(a[3]));//16——int [4],16=4*4;a[3]无需真实存在,仅仅通过类型的推断就能算出长度//a[3]是第四行的数组名,单独放在sizeof内部,计算的是第四行的大小,16个字节
}
指针运算笔试题解析
题目1:
#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:
#include <stdio.h>
//在X86环境下(32环境)
//假设结构体的大小是20个字节
//程序输出的结果是?
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}*p = (struct Test*)0x100000;//结构体指针
//指针+-整数
int main()
{//0x1就是1printf("%p\n", p + 0x1);//00100014——结构体指针+1,要跳过整个结构体;0x100000+20->0x100014printf("%p\n", (unsigned long)p + 0x1);//00100001——不再是指针,long类型,整型值+1就是+1,0x100000+1->0x100001printf("%p\n", (unsigned int*)p + 0x1);//00100004——int*占4个字节return 0;
}
题目3:
#include <stdio.h>
int main()
{int a[3][2] = { {0,1},{2,3},{4,5} };int* p;p = a[0];printf("%d", p[0]);//0return 0;
}
#include <stdio.h>
int main()
{int a[3][2] = { (0,1),(2,3),(4,5) };//逗号表达式,即{1, 3, 5},后面元素用0来填充int* p;p = a[0];printf("%d", p[0]);//1return 0;
}
题目4:
#include <stdio.h>
int main()
{int a[5][5];int(*p)[4];//p是一个数组指针,指向的数组是4个整型元素p = a;printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);//FFFFFFFC,-4//a的类型:int (*)[5];p的类型是int (*)[4],一行四个元素//p[4][2]==*(*(p+4)+2)//两个指针之间相差4个元素//指针-指针的绝对值是指针和指针之间的元素个数return 0;
}
题目5:
#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*int* ptr2 = (int*)(*(aa + 1));//*(aa+1)==aa[1],aa[1]是第二行的数组名,数组名表示首元素的地址,aa[1]也是&aa[1][0]printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10,5return 0;
}
题目6:
#include <stdio.h>
int main()
{char* a[] = { "work","at","alibaba" };//数组的每个元素都是char*,a是指针数组char** pa = a;pa++;printf("%s\n", *pa);//atreturn 0;
}
题目7:
#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);//POINT——cpp+1,指向c+2printf("%s\n", *-- * ++cpp + 3);//ER——复杂!+优先级最低,cpp+1+1解引用指向c+1,c+1-1即为c,解引用得到"ENTER"首字母,首字母+3得到ERprintf("%s\n", *cpp[-2] + 3);//ST——*cpp[-2]+3即**(cpp-2)+3,cpp+2-2=cpp,指向c+3,指向FIRST,+3得到STprintf("%s\n", cpp[-1][-1] + 1);//EW——cpp[-1][-1]=*(*(cpp-1)-1);cpp+2-1=cpp+1,指向c+2,c+2-1=c+1指向NEW,+1得到EWreturn 0;
}

相关文章:
指针的学习5
目录 sizeof和strlen的区别 sizeof strlen 数组和指针笔试题解析 一维数组 字符数组 二维数组 指针运算笔试题解析 题目1: 题目2: 题目3: 题目4: 题目5: 题目6: 题目7: sizeof和…...
Dynamo——常用几何形体的创建与编辑(二)
上一次,我们简单整理了一些创建几何形体的节点用法,今天我们接着整理一些,几何形体的编辑方法。 一、坐标点的平移复制 [Point.Add] 使用节点 “Vector.ByCoordinates” 生成一个向量,将该向量连接到 “Point.Add” 节点的输入端 …...
uniapp富文本编辑-editor-vue2-vue3-wangeditor
前言 不管vue2还是vue3,都推荐官方的editor组件, 官方手册 https://uniapp.dcloud.net.cn/component/editor.html除了“微信小程序”,其他小程序想要使用editor组件实现富文本编辑,很难 第三方组件wangeditor在vue2࿰…...
【java】22:try-catch 异常处理
try-catch 方式处理异常说明 public static void main(String[] args) { int num1 10; int num2 0; try { int res num1 / num2; } catch (Exception e) { System.out.println(e.getMessage()); } } 注意事项 1)如果异常发生了,则异常发生后面的代码不会执行&…...
【C语言】linux内核ip_local_out函数
一、讲解 这个函数 __ip_local_out 是 Linux 内核网络子系统中的函数,部分与本地出口的 IPv4 数据包发送相关。下面讲解这段代码的每一部分: 1. 函数声明 int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb): -…...
动态规划6,最大数组和,环形子数组最大和,乘积最大子数组
最大子数组和 思路: 1.经验题目要求 dp[i]表示:以 i 位置为结尾的所有子数组中的最大和 2.状态转移方程 按长度来划分,如果长度为1,那么dp[i] nums[i]; 如果长度大于1,那么当前位置的最大和就为 i-1 位置最大和 …...
js 清空数组的方法
1、直接赋值空数组 let array [1, 2, 3, 4, 5]; array []; 这种方法并不推荐,如下图所示: 虽然a数组确实变为了空数组,但这种方法只是修改了a的指向,把a指向一个新的空数组,然而[1,2,3,4,5]这个数组并没有被清除&a…...
QT中使用QProcess执行命令,实时获取数据,例如进度条
前言 因为之前写了一个接收和发送文件的脚本,然后又需要获取进度,同步到进度条中。 效果: 使用正则匹配,获取命令行命令中的以下数据,然后同步到进度条 源码demo: 非完整代码: #include <Q…...
绘图设计:用Draw.io绘制图形技巧大全(含统一建模语言UML模板)
一、常见UML模板 1.流程图 2.用例图 include是包含关系,extend是扩展关系 简而言之,include是子集指向父集;而extend是扩展用例指向基础用例(基础用例可以理解为系统核心功能,扩展用例是可选的,不是必须…...
被唤醒的“第二十条”深入人心
近来张艺谋执导的电影《第二十条》,因为它与正在召开中的全国两会所发布的《最高人民法院工作报告》联系相当紧密,加之可免费收看,网民便相互转告,于是此信息条目立即冲上了网络热搜榜,观者如潮。因为最高人民法院工作…...
PHPInfo()信息泄漏原理以及修复方法
漏洞名称:PHPInfo信息泄漏、phpinfo()函数信息泄漏 漏洞描述: phpinfo()函数返回的信息中包含了服务器的配置信息,包括: 1)PHP编译选项以及文件扩展名的相关信息; 2)php的版本信息 3&#…...
202441读书笔记|《笠翁对韵》—— 金菡萏,玉芙蓉,酒晕微酡琼杏颊,香尘浅印玉莲双
202441读书笔记|《笠翁对韵》——金菡萏,玉芙蓉,酒晕微酡琼杏颊,香尘浅印玉莲双 《作家榜名著:笠翁对韵》作者李渔,霍俊明。是所有词句都有注音的一本书,轻松学不认识的字,非常朗朗上口的对偶词…...
006-v-model原理
v-model原理 简介v-model应用在输入框上v-model应用在组件上 简介 由 属性绑定(v-bind:value“searchText”) 配合 input事件监听(v-on:input“searchText event.target.value”) 实现。 应用在组件上由 props: {value: xxx } ,this.$emit(‘input’, xxx ) 完成。…...
Ubuntu下使用DAPLink(OpenOCD)
目录 1. 下载OpenOCD源代码 2. 编译代码 2.1 运行bootstrap 2.2 安装关联库 2.3 运行./configure 2.4 运行make 2.5 运行sudo make install 3. 烧录程序 3.1 挂起MCU 3.2 写入镜像 3.3 校验镜像 通过OpenOCD实现,在Ubuntu18 64bit下验证。 1. 下载OpenOC…...
C# 中 Math.Round 数学函数
在 C# 中,Math.Round 是一个数学函数,用于对一个浮点数进行四舍五入操作。它接受一个浮点数作为输入,并返回一个最接近输入值的整数或指定小数位数的浮点数。 Math.Round 方法有多个重载,其中最常用的重载有以下两种形式…...
力扣---接雨水---单调队列
题目: 单调队列思想: 没有思路的小伙伴可以先把这个想清楚哦:力扣hot10---大根堆双端队列-CSDN博客 从上面的图就可以发现,如果柱子呈递减序列,那么不会接到雨水,只要有一个小凸起柱子,那么这个…...
微分学<4>——微分中值定理
索引 微分中值定理极值定义4.1 极大(小)值定理4.1 Fermat引理定理4.2 Rolle定理 Lagrange中值定理定理4.3 Lagrange中值定理定理4.4 Cauchy中值定理 导数对函数性质的刻画Jensen不等式 微分中值定理 极值 定义4.1 极大(小)值 若存在 x 0 x_{0} x0的邻域 U ( x 0 , δ ) U\…...
FPGA的时钟资源
目录 简介 Clock Region详解 MRCC和SRCC的区别 BUFGs 时钟资源总结 简介 7系列FPGA的时钟结构图: Clock Region:时钟区域,下图中有6个时钟区域,用不同的颜色加以区分出来 Clock Backbone:从名字也能看出来&#x…...
LeetCode27: 移除元素
题目描述 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出…...
Python使用Beautiful Soup及解析html获取元素并提取内容值
Python使用Beautiful Soup及解析html获取元素并提取内容值 1. 包括解析获取标题2. 根据标签及id获取所有元素3. 根据标签及class获取所有元素4. 获取元素下的标签的值5. 获取元素下的parent及child的元素的值参考 1. 包括解析获取标题 2. 根据标签及id获取所有元素 3. 根据标…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
