指针和数组笔试题解析【上】

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 指针和数组笔试题解析【上】
1.对数组名的理解


①数组名是数组首元素的地址


②但是有两个例外:


sizeof(数组名)这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节。

&数组名,这里的数组名也表示整个数组,取出的是数组的地址。

//一维数组
int a[] = {1,2,3,4};//4个元素,每个元素是int类型(4个字节)
printf("%d\n",sizeof(a));
//16 数组名a单独放在sizeof内部,计算的是整个数组的大小,单位是字节,是16个字节
printf("%d\n",sizeof(a+0));
//a并非单独放在sizeof内部,也没有&,所以数组名表示首元素的地址,a+0还是首元素地址,是地址就是4/8个字节
printf("%d\n",sizeof(*a));
//a并非单独放在sizeof内部,也没有&,所以还是表示首元素地址,对a解引用,就是a[0],大小是4个字节
printf("%d\n",sizeof(a+1));
//a并非单独放在sizeof内部,也没有&,表示首元素地址,a+1就表示第二个元素的地址,等价于&a[1],是地址就是4/8个字节
printf("%d\n",sizeof(a[1]));
//a并非单独放在sizeof内部,也没有&,表示数组第二个元素,计算的是第二个元素的大小单位是字节-4
printf("%d\n",sizeof(&a));
//&a--表示的是:取出整个数组的地址,但是数组的地址也是地址,是地址就是4/8个字节
//数组的地址 和 数组首元素的地址的 本质区别是类型的区别,并非大小的区别
//a--int*             int* p= a;       解引用访问一个整型的大小
//&a--int *()[4]      int (*p)[4] =&a; 解引用访问一个数组的大小
printf("%d\n",sizeof(*&a));
//16字节--&a,取出数组的地址,解引用可以访问整个数组的大小,即4个整型的大小,就是16字节
//*和&可以互相抵消,所以sizeof(*&a)==sizeof(a),所以是16字节
printf("%d\n",sizeof(&a+1));
//4/8字节--&a取出的是数组a的地址,&a+1还是地址,是地址就是4/8个字节,需要理解的是,&a+1跳过的是一个数组
printf("%d\n",sizeof(&a[0]));
//4/8字节--取出的是数组首元素的地址,计算的是地址的大小,是地址就是4/8个字节
printf("%d\n",sizeof(&a[0]+1));
//4/8字节--&a[0]取出首元素的地址,+1就是第二个元素的地址,是地址就是4/8个字节

image.png

//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));
//数组名arr单独放在sizeof内部,计算的是整个数组的大小,单位是字节,是6个字节
printf("%d\n", sizeof(arr+0));
//arr并非单独放在sizeof内部,也没有&,所以arr是首元素的地址,&arr[0],是地址就是4/8个字节
//在这里简单说明一下,指针变量的大小和类型无关,不管什么类型的指针变量,大小都是4/8个字节
//指针变量是用来存放地址的,地址存放需要多大空间,指针变量的大小就是几个字节
//32位环境下,地址是32个二进制位,需要4个字节
//64位环境下,地址是64个二进制位,需要8个字节
printf("%d\n", sizeof(*arr));
//arr表示数组首元素的地址,解引用就是数组首元素的,大小是1个字节
printf("%d\n", sizeof(arr[1]));
//arr[1]表示第二个元素,大小是1个字节
printf("%d\n", sizeof(&arr));
//&arr取出的是数组的地址,数组的地址也是地址,大小是4/8个字节
printf("%d\n", sizeof(&arr+1));
//&arr+1是跳过数组后的地址,也是地址,当然也是4/8个字节
printf("%d\n", sizeof(&arr[0]+1));
//&arr[0]取出首元素地址,+1就是第二个元素的地址,是地址就是4/8个字节

image.png


分析了上面的代码后,对上面的代码稍加修改,再来看一下输出的结果。


//strlen 求字符串长度,统计的是在字符串中\0之前的字符个数
char arr[] = {'a','b','c','d','e','f'};
//当前数组并没有在末尾有'\0'
printf("%d\n", strlen(arr));
//>=6随机值--arr是首元素的地址(没有'\0')
printf("%d\n", strlen(arr+0));
//arr是首元素地址,+0还是首元素地址,还是随机值
//printf("%d\n", strlen(*arr));
//通常给strlen传的参数是地址,arr是首元素的地址,*arr就是首元素,字符'a'的ASCII码值是97,
//站在strlen角度,认为传参进去的'a'-97就是地址,97作为地址直接进行访问,就是非法访问(错误代码)
//printf("%d\n", strlen(arr[1]));
//同上一样,也是错误代码
printf("%d\n", strlen(&arr));
//&arr取出整个数组的地址,类型是--char (*)[6],而strlen的参数类型是const char*,
//会有类型上的差异,但是依然可以运行,
printf("%d\n", strlen(&arr+1));
//&arr取出数组的地址,+1跳过数组,依然是随机值
printf("%d\n", strlen(&arr[0]+1));
//从第二个元素的地址开始,仍然是随机值


