【c语言】指针和数组笔试题解析

    一维数组:

//数组名a如果既不单独放在sizeof()中,也不与&结合,那么就表示数组首元素的大小
//a一般表示数组首元素地址,只有两种情况表示整个数组,sizeof(arr)表示整个数组的大小,&arr表示数组的地址
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16
printf("%d\n", sizeof(a + 0));//注意:此时a是首元素地址;结果:4/8
printf("%d\n", sizeof(*a));//4
printf("%d\n", sizeof(a + 1));//注意:此时a是第二个元素地址;结果:4/8
printf("%d\n", sizeof(a[1]));//4
printf("%d\n", sizeof(&a));//4/8 注意:是地址
printf("%d\n", sizeof(*&a));//16 注意:&a是数组指针,对数组指针解引用访问一个数组的大小
printf("%d\n", sizeof(&a + 1));//4/8
printf("%d\n", sizeof(&a[0]));//4/8
printf("%d\n", sizeof(&a[0] + 1));//4/8

字符数组:

char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6
printf("%d\n", sizeof(arr + 0));//4/8
printf("%d\n", sizeof(*arr));//1
printf("%d\n", sizeof(arr[1]));//1
printf("%d\n", sizeof(&arr));//4/8
printf("%d\n", sizeof(&arr + 1));//4/8
printf("%d\n", sizeof(&arr[0] + 1));//4/8
printf("%d\n", strlen(arr));//随机数
printf("%d\n", strlen(arr + 0));//随机数
//printf("%d\n", strlen(*arr));//err
//printf("%d\n", strlen(arr[1]));//err
//arr是首元素的地址,*arr就是首元素,站在strlen的角度,认为传参进去的'a'-97就是地址,97作为地址直接进行访问就是非法访问
//strlen不能传元素,只能传地址
printf("%d\n", strlen(&arr));//随机数
printf("%d\n", strlen(&arr + 1));//随机数
printf("%d\n", strlen(&arr[0] + 1));//随机数
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7 注意:sizeof()计算字符串大小,有'\0'是需要计算'\0'
printf("%d\n", sizeof(arr + 0));//4/8
printf("%d\n", sizeof(*arr));//1
printf("%d\n", sizeof(arr[1]));//1
printf("%d\n", sizeof(&arr));//4/8
printf("%d\n", sizeof(&arr + 1));//4/8
printf("%d\n", sizeof(&arr[0] + 1));//4/8
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr + 0));//6
printf("%d\n", strlen(*arr));//err
printf("%d\n", strlen(arr[1]));//err
printf("%d\n", strlen(&arr));//6
printf("%d\n", strlen(&arr + 1));//随机数 注意:&arr+1跳过整个数组,指向的位置何时出现'\0'未知
printf("%d\n", strlen(&arr[0] + 1));//5
char* p = "abcdef";
printf("%d\n", sizeof(p));//4/8
printf("%d\n", sizeof(p + 1));//4/8
printf("%d\n", sizeof(*p));//1
printf("%d\n", sizeof(p[0]));//1
printf("%d\n", sizeof(&p));//4/8
printf("%d\n", sizeof(&p + 1));//4/8
printf("%d\n", sizeof(&p[0] + 1));//4/8
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p + 1));//5
printf("%d\n", strlen(*p));//err
printf("%d\n", strlen(p[0]));//err
printf("%d\n", strlen(&p));//随机数
printf("%d\n", strlen(&p + 1));//随机数
printf("%d\n", strlen(&p[0] + 1));//5
//注意:p,p+1,&p[0]是地址(指针),p[0]是元素,&p,&p+1是二级指针,strlen()中存放指针,计算该指针指向的对象'\0'前的元素个数;如果是二级指针,则计算指向的一级指针'\0'前的元素个数,未知!

二维数组:

