指针的学习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));//4
	printf("%zd\n", sizeof(int));//4
	printf("%zd\n", sizeof a);//4——侧面证明了sizeof不是函数!函数调用要有括号
	return 0;
}

sizeof后面的()不进行计算!

	int b = 8;
	short s = 4;
	printf("%d\n", sizeof(s = b + 2));//2
	printf("%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*4
	printf("%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或8
	printf("%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或8
	printf("%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或8
	printf("%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));//数组的地址,起始位置是数组的第一个元素的位置,结束位置随机x
	printf("%d\n", strlen(&arr + 1));//跳过整个数组得到的地址,指向数组后面的空间,随机值x-6
	printf("%d\n", strlen(&arr[0] + 1));//从第二个元素开始向后统计,随机值x-1
	return 0;
}

代码3: 

#include <stdio.h>
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7
	printf("%d\n", sizeof(arr + 0));//4或8——arr表示数组首元素地址,arr+0还是数组首元素地址,是地址就是4或8
	printf("%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));//6
	printf("%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));//5
	return 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或8
	printf("%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));//6
	printf("%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));//5
	return 0;
}
二维数组
#include <stdio.h>
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//48——a是数组名,单独放在sizeof内部,计算的是整个数组的大小,单位是字节48=3*4*4
	printf("%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或8
	printf("%d\n", sizeof(*(a + 1)));//16——第二行的大小16=4*4
	printf("%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,5
	return 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就是1
	printf("%p\n", p + 0x1);//00100014——结构体指针+1,要跳过整个结构体;0x100000+20->0x100014
	printf("%p\n", (unsigned long)p + 0x1);//00100001——不再是指针,long类型,整型值+1就是+1,0x100000+1->0x100001
	printf("%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]);//0
	return 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]);//1
	return 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,5
	return 0;
}
题目6:
#include <stdio.h>
int main()
{
	char* a[] = { "work","at","alibaba" };//数组的每个元素都是char*,a是指针数组
	char** pa = a;
	pa++;
	printf("%s\n", *pa);//at
	return 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+2
	printf("%s\n", *-- * ++cpp + 3);
	//ER——复杂!+优先级最低,cpp+1+1解引用指向c+1,c+1-1即为c,解引用得到"ENTER"首字母,首字母+3得到ER
	printf("%s\n", *cpp[-2] + 3);//ST——*cpp[-2]+3即**(cpp-2)+3,cpp+2-2=cpp,指向c+3,指向FIRST,+3得到ST
	printf("%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得到EW
	return 0;
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安装配置Hadoop集群

安装配置Hadoop集群的主要步骤 1、安装配置Hadoop 2、配置用户环境变量 3、配置Hadoop 配置core-site.xml文件配置hdfs-site.xml文件配置mapred-site.xml文件配置yarn-site.xml文件配置slaves文件配置hadoop-env.sh文件 更多配置文件的配置信息请参见官方网站的解释。 4、…

vue2中使用异步组件

在大型应用中&#xff0c;我们可能需要将应用分割成小一些的代码块&#xff0c;并且只在需要的时候才从服务器加载一个模块。这时就就可以使用异步组件。 1.通过import方式引入 //组件1<tempalte><Parent v-if"show"></Parent><button clickha…

关于Spring依赖注入简洁方式的探索

最近在项目开发过程中关注到一个依赖注入的写法差异&#xff0c;因为本人代码上有点强迫症&#xff0c;看到这种不同人不一样的写法&#xff0c;特意了解了一下&#xff0c;但是依然有部分疑惑未解。 两种写法&#xff1a;(就是传说中最常见的属性注入和构造函数注入) Service…

云打印机多少钱一台?

随着新的一年的开始&#xff0c;很多同学们都开始打印资料&#xff0c;以应对新一年的各种考试。但是对于学生们来说&#xff0c;去打印店打印价格贵、打印不方便、没时间去打印等多种原因导致我们没办法及时打印资料&#xff0c;这个时候我们就需要用到云打印机。那么云打印机…

浅谈游戏AI LOD的智能控制——LOD交易员

前引 LOD的概念 提到 细节层次 &#xff08;Level of Details&#xff0c;简写LOD&#xff09;&#xff0c;大家可能首先会想到图像渲染&#xff0c;像游戏中大地图的3D物体会随玩家与其距离的远近而变化精度&#xff08;主要是模型面数的变化&#xff0c;有时还会直接剔除&a…

CSS基础知识

font-family: "Trebuchet MS", Verdana, sans-serif; 字体栈&#xff0c;浏览器会一个一个试过去看下哪个可以用 font-size16px; font-size1em; font-size100%;//相对于16px 字体大小&#xff0c;需要进行单位换算16px1em font-weightnormal;//400font-weight属性…

ai直播数字人:AI大模型应用开发的神奇世界

当AI技术的发展走向一个新的高峰&#xff0c;AI直播数字人逐渐成为人们关注的焦点。这种全新的数字人形态&#xff0c;通过大模型应用开发&#xff0c;带来了一个神奇世界。 在这个神奇世界里&#xff0c;AI直播数字人可以展现出与真实人类相媲美的外貌和声音。通过先进的图像…

HarmonyOS ArkTS工程目录结构(Stage模型)

1. ArkTS工程目录结构&#xff08;Stage模型&#xff09; 官方文档&#xff08;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/start-with-ets-stage-0000001477980905-V2&#xff09; 1.1. AppScope AppScope > app.json5&#xff1a;应用的全局配…

图的单源最短路径问题

目录 一、简述 二、前置配置 三、迪杰斯特拉算法 四、改进的迪杰斯特拉算法 五、贝尔曼福特算法 一、简述 图是一种比较常用的数据结构&#xff0c;将问题转换成图相关的思路也是比较常用的。 图的单源最短路径问题&#xff0c;也就是图中某一个节点到图中其他节点的最短路…

基于SSM的植物园管理系统设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 开发技术简介 3 1.1 SSM框架 3 1.2 JSON 3 1.3 Ajax 4 1.4 Bootstrap前台框架 4 1.5 Eclipse 4 1.6 本章小结 4 2 系统分析 5 2.1可行性分析 5 2.1.1 技术可行性 5 2.1.2 经济可行性 5 2.1.3 操作可行性 5 2.2 功能需求 5 2.3 用例分析 6…

洞悉 Kubernetes 高阶奥秘:掌控资源、网络、存储,玩转容器化应用!

昨天我们已经入门了K8S&#xff0c;今天带大家学习一下资源、网络、存储这几个进阶的知识点模块内容。这几天陆陆续续会把K8S从头到尾讲一遍&#xff0c;最后会带大家实战一下&#xff0c;下面就开始今天的学习吧。 高级资源和控制器 Kubernetes 提供了一系列高级资源和控制器…

请编程输出无向无权图各个顶点的度 ← 链式前向星存图

【题目描述】请利用链式前向星存图&#xff0c;编程输出无向无权图各个顶点的度。【输入样例】 5 6 1 3 2 1 1 4 2 3 3 4 5 1【输出样例】 4 2 3 2 1【算法分析】 本例需要用到基于链式前向星的广度优先搜索&#xff08;BFS&#xff09;。 链式前向星广度优先搜索&#xff08;B…

JavaScript 实现飞机大战

文章目录 一些关键点概览&#xff1a;核心模块的具体实现示例&#xff1a;飞机类&#xff08;Plane&#xff09;的基本结构&#xff1a;子弹类&#xff08;Bullet&#xff09;的基本结构&#xff1a;敌机类&#xff08;Enemy&#xff09;的基本结构&#xff1a; 基于前面定义的…

Idea创建Maven项目

Maven安装配置步骤&#xff1a; 解压安装 bin目录 &#xff1a; 存放的是可执行命令。&#xff08;mvn 命令重点关注&#xff09; conf目录 &#xff1a;存放Maven的配置文件。&#xff08;settings.xml配置文件后期需要修改&#xff09; lib目录 &#xff1a;存放Maven依赖的j…

Python快速入门系列-2(Python的安装与环境设置)

第二章&#xff1a;Python的安装与环境设置 2.1 Python的下载与安装2.1.1 访问Python官网2.1.2 安装Python对于Windows用户对于macOS用户对于Linux用户 2.2 集成开发环境&#xff08;IDE&#xff09;的选择与设置2.2.1 PyCharm2.2.2 Visual Studio Code2.2.3 Jupyter Notebook2…

bat文件给多个Android设备安装apk

本文是安装一个apk 1、确保以下3个文件在同一个目录下 1>要安装的apk&#xff0c;这里是mmb.apk 2>设备名单&#xff0c;保存在.txt文件中&#xff0c;一行一个设备名&#xff0c;设备名通过adb devices获取&#xff0c;截图中是两个设备 txt文件中的样式 3>要运行…

基于springboot实现大学外卖管理系统项目【项目源码+论文说明】

基于springboot实现大学外卖管理系统演示 摘要 如今&#xff0c;信息化不断的高速发展&#xff0c;社会也跟着不断进步&#xff0c;现今的社会&#xff0c;各种工作都离不开信息化技术&#xff0c;更离不开电脑的管理。信息化技术也越来越渗透到各小型的企业和公司中&#xff…

AI 资讯 | GPT-4 时代终结!Claude 3 一举成为地表最强 AI 模型,今天就能用上!

AI 的飞速发展&#xff0c;对开发者而言意义重大。为此&#xff0c;我们精心筛选了最新 AI 相关资讯与大家分享交流。 未来&#xff0c;Apifox 也将时刻关注 AI 领域发展动态&#xff0c;及时呈现全面的 AI 资讯&#xff0c;与大家一起把握 AI 机遇。希望 在这些资讯中&#xf…

3.9Code

基于顺序存储结构的图书信息表的图书去重 #include<iostream> #include<stdlib.h> #include<string.h>typedef int status;#define OK 1using namespace std;typedef struct{char no[50];char name[50];float price; }Book;typedef struct{Book* elem;int …

J8 - Inception v1算法

目录 理论知识Inception卷积计算 模型结构模型实现inception 结构GoogLeNet模型打印模型结构 模型效果总结与心得体会 理论知识 GoogLeNet首次出现就在2014年的ILSVRC比赛中获得冠军&#xff0c;最初的版本为InceptionV1。共有22层深&#xff0c;参数量5M。 可以达到同时期VGG…