运行结果都是随机值:

image.png

char arr[] = "abcdef";
//a b c d e f \0
printf("%d\n", sizeof(arr));
//计算整个数组的大小,7
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));
//取出第一个元素的地址,+1就是第二个元素的地址,那么就是4/8个字节

image.png

char arr[] = "abcdef";
//a b c d e f \0
printf("%d\n", strlen(arr));
//表示首元素地址,统计\0之前的字符,结果是6
printf("%d\n", strlen(arr+0));
//首元素地址+0还是首元素地址,结果还是6
printf("%d\n", strlen(*arr));//err
//*arr表示第一个元素,会报错
printf("%d\n", strlen(arr[1]));//err
//同上的道理,传进去的是第二个元素的ASCII码值
printf("%d\n", strlen(&arr));
//取出的数组的地址,结果也是6
printf("%d\n", strlen(&arr+1));
//&arr+1跳过整个数组,把\0也跳过,结果就是随机值
printf("%d\n", strlen(&arr[0]+1));
//表示第二个元素的地址,结果是5

image.png

char* p = "abcdef";
//把a的地址存到指针变量p中
printf("%d\n", sizeof(p));
//4/8,计算的是指针变量的大小
printf("%d\n", sizeof(p + 1));
//p+1指向第二个元素,存的是第二个元素的地址,就是4/8个字节
printf("%d\n", sizeof(*p));
//*p是第一个元素,大小是1个字节
printf("%d\n", sizeof(p[0]));//p[0]==*(p+0)--->*p
//也是第一个元素,大小是1个字节
printf("%d\n", sizeof(&p));
//取出的是p的地址,大小也是4/8个字节,p的地址的类型是char**,是二级指针
printf("%d\n", sizeof(&p + 1));
//&p是地址,+1还是地址,是地址就是4/8个字节
//需要理解的是:&p+1指向哪里?跳过一个p的大小
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));
//&p的地址,无法确定有没有\0,是随机值
printf("%d\n", strlen(&p + 1));
//随机值,这里不再过多解释
printf("%d\n", strlen(&p[0] + 1));
//5

image.png


目录
相关文章
|
24天前
|
JavaScript
js 解析 byte数组 成字符串
js 解析 byte数组 成字符串
|
2月前
|
搜索推荐 C语言
指针与数组
指针与数组
51 9
|
2月前
|
SQL 存储 算法
【数据挖掘】恒生金融有限公司2023届秋招数据ETL工程师笔试题解析
恒生科技2022年9月24号数据ETL工程师岗位的笔试题目及答案汇总,包括了SQL选择题、SQL编程题和业务应用SQL编程题,涵盖了数据库基础知识、SQL语句编写以及数据仓库概念等多个方面。
50 2
【数据挖掘】恒生金融有限公司2023届秋招数据ETL工程师笔试题解析
|
2月前
|
机器学习/深度学习 自然语言处理 算法
【数据挖掘】2020奇安信秋招算法方向试卷1 笔试题解析
2020年奇安信秋招算法方向试卷1的题目解析,覆盖了数据结构、机器学习、深度学习、自然语言处理、排序算法、激活函数、主题模型、采样方法、图像处理等多个领域的知识点。
39 1
【数据挖掘】2020奇安信秋招算法方向试卷1 笔试题解析
|
2月前
|
机器学习/深度学习 存储 算法
【数据挖掘】2020奇安信秋招算法方向试卷3 笔试题解析
2020年奇安信秋招算法方向试卷3的题目解析,涵盖了数据结构、机器学习、深度学习、自然语言处理、排序算法、激活函数、PCA、词嵌入库等多个领域的知识点。
36 1
【数据挖掘】2020奇安信秋招算法方向试卷3 笔试题解析
|
2月前
|
算法 Java
双指针在数组遍历中的应用
文章深入探讨了双指针技术在数组遍历中的应用,通过实战例子详细解释了快慢指针和首尾指针的不同用法,并提供了解决LeetCode相关问题的Java代码实现。
|
2月前
|
存储 程序员 C语言
指针的高级应用:指针数组、数组指针、函数指针等。
指针的高级应用:指针数组、数组指针、函数指针等。
81 0
|
2月前
|
存储 JavaScript 前端开发
一文带你深度解析:JavaScript中对象与数组的威力究竟有多大?
一文带你深度解析:JavaScript中对象与数组的威力究竟有多大?
|
3月前
|
运维
开发与运维数组问题之指针的加减法意义如何解决
开发与运维数组问题之指针的加减法意义如何解决
38 7
|
3月前
|
C++ 索引 运维
开发与运维数组问题之在C++中数组名和指针是等价如何解决
开发与运维数组问题之在C++中数组名和指针是等价如何解决
22 6

热门文章

最新文章

推荐镜像

更多
下一篇
无影云桌面