C语言:指针【进阶】习题练习及分析讲解

这篇具有很好参考价值的文章主要介绍了C语言:指针【进阶】习题练习及分析讲解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言:

前面我们刚刚学完了C语言:指针详解【进阶】的知识,这部分的知识还是要重在理解加实践,今天我这里就分享一些有关C语言指针方面的练习供大家更深入的理解指针的知识。
我们初期的指针学习大部分都是与数组的知识绑定在一起的,所以今天的练习也是大多与数组有关的,目的是透过数组中指针的操作帮助强化理解指针在内存中的是如何操作的。


话不多说,直接上题:

一维数组

关于数组对于sizeof()和strlen函数的使用,这里先回顾一下:

数组名大部分情况下代表数组的首元素的地址

有两种情况例外:

  1. 数组名单独放在sizeof内部,这里数组名代表整个数组计算的是整个数组的大小
  2. &数组名,这里取出的是整个数组的地址

sizeof()计算的是数据在内存中所占的字节大小
strlen函数只能计算字符串的长度,计算过程中遇到\0结束

关于strlen函数和sizeof()的练习

下面程序输出结果是什么?

整型数组

练习一:

#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;
}

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:

内存:

C语言:指针【进阶】习题练习及分析讲解

对应题查看对应颜色的解释哦。

C语言:指针【进阶】习题练习及分析讲解


字符数组

练习二:

#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));
	return 0;
}

这里分两部分练习(sizeof的为一部分,strlen的为一部分)
sizeof的结果:
C语言:指针【进阶】习题练习及分析讲解
分析:

内存:
C语言:指针【进阶】习题练习及分析讲解
C语言:指针【进阶】习题练习及分析讲解


strlen的结果:

注意:strlen函数的参数类型

C语言:指针【进阶】习题练习及分析讲解

分析:
C语言:指针【进阶】习题练习及分析讲解
练习三:

#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;
}

注意这里的字符数组在内存中的存储形式

这里分两部分练习(sizeof的为一部分,strlen的为一部分)
sizeof的结果:
C语言:指针【进阶】习题练习及分析讲解

分析:

内存:注意这个数组后面还放了'\0','\0'也要占一个字节
C语言:指针【进阶】习题练习及分析讲解
C语言:指针【进阶】习题练习及分析讲解


strlen的结果:

注意:strlen函数的参数类型

C语言:指针【进阶】习题练习及分析讲解

分析:
C语言:指针【进阶】习题练习及分析讲解


指针

练习三:

#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;
}

这里分两部分练习(sizeof的为一部分,strlen的为一部分)
sizeof的结果:
C语言:指针【进阶】习题练习及分析讲解
分析:

内存:
C语言:指针【进阶】习题练习及分析讲解
C语言:指针【进阶】习题练习及分析讲解


strlen的结果:

注意:strlen函数的参数类型

C语言:指针【进阶】习题练习及分析讲解

分析:
C语言:指针【进阶】习题练习及分析讲解
练习三:

#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;
}

注意这里的字符串在内存中的存储形式

这里分两部分练习(sizeof的为一部分,strlen的为一部分)
sizeof的结果:
C语言:指针【进阶】习题练习及分析讲解

分析:

内存:注意这个字符串后面还放了'\0','\0'也要占一个字节

C语言:指针【进阶】习题练习及分析讲解
C语言:指针【进阶】习题练习及分析讲解


strlen的结果:

注意:strlen函数的参数类型

C语言:指针【进阶】习题练习及分析讲解

分析:
C语言:指针【进阶】习题练习及分析讲解

传入的是二级指针时指向的就是指针p的地址,strlen计算的就是从p的地址开始向后计算遇到\0时的长度。


二维数组

练习四:

#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;
}

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:
该二维数组在内存中是三个一维数组连续存放的。

内存:

C语言:指针【进阶】习题练习及分析讲解

C语言:指针【进阶】习题练习及分析讲解


