当前位置:网站首页>c语言经典指针和数组笔试题解析
c语言经典指针和数组笔试题解析
2022-07-04 04:51:00 【real Wangyanbin】
前面我们已经学习了数组,指针初阶和进阶。学了上述知识还没有练习多少题目,接下来就来看看c语言经典指针和数组笔试题解析
一维数组
#include<stdio.h>
int main()
{
int a[] = {
1,2,3,4 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(a[1]));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0] + 1));
return 0;
}
我们在进行题目练习之前回顾一下基础知识
sizeof()计算的是数据所占空间的大小单位是字节。
数组名代表的是数组首元素的地址,但是有两种情况除外:
- sizeof(数组名) 计算的是整个数组的大小,注意是只有数组名,有其他操作就不是整个数组的大小了。
- &数组名,取出的是整个数组的地址,+1,-1跳过的是整个数组。
地址的大小是4/8,与电脑有关。
题目解析
#include<stdio.h>
int main()
{
int a[] = {
1,2,3,4 };
printf("%d\n", sizeof(a));//16
//sizeof(数组名),计算的是整个数组的大小,
//所以输出值为4*4=16
printf("%d\n", sizeof(a + 0));// 4/8
//sizeof()内部a并不是单独存在的,也没有&
//所以数组名代表的是数组首元素的地址
printf("%d\n", sizeof(*a));//4
//*a中a是数组首元素的地址,*a找到的就是数组首元素
//首元素是整形,大小是4字节
printf("%d\n", sizeof(a + 1));//4/8
//a是数组首元素的地址,a+1是数组第二个元素的地址。
//地址的大小是4/8
printf("%d\n", sizeof(a[1]));//4
//a[1]数组第二个元素,大小4字节。
printf("%d\n", sizeof(&a));
//&a是整个数组的地址,只要是地址大小为4/8
printf("%d\n", sizeof(*&a));//16
//有两种理解方式
//1.&a<-->int (*)[4]
// &a取出的是数组名的地址,类型是int (*)[4],是数组指针
// 数组指针指向的是数组,*&a-->a
//
//2.&和*抵消了,*&a-->a
printf("%d\n", sizeof(&a + 1));// 4/8
//&a取出的是数组的地址,&a<-->int (*)[4]
//&a+1 是从数组a的地址向后跳过了一个(4个整形元素)数组的大小。
//&a+1还是地址,是地址就是4/8字节
printf("%d\n", sizeof(&a[0]));//4/8
//a[0]数组首元素,&a[0]数组首元素的地址
printf("%d\n", sizeof(&a[0] + 1));// 4/8
//&a[0]+1,数组首元素地址+1-->数组第二个元素地址。
return 0;
}
字符数组
需要补充的知识,strlen是函数,头文件<string.h>,是专门获取字符串长度的函数,字符串的结束标志是’\0’,字符数组什么时候出现‘\0’就是strlen函数获取字符串长度的关键。
第一组–>字符数组
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = {
'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
代码解析
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = {
'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6
//sizeof(数组名),数组所占空间大小,1*6=6byte
printf("%d\n", sizeof(arr + 0));// 4/8
//arr+0,数组名未单独出现在sizeof内,数组名代表数组首元素地址
//arr+0数组首元素地址
printf("%d\n", sizeof(*arr));// 1
//*arr,对数组首元素地址进行解引用,数组首元素。
//数组首元素是字符型,大小为1byte
printf("%d\n", sizeof(arr[1]));// 1
//数组首元素大小1byte
printf("%d\n", sizeof(&arr));// 4/8
//&arr,取出整个数组的地址,它是地址
//是地址大小为4/8
printf("%d\n", sizeof(&arr + 1));//4/8
//&arr + 1是数组后的地址。
printf("%d\n", sizeof(&arr[0] + 1));//4/8
//&arr[0] + 1是数组第二个元素的地址
printf("%d\n", strlen(arr));//随机值1
//字符数组内'a','b','c','d','e','f'。
//字符数组后面的'\0'还不知道在什么位置。
//所以大小为随机值
printf("%d\n", strlen(arr + 0));///随机值
//arr+0数组首元素的地址,和arr效果一样
//printf("%d\n", strlen(*arr));//报错
//*arr为数组首元素'a',ASCII码为97
//strlen('a')-->strlen(97)
//地址为97的内存是属于系统的,不允许用户使用。
//访问的地址不能预测产生什么效果,*arr可视为野指针
//改代码会报错
//printf("%d\n", strlen(arr[1]));//报错
//a[1]-->'b',
//strlen('b')-->strlen(98)
//产生错误的原因与*a相同
printf("%d\n", strlen(&arr));//随机值1
//&a为整个数组的地址,但是地址访问还是从首元素地址开始
//所以结果也是随机值
printf("%d\n", strlen(&arr + 1)); //随机值1 - 6
//&arr+1,跳过的是整的数组,地址为数组后面的地址
//也为随机值,但是该随机值为随机值1-6
printf("%d\n", strlen(&arr[0] + 1)); //随机值1 - 1
//&arr[0]+1是数组第二个元素的地址,该结果也为随机值
//但是该随机值的为 随机值1-1
return 0;
}
字符串
字符串"abcdef",存放在字符数组中,f后默认为’\0’,
strlen是求字符串长度的,关注的是字符串中的\0,计算的是\0之前出现的字符的个数
strlen是库函数,只针对字符串
sizeof只关注占用内存空间的大小,不在乎内存中放的是什么
sizeof是操作符
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
题目解析
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdef";
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));//4/8,数组第二个元素地址的大小
printf("%d\n", strlen(arr));//6,字符串的大小
printf("%d\n", strlen(arr + 0));//6
printf("%d\n", strlen(*arr));//错误,*arr=‘a’;访问地址非法
printf("%d\n", strlen(arr[1]));//错误,arr[1]='b';访问地址非法
printf("%d\n", strlen(&arr));//6,整个数组的地址,得到的也是最低地址处的地址
printf("%d\n", strlen(&arr + 1));//随机值,跳过了整个数组不知道是数组后面的地址
//‘/0’的位置不确定
printf("%d\n", strlen(&arr[0] + 1));//5,指针跳过1个字符型大小的字节
//是第二个元素的地址,计算字符串长度6-1
return 0;
}
常量字符串
需要注意的地方是,char* p = “abcdef”;p是指针变量。 p存储的"abcdef"是字符串首地址,而不是存储的字符串。p+1跳过的是一个字符型所占空间的大小
练习题:
#include<stdio.h>
#include<string.h>
int main()
{
char* p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p + 1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p + 1));
printf("%d\n", sizeof(&p[0] + 1));
printf("%d\n", strlen(p));
printf("%d\n", strlen(p + 1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p + 1));
printf("%d\n", strlen(&p[0] + 1));
return 0;
}
题目解析:
#include<stdio.h>
#include<string.h>
int main()
{
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,字符指针p的地址
printf("%d\n", sizeof(&p + 1));//4/8,+1跳过一个字符指针的大小,
//但是该空间指向的不确定是谁。
printf("%d\n", sizeof(&p[0] + 1));//4/8,p[0]-->*(p+0)-->*p
//&p[0]+1-->p+1,字符串常量第二个字符地址
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是取出指针变量p的地址,
//指针变量p存储的是常量字符串的地址,strlen函数把字符串常量的地址
//看作字符串,这个是一个不确定的值,常量字符串的地址在指针变量中的存储
//是大端存储还是小端存储还是不确定的,所以结果为随机值
printf("%d\n", strlen(&p + 1));//随机值,但是与&p两个随机值没有什么关系
//&p+1是跳过一个指针的大小,指向的该地址与p中不能确定设有'\0'.
//还是谁没有'\0',还是都没有'\0'.
printf("%d\n", strlen(&p[0] + 1));//5,&p[0]+1-->p+1
return 0;
}
二维数组
需要注意的一些知识
二维数组可以看作是一维数组的数组
数组名代表着首元素的地址,二维数组首元素是一维数组,所以二维数组的的数组名代表第一行一位数组的地址
int a[3][4] = { 0 };
- a[0]可以看作是二维数组第一行一维数组的地址,以此类推a[1],a[2]
- arr单独在sizeof()内,或者&arr是整个二维数组的地址,其余情况是arr[0]的地址,数据类型int(*)[4]
sizeof()内部表达式是不进行运算的,只是得到该表达式的数据类型
例题:
#include<stdio.h>
#include<stdio.h>
int main()
{
int a[3][4] = {
0 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0] + 1));
printf("%d\n", sizeof(*(a[0] + 1)));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(*(a + 1)));
printf("%d\n", sizeof(&a[0] + 1));
printf("%d\n", sizeof(*(&a[0] + 1)));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a[3]));
return 0;
}
解析:
#include<stdio.h>
#include<stdio.h>
int main()
{
int a[3][4] = {
0 };
printf("%d\n", sizeof(a));//48
//3*4*4
printf("%d\n", sizeof(a[0][0]));//4
//二维数组第一个整形元素的大小
printf("%d\n", sizeof(a[0]));//16
//a[0],相当于第一行一维数组名,sizeof(a[0])
//是二维数组第一行的大小
printf("%d\n", sizeof(a[0] + 1));//4/8
//a[0], 相当于第一行一维数组名
//a[0]+1,相当于二维数组第一行第二个元素地址
printf("%d\n", sizeof(*(a[0] + 1)));//4
//*(a[0] + 1)-->a[0][1]
//计算的是第一行第二个元素的大小
printf("%d\n", sizeof(a + 1));//4/8
//a+1二维数组第二行元素的地址
printf("%d\n", sizeof(*(a + 1)));//16
//*(a + 1)-->a[1],相当于第二行一维数组名,sizeof(a[1])
//是二维数组第二行的大小
printf("%d\n", sizeof(&a[0] + 1));//4/8
//&a[0]-->&*(a+0)-->a
//&a[0] + 1-->a+1
printf("%d\n", sizeof(*(&a[0] + 1)));//16
//&a[0] + 1-->a+1
//*(&a[0] + 1)-->*(a+1)-->a[1]
//a[1], 相当于第二行一维数组名,sizeof(a[1])
//是二维数组第二行的大小
printf("%d\n", sizeof(*a));//16
//*a-->a[0]是二维数组第一行的地址
printf("%d\n", sizeof(a[3]));//16
//a[3]是二维数组第4行的地址
//虽然二维数组没有第四行,但该代码不是越界
//sizeof()内部表达式是不进行运算的,只是得到该表达式的数据类型
return 0;
}
边栏推荐
- Technology Management - learning / practice
- Network equipment emergency response Guide
- Simulink与Arduino串口通信
- Automated testing selenium foundation -- webdriverapi
- 【MATLAB】MATLAB 仿真数字基带传输系统 — 双极性基带信号(余弦滚降成形脉冲)的眼图
- Zhongke panyun-d module analysis and scoring standard
- 数据标注是一块肥肉,盯上这块肉的不止中国丨曼孚科技
- [matlab] matlab simulation - low pass Gaussian white noise
- Error response from daemon: You cannot remove a running container 8d6f0d2850250627cd6c2acb2497002fc3
- Flutter ‘/usr/lib/libswiftCore. dylib‘ (no such file)
猜你喜欢

