指针的学习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. 根据标…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...
验证redis数据结构
一、功能验证 1.验证redis的数据结构(如字符串、列表、哈希、集合、有序集合等)是否按照预期工作。 2、常见的数据结构验证方法: ①字符串(string) 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...
初级程序员入门指南
初级程序员入门指南 在数字化浪潮中,编程已然成为极具价值的技能。对于渴望踏入程序员行列的新手而言,明晰入门路径与必备知识是开启征程的关键。本文将为初级程序员提供全面的入门指引。 一、明确学习方向 (一)编程语言抉择 编…...
Neo4j 完全指南:从入门到精通
第1章:Neo4j简介与图数据库基础 1.1 图数据库概述 传统关系型数据库与图数据库的对比图数据库的核心优势图数据库的应用场景 1.2 Neo4j的发展历史 Neo4j的起源与演进Neo4j的版本迭代Neo4j在图数据库领域的地位 1.3 图数据库的基本概念 节点(Node)与关系(Relat…...
OpenHarmony标准系统-HDF框架之I2C驱动开发
文章目录 引言I2C基础知识概念和特性协议,四种信号组合 I2C调试手段硬件软件 HDF框架下的I2C设备驱动案例描述驱动Dispatch驱动读写 总结 引言 I2C基础知识 概念和特性 集成电路总线,由串网12C(1C、12C、Inter-Integrated Circuit BUS)行数据线SDA和串…...