//注意:二维数组是一维数组的数组,这个思想非常重要
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//48
printf("%d\n", sizeof(a[0][0]));//4
printf("%d\n", sizeof(a[0]));//16 注意:a[0]是第一行这个一维数组的数组名,数组名单独放在了sizeof内部,计算整个一维数组的大小
printf("%d\n", sizeof(a[0] + 1));//4/8 注意:a[0]是一维数组的数组名,没有单独放在sizeof中,表示一维数组首元素的地址,+1表示第二个元素的地址
printf("%d\n", sizeof(*(a[0] + 1)));//4 第一行的一维数组的第二个元素
printf("%d\n", sizeof(a + 1));//4/8
printf("%d\n", sizeof(*(a + 1)));//16 第二行大小
printf("%d\n", sizeof(&a[0] + 1));//4/8 第二行一维数组的地址
printf("%d\n", sizeof(*(&a[0] + 1)));//16 第二行一维数组的大小
printf("%d\n", sizeof(*a));//16  第一行的大小
printf("%d\n", sizeof(a[3]));//16 
//注意:不会越界,sizeof()中一旦有表达式,就能够确定类型,sizeof(表达式)在编译器编译时就能根据类型计算大小,不需要sizeof真的访问a
//a[3]==a[0]
//int[4]==int[4]
//表达式有两个属性:类型属性,值属性
//sizeof使用的是表达式的类型属性

指针练习题:

练习1:

int main()
{int a[5] = { 1, 2, 3, 4, 5 };int* ptr = (int*)(&a + 1);printf("%d,%d", *(a + 1), *(ptr - 1));return 0;
}
//程序的结果是什么?
// 2 5

练习2:

#include <stdio.h>
//由于还没学习结构体,这里告知结构体的大小是20个字节
//x86环境下演示
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{p = (struct Test*)0x100000;printf("%p\n", p + 0x1);//注意:0x1是16进制,实际上就是1;结构体指针+1,就是跳过一个结构体(20个字节);p是16进制,20的16进制是14,结果:00100014//x86环境下,32位地址,地址大小是4字节,16进制打印有8位printf("%p\n", (unsigned long)p + 0x1);//将地址强转为整型,整型加1就是加1,以%p格式打印,结果:00100001printf("%p\n", (unsigned int*)p + 0x1);//结果:00100004//注意:以%p格式打印时,前面的0不省略return 0;
}

练习3:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{int a[4] = { 1, 2, 3, 4 };int* ptr1 = (int*)(&a + 1);int* ptr2 = (int*)((int)a + 1);//元素:小端存储:01 00 00 00,02 00 00 00//首元素地址强转为整型int后+1,再强转为int*,表示地址向后跳过一个字节//指向的元素在内存中为00 00 00 02,实际为02000000(16进制)//以%x格式打印,前面的0可以省略printf("%x,%x", ptr1[-1], *ptr2);//4 2000000return 0;
}

练习4:

#include <stdio.h>
int main()
{int a[3][2] = { (0, 1), (2, 3), (4, 5) };//逗号表达式//                1       3        5//a[3][2]={{1,3},{5,0},{0,0}};int* p;p = a[0];//数组名表示首元素地址,p==&a[0][0]printf("%d", p[0]);//p[0]==*(p+0)==*p==a[0][0]//1return 0;
}

练习5:

#include <stdio.h>
int main()
{int a[5][5];int(*p)[4];p = a;//a-int (*)[5]//p-int (*)[4]//注意:类型不同的指针访问数组的方式不同printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);//FFFFFFFC,-4return 0;
}

指针相减得到两指针间的元素个数且数组在内存中从低地址向高地址存储:&p[4][2]-&a[4][2]=-4

-4:

原码:10000000000000000000000000000100

反码:1111111111111111111111111111111111011

补码:1111111111111111111111111111111111100(内存中存储)

以%p格式打印:补码即地址(x82—32位—4字节—8个十六进制位):FFFFFFFC

以%d格式打印:-4

练习6: 

#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));//*(aa + 1)==aa[1]==第二行一维数组首元素的地址(注意这个重要变换)/首元素的地址本身就是整型指针,int*强转是迷惑printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10,5return 0;
}

练习7:

#include <stdio.h>
int main()
{char* a[] = { "work","at","alibaba" };//字符指针数组:a的元素时字符指针,分别指向"work","at","alibaba"的首个字符char** pa = a;pa++;printf("%s\n", *pa);//atreturn 0;
}

练习8: 

#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);//注意:前置后置++/--的优先级都高于解引用//地址++,即指向的元素跳过一个//解引用得到c+2,指向c[2],再解引用得到c+2指向的元素,即POINTprintf("%s\n", *-- * ++cpp + 3);//关系运算符的优先级低于解引用和自增操作符//++cp是在上一个cp的前提下++//解引用得到c+1,自减操作得到c,再解引用得到c指向的元素ENTER,+3向后移3个字符,得到ERprintf("%s\n", *cpp[-2] + 3);//*cpp[-2]==*(*(cp-2))==FIRST,+3得到ST//注意:cp-2,cp的值不变printf("%s\n", cpp[-1][-1] + 1);//cpp[-1][-1]==*(*(cpp-1)-1)==ENTER//+1得到EWreturn 0;
}