C basic (VII) document operation

Share some of my telecommuting experience
![[paper summary] zero shot semantic segmentation](/img/78/ee64118d86a7e43ec4d1cb97191fbe.jpg)
[paper summary] zero shot semantic segmentation

Simple g++ and GDB debugging

Notes on the paper "cross view transformers for real time map view semantic segmentation"

拼夕夕二面:说说布隆过滤器与布谷鸟过滤器?应用场景?我懵了。。

NTFS security permissions

《Cross-view Transformers for real-time Map-view Semantic Segmentation》论文笔记

Public inputs in appliedzkp zkevm (13)

Customize a pager needed in your project
随机推荐
2022危险化学品经营单位安全管理人员上岗证题库及答案
2022年T电梯修理操作证考试题库及模拟考试
TCP state transition diagram
小程序毕业设计---美食、菜谱小程序
【MATLAB】通信信号调制通用函数 — 低通滤波器
LM小型可编程控制器软件(基于CoDeSys)笔记二十一:错误3703
MAUI 入门教程系列(5.XAML及页面介绍)
Flutter ‘/usr/lib/libswiftCore. dylib‘ (no such file)
The second case analysis of the breakthrough of defense system from the perspective of the red team
Maui introductory tutorial series (5.xaml and page introduction)
Zkevm (12) state proof of appliedzkp
Error response from daemon: You cannot remove a running container 8d6f0d2850250627cd6c2acb2497002fc3
【MATLAB】通信信号调制通用函数 — 带通滤波器
TCP状态转换图
PostgreSQL 正式超越 MySQL,这家伙也太强了吧!
Just do it with your hands 7 - * project construction details 2 - hook configuration
Annex III: scoring standard of the defender docx
[QT] timer
2022广东省赛——编码信息获取 解析flag
中科磐云—D模块解析以及评分标准