笔试题

通过上面的练习,相信你应该已经能理解指针在内存中的操作了,下面是几道笔试题,一起来检验一下学习成果吧。


笔试题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));
	return 0;
}
//程序的结果是什么?

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:
C语言:指针【进阶】习题练习及分析讲解
C语言:指针【进阶】习题练习及分析讲解


笔试题2:

//由于还没深入学习结构体,这里告知结构体Test类型的大小是20个字节
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
#include <stdio.h>
int main()
{
	p = 0x100000;
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:
C语言:指针【进阶】习题练习及分析讲解

C语言:指针【进阶】习题练习及分析讲解


笔试题3:

#include <stdio.h>
int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;
}

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:

%x :打印16进制的数字
注意:这里需要画更细致的内存分布图才能分析清指针的操作
(默认小端存储)

C语言:指针【进阶】习题练习及分析讲解
C语言:指针【进阶】习题练习及分析讲解


笔试题4:

#include <stdio.h>
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	int* p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:
这道题其实考的是大家对操作符的了解,对于一个二维数组来说,要在二维数组内初始化,需要用到的是{},而不是(),这里的()是逗号表达式的操作符。

( , , ):逗号表达式是以此执行括号内的语句,但只有最后一句的表达式是整个逗号表达式的值。

所以,这里的二维数组中只初始化了前三个元素1,2,3,后面的元素都为0a[0]代表第一行的地址,p[0]就是第一行第一个元素1


笔试题5:

#include <stdio.h>
int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:

这里要注意不同类型的指针一次能访问到的空间是不同的
注意:地址是16进制数字

C语言:指针【进阶】习题练习及分析讲解


笔试题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));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:

C语言:指针【进阶】习题练习及分析讲解


笔试题7:

#include <stdio.h>
int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}

结果:
C语言:指针【进阶】习题练习及分析讲解

分析:

C语言:指针【进阶】习题练习及分析讲解


笔试题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);
	printf("%s\n", *-- * ++cpp + 3);
	printf("%s\n", *cpp[-2] + 3);
	printf("%s\n", cpp[-1][-1] + 1);
	return 0;
}

结果:

C语言:指针【进阶】习题练习及分析讲解

分析:

这里必须把内存布局画出来,才能清晰的观察指针的动向。
注意:cpp进行++--操作后,指针的指向是要发生变化的。

C语言:指针【进阶】习题练习及分析讲解


本篇有关C语言指针进阶的练习就到此结束了,希望你能从中学习到在面对指针问题时,尽量画出指针的内存操作图,进而解题的思路
重点说三遍:
画图!
画图!!
还是画图!!!
如果你还有什么问题可以评论区讨论或私信我哦。😘

下一篇文章将会对前面C语言指针【进阶】中的qsort函数的模拟实现写一篇博客,保证简单易懂,看完就会。
再往后我们会对字符串的研究进行深入了解,并讲解一系列关键的字符串函数和内存函数,和它们的模拟实现。


感兴趣的的小伙伴点点赞,点点关注,谢谢大家的阅读哦!!!
点点关注,后期不错过哦。😘
你们的鼓励就是我的动力,欢迎下次继续阅读!!!😘😘😘文章来源地址https://www.toymoban.com/news/detail-432634.html