结果:

POINT
ER
ST
EW 

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

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

相关文章

机器人进阶---视觉算法(六)傅里叶变换在图像处理中怎么用

傅里叶变换在图像处理中怎么用 傅里叶变换的基本原理应用场景Python代码示例逐行解释总结傅里叶变换在图像处理中是一种重要的工具,它将图像从空间域转换到频域,从而可以对图像的频率特性进行分析和处理。傅里叶变换在图像滤波、图像增强、图像压缩和图像分析等方面都有广泛应…

深度学习与总结JVM专辑(七):垃圾回收器—CMS(图文+代码)

CMS垃圾收集器深度解析教程 1. 前言&#xff1a;为什么需要CMS&#xff1f;2. CMS 工作原理&#xff1a;一场与时间的赛跑2.1. 初始标记&#xff08;Initial Mark&#xff09;2.2. 并发标记&#xff08;Concurrent Mark&#xff09;2.3. 重新标记&#xff08;Remark&#xff09…

数据采集:AI 发展的基石与驱动力

人工智能&#xff08;AI&#xff09;无疑是最具变革性的技术力量之一&#xff0c;正以惊人的速度重塑着各行各业的格局。从智能语音助手到自动驾驶汽车&#xff0c;从精准的医疗诊断到个性化的推荐系统&#xff0c;AI 的广泛应用已深刻融入人们的日常生活与工作的各个层面。而在…

从信息泄露到内网控制

0x01 背景 之前常见用rce、文件上传等漏洞获取webshell&#xff0c;偶然遇到一次敏感信息泄露获取权限的渗透&#xff0c;简单记录一下过程。 0x02 信息泄露 发现系统某端口部署了minio服务&#xff0c;经过探测发现存在minio存储桶遍历 使用利用工具把泄露的文件全部整理一…

《门》凡是过往,皆为序曲。我们的爱,和最初一样

《门》凡是过往&#xff0c;皆为序曲。我们的爱&#xff0c;和最初一样 夏目漱石&#xff0c;本名夏目金之助&#xff0c;笔名漱石&#xff0c;日本近代作家&#xff0c;代表作有《三四郎》《门》《从此以后》《我是猫》《心》《明暗》等。 竺家荣 译 文章目录 《门》凡是过往&…

衡石ChatBI:依托开放架构构建技术驱动的差异化数据服务

在当今数字化浪潮中&#xff0c;企业对数据价值的挖掘和利用需求日益增长。BI&#xff08;商业智能&#xff09;工具作为企业获取数据洞察的关键手段&#xff0c;其技术架构的创新与发展至关重要。衡石科技的Chat BI凭借其独特的开放架构&#xff0c;在BI领域脱颖而出&#xff…

oracle中错误总结

oracle中给表起别名不能用as&#xff0c;用as报错 在 Oracle 数据库中&#xff0c;​​WITH 子句&#xff08;即 CTE&#xff0c;公共表表达式&#xff09;允许后续定义的子查询引用前面已经定义的 CTE​​&#xff0c;但 ​​前面的 CTE 无法引用后面的 CTE​​。这种设计类似…

NLP高频面试题(五十)——大模型(LLMs)分词(Tokenizer)详解

在自然语言处理(NLP)任务中,将文本转换为模型可处理的数字序列是必不可少的一步。这一步通常称为分词(tokenization),即把原始文本拆分成一个个词元(token)。对于**大型语言模型(LLM,Large Language Model,大型语言模型)**而言,选择合适的分词方案至关重要:分词的…

优化WAV音频文件

优化 WAV 音频文件通常涉及 减小文件体积、提升音质 或 适配特定用途&#xff08;如流媒体、广播等&#xff09;。以下是分场景的优化方法&#xff0c;涵盖工具和操作步骤&#xff1a; 一、减小文件体积&#xff08;无损/有损压缩&#xff09; 1. 无损压缩 转换格式&#xff1…

