指针的学习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. 根据标…...
为什么你的Copilot代码在生产环境崩了?——奇点大会披露的6类静态不可见、动态必爆的性能反模式
第一章:为什么你的Copilot代码在生产环境崩了?——奇点大会披露的6类静态不可见、动态必爆的性能反模式 2026奇点智能技术大会(https://ml-summit.org) 在奇点大会的“AI生成代码可靠性”闭门研讨中,来自Netflix、Stripe和CNCF可观测性工作…...
Go语言中 与 -:指针取址与解引用的完整解析
本文深入讲解 Go 中 &(取地址符)和 *(解引用符)的本质区别与协同关系,结合 json.Decode 等典型场景说明何时必须用 &、何时需声明 *T 类型,并通过可运行示例直观展示指针层级与内存语义。 本文…...
一次由Nginx的proxy_pass尾随斜杠引发的重定向循环
一次由Nginx的proxy_pass尾随斜杠引发的重定向循环 在Web服务器配置中,Nginx的proxy_pass指令是反向代理的核心组件,但一个看似微不足道的斜杠差异可能导致严重的重定向循环问题。某次线上服务突然出现大量HTTP 302跳转,最终发现是proxy_pas…...
Superpowers - 15 用 Git Worktrees 打造“无尘室”开发环境:从 Superpowers 实践谈起
文章目录Pre一、为什么需要 Git Worktrees:上下文切换是真正的杀手1.1 传统分支切换的痛点1.2 Worktree 的核心价值:隔离,而不是复制二、Superpowers 的视角:Worktree 是必选项而非锦上添花2.1 三个关键技能的前置条件2.2 生命周期…...
从干旱监测到论文图表:SPEI数据在R语言中的实战应用指南
SPEI数据在R语言中的科研实战:从干旱监测到论文图表优化 干旱研究一直是气候科学和水文农业领域的重要课题。标准化降水蒸散发指数(SPEI)作为评估干湿状况的核心指标,其数据处理和可视化能力直接影响科研成果的表达效果。本文将带…...
AGI不是失业通知,而是职业跃迁加速器:3步完成从执行者到AGI协作者的身份升级
第一章:AGI与就业市场的未来变化 2026奇点智能技术大会(https://ml-summit.org) 通用人工智能(AGI)的渐进式突破正重塑全球劳动力结构,其影响远超传统自动化范畴——不再仅替代重复性任务,而是持续重构职业能力边界、…...
客服效率革命:如何用咕咕文本实现秒级响应
客户服务工作的核心指标之一,就是响应速度。 在电商平台的评价体系里,回复时长直接影响店铺的服务评分。 然而,面对海量咨询,即便是经验丰富的客服人员,手工打字也难以保证始终如一的快速响应。 传统的客服工作模式…...
[物理理论]全域场相互作用模型·阿雪心学·道场—东方仙盟天道量子
引言东方仙盟、阿雪心学、道场,是东方玄学体系中相互关联、辩证统一的三大核心范畴:东方仙盟是群体修持者的集合与共振共同体,阿雪心学是个体修心、调控自身场域的核心指导,道场是连接个体与集体、承载场能、实现场域交互的物理与…...
python containerd
# 聊聊Python Containerd:容器运行时的新选择 容器技术这几年发展得特别快,Docker几乎成了容器的代名词。但如果你在容器生态里待得够久,会发现事情正在起变化。Docker确实好用,但它把太多东西打包在一起了——运行时、镜像管理、…...
3步快速修复:用G-Helper解决华硕笔记本屏幕色彩发白问题
3步快速修复:用G-Helper解决华硕笔记本屏幕色彩发白问题 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, …...