到了这里,关于C语言:指针【进阶】习题练习及分析讲解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言】指针的进阶(二)—— 回调函数的讲解以及qsort函数的使用方式

    目录 1、函数指针数组 1.1、函数指针数组是什么?  1.2、函数指针数组的用途:转移表 2、扩展:指向函数指针的数组的指针 3、回调函数 3.1、回调函数介绍  3.2、回调函数的案例:qsort函数 3.2.1、回顾冒泡排序  3.2.1、什么是qsort函数? 函数指针数组 是什么?首先主语是 数

    2024年02月07日
    浏览(44)
  • 10 SQL进阶 -- 综合练习题 -- 10道经典SQL题目,配套数据与解答

    点击下方链接直接下载 创建数据表脚本:http://tianchi-media.oss-cn-beijing.aliyuncs.com/dragonball/SQL/create_table.sql 执行建表语句 执行成功 查看创建的表 点击下方链接直接下载 插入数据脚本:https://tianchi-media.oss-cn-beijing.aliyuncs.com/dragonball/SQL/data.zip 大家下载好脚本后,先在MySQL环境中运

    2024年04月27日
    浏览(39)
  • 日志审计与分析练习题

    1.  ( 单选题) 【单选题】以下关于日志的描述不正确的是( ) A. 日志是在事故发生后查明“发生了什么”的一个很好的“取证”信息来源,但无法为审计进行跟踪 B. 日志是由各种不同的实体产生的“安全记录”的集合 C. 通常为计算机系统、设备、软件等在某种情况下记录的信息

    2024年02月08日
    浏览(55)
  • 习题练习 C语言(暑期)

    今天为大家分享我暑假期间所练习的一些小题目! 相信大家看完之后都会有所提升的! 加油! 以下不正确的定义语句是( ) A: double x[5] = {2.0, 4.0, 6.0, 8.0, 10.0}; B: char c2[] = {‘x10’, ‘xa’, ‘8’}; C: char c1[] = {‘1’,‘2’,‘3’,‘4’,‘5’}; D: int y[5+3]={0, 1, 3, 5, 7, 9}; 题目解

    2024年02月10日
    浏览(54)
  • 习题练习 C语言

    首先我们要了解什么是offsetof宏: . 此具有函数形式的宏返回数据结构或联合类型中成员成员的偏移值(以字节为单位)。 . 返回的值是size_t类型的无符号整数值,其字节数位于指定成员与其结构开头之间。 什么意思呢,可以看到下面这张图片: 下面我们来看到这一习题:

    2024年02月14日
    浏览(50)
  • C语言习题练习

    首先我们要了解什么是offsetof宏: . 此具有函数形式的宏返回数据结构或联合类型中成员成员的偏移值(以字节为单位)。 . 返回的值是size_t类型的无符号整数值,其字节数位于指定成员与其结构开头之间。 什么意思呢,可以看到下面这张图片: 下面我们来看到这一习题:

    2024年02月15日
    浏览(52)
  • C 语言练习题更新

    目录(先不要看答案,首先自己做才能更好的领悟,做不来没关系) 题目一:有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析:可填在百位、十位、个位的数字都是 1、2、3、4,组成所有的排列后再去掉不满足条件的排列。 题目

    2024年02月14日
    浏览(45)
  • C语言之练习题

    欢迎来到我的: 世界 希望作者的文章对你有所帮助,有不足的地方还请指正,大家一起学习交流 ! 这期文章由:两题问答题+四道编程题;小孩在文章中写有详细解题思路,感谢大家支持支持。 思路: 首先我们要知道 x=x(x-1) 的含义; 假设x=3;也就是 011 ; 而x-1=2;是 010 ;

    2024年02月10日
    浏览(58)
  • 【C语言】练习题整理:11

    今天是10道选择题 下面代码段的输出结果是: -12 自右至左的结合方向称为“右结合性”。最典型的右结合 性运算符是赋值运算符。 如x=y=z,由于“=”的右结合性,应先执行y=z,再执行x=(y=z)运算。 C语言运算符中有不少为右结合性,应注意区别,以避免理解错误。 计算顺序是

    2024年02月11日
    浏览(46)
  • C语言/C++练习题

    题目:从键盘输入年份和月份,输出这个月的天数。 【样例输入】2023 1 【样例输出】31 【样例输入】2020 2 【样例输出】29 提示:当输入的月份为2月份时,需要判断该年年份是否为闰年。 判断闰年的条件:年份为4的倍数并且不是100的倍数,或者年份是400的倍数。 ​ 在控制

    2024年02月06日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包