ORACLE SQL输入的变量由于隐式转换无法使用索引的分析优化

近期&#xff0c;某客户在巡检分析AWR报告时&#xff0c;发现有个TOP SQL的执行效率偏慢&#xff0c;检查分析SQL&#xff0c;发现数据块读取量高&#xff0c;分析执行计划&#xff0c;发现有个查询条件未使用到索引&#xff1b; 对执行计划及表上的字段、索引进行分析&#x…

【锂电池SOH估计】RF随机森林锂电池健康状态估计,锂电池SOH估计(Matlab完整源码和数据)

目录 效果一览程序获取程序内容代码分享研究内容基于随机森林(RF)的锂电池健康状态(SOH)估计算法研究摘要1. 引言2. 锂电池SOH评估框架3. 实验与结果分析4. 未来研究方向6. 结论效果一览 程序获取 获取方式一:文章顶部资源处直接下载:【锂电池SOH估计】RF随机森林锂电池…

安全高效两不误,这款安全数据摆渡系统支持8种传输协议

安全高效两不误&#xff01;这款安全数据摆渡系统支持8种传输协议 传统的安全数据摆渡系统主要包括物理介质拷贝&#xff08;如光盘、U盘&#xff09;、网闸、光闸、防火墙文件交换模块等&#xff0c;这些安全数据摆渡系统和传输方式在传输协议支持及功能实现上各有优劣势。 …

(51单片机)LCD显示温度(DS18B20教程)(LCD1602教程)(延时函数教程)(单总线教程)

演示视频&#xff1a; LCD显示温度 源代码 如上图将9个文放在Keli5 中即可&#xff0c;然后烧录在单片机中就行了 烧录软件用的是STC-ISP&#xff0c;不知道怎么安装的可以去看江科大的视频&#xff1a; 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.…

【愚公系列】《Python网络爬虫从入门到精通》063-项目实战电商数据侦探(主窗体的数据展示)

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…

日志分析工具快速统计电商系统单位时间内的请求总数

一、常用日志分析工具及操作步骤 ‌ELK Stack(Elasticsearch + Logstash + Kibana)‌核心操作‌ 日志收集‌:通过Logstash配置日志输入(如Nginx日志文件),使用grok插件解析日志格式。 数据存储‌:将解析后的日志存入Elasticsearch,利用其分布式搜索能力快速索引数据。…

Win10一体机(MES电脑设置上电自动开机)

找个键盘&#xff0c;带线的那种&#xff0c;插到电脑上&#xff0c;电脑开机&#xff1b;连续点按F11&#xff1b;通过↑↓键选择Enter Setup 然后回车&#xff1b; 选择 smart settings &#xff1b; 选择 Restore AC Power Loss By IO 回车&#xff1b; 将prower off 改为…

crontab 定时备份 mysql 数据库

1、使用 mysqldump 命令备份数据 1.1 备份全部数据库的数据和结构 mysqldump -uroot -p123456 -A > /data/backup/db.sql1.2 备份全部数据库的结构&#xff08;加 -d 参数&#xff09; mysqldump -uroot -p123456 -A -d > /data/backup/db.sql1.3 备份全部数据库的数据…

【Git】branch合并分支

在 Git 中&#xff0c;将分支合并到 main 分支是一个常见的操作。以下是详细的步骤和说明&#xff0c;帮助你完成这个过程。 1. 确保你在正确的分支上 首先&#xff0c;你需要确保当前所在的分支是 main 分支&#xff08;或者你要合并到的目标分支&#xff09;。 检查当前分支…

基于Python+Pytest实现自动化测试(全栈实战指南)

目录 第一篇&#xff1a;基础篇 第1章 自动化测试概述 1.1 什么是自动化测试 第2章 环境搭建与工具链配置 2.1 Python环境安装&#xff08;Windows/macOS/Linux&#xff09; 2.2 虚拟环境管理 2.3 Pytest基础配置&#xff08;pytest.ini&#xff09; 第3章 Pytest核心语…

什么是CRM系统,它的作用是什么?CRM全面指南

CRM&#xff08;Customer Relationship Management&#xff0c;客户关系管理&#xff09;系统是一种专门用于集中管理客户信息、优化销售流程、提升客户满意度、支持精准营销、驱动数据分析决策、加强跨部门协同、提升客户生命周期价值的业务系统工具。其中&#xff0c;优化销售…