C语言——指针和数组练习题解析

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

前言:

学习了指针的初阶和进阶后,已经对指针有了一定了解。下面就需要做题目,去巩固所学的知识。
对数组名的理解:
数组名是数组首元素的地址,但是由两个例外

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名是整个数组,取出的是整个数组的地址。

一、一维数组

#include <stdio.h>
int main()
{
    int arr1[] = { 1,2,3,4 };
    printf("%d\n", sizeof(arr1));
    //16(计算整个数组的大小)
    printf("%d\n", sizeof(arr1+0));
    //4/8(数组名arr1是首元素地址,a+0还是首元素的地址,地址的大小为4/8个字节)
    printf("%d\n", sizeof(*arr1));
    //4(*arr1是首元素,大小是4个字节)
    printf("%d\n", sizeof(arr1+1));
    //4/8(arr1是首元素的地址,arr1+1是第二个元素的地址,地址大小为4/8个字节)
    printf("%d\n", sizeof(arr1[1]));
    //4(arr1[1]是第2个元素,大小是4个字节)
    printf("%d\n", sizeof(&arr1));
    //4/8(&arr1是数组的地址,数组的地址也是地址,是地址那就是4/8个字节)
    printf("%d\n", sizeof(*&arr1));
    //16(&arr1是数组的地址,*&arr1是整个数组的元素,是16个字节)
    printf("%d\n", sizeof(&arr1+1));
    //4/8(&arr1是整个数组的地址,&arr1+1是跳过了整个数组的下一个地址,是地址那就是4/8个字节)
    printf("%d\n", sizeof(&arr1[0]));
    //4/8(arr1[0]是首元素,&arr1[0]是首元素的地址,是地址那就是4/8个字节)
    printf("%d\n", sizeof(&arr1[0]+1));
    //4/8(&arr1[0]是首元素的地址,&arr1[0]+1是第二个元素的地址,是地址那就是4/8个字节)
    return 0;
}

二、字符数组

#include <stdio.h>
#include <string.h>
int main()
{
    char arr2[] = { 'a','b','c','d','e','f' };
    printf("%d\n", sizeof(arr2));
    //6(数组名单独放在sizeof内部,这里的arr2表示整个数组,计算的是整个数组的大小,单位是字节,大小为6个字节)
    printf("%d\n", sizeof(arr2+0));
    //4/8(arr2表示数组的首元素地址,arr2+0还是数组的首元素地址,是地址就是4/8个字节)
    printf("%d\n", sizeof(*arr2));
    //1(arr2表示数组的首元素地址,*arr2表示首元素,大小为1个字节)
    printf("%d\n", sizeof(arr2[1]));
    //1(arr2[1]表示第二个元素,大小为1个字节)
    printf("%d\n", sizeof(&arr2));
    //4/8(&arr2是整个数组的地址,是地址就是4/8个字节)
    printf("%d\n", sizeof(&arr2+1));
    //4/8(&arr2是整个数组的地址,&arr2+1是跳过整个数组后的地址,是地址就是4/8个字节)
    printf("%d\n", sizeof(&arr2[0]+1));
    //4/8(&arr2[0]是数组的首元素地址,&arr2[0]+1是第二个元素的地址,是地址那就是4/8个字节)

    printf("%d\n", strlen(arr2));
    //随机值(因为字符数组中没有\0,所以求字符长度的时候,会一直往后找,产生的结果是随机值)
    printf("%d\n", strlen(arr2+0));
    //随机值(arr2+0是数组的首元素地址,是随机值)
    printf("%d\n", strlen(*arr2));
    //非法访问(arr2是数组的首元素地址,*arr2是数组首元素,就是字符‘a’也是97,strlen就从97这个地址开始访问,统计字符串长度,非法访问)
    printf("%d\n", strlen(arr2[1]));
    //非法访问(arr2[1]是第二个元素‘b’,以第二个元素的值为地址开始访问,统计字符串长度,非法访问)
    printf("%d\n", strlen(&arr2));
    //随机值(&arr2是整个数组的地址,数组的地址和数组首元素的地址,值是一样的,传递给strlen函数,从数组第一个位置开始统计字符串长度,结果是随机值)
    printf("%d\n", strlen(&arr2+1));
    //随机值(&arr2是整个数组的地址,&arr2+1跳过整个数组后的地址,然后开始统计字符串长度,结果为随机值)
    printf("%d\n", strlen(&arr2[0]+1));
    //随机值(&arr2[0]是首元素的地址,&arr2[0]+1是第二个元素的地址,从第二个元素地址开始统计字符串长度,结果为随机值)

    char arr3[] = "abcdef";
    printf("%d\n", sizeof(arr3));
    //7(计算整个数组的大小,‘\0’也统计在内,为7个字节)
    printf("%d\n", sizeof(arr3 + 0));
    //4/8(arr3为数组首元素地址,arr3 + 0也是数组首元素地址,是地址就是4/8个字节)
    printf("%d\n", sizeof(*arr3));
    //1(arr3为数组首元素地址,*arr3为数组首元素,首元素为1个字节)
    printf("%d\n", sizeof(arr3[1]));
    //1(arr3[1]为第二个元素,占1个字节)
    printf("%d\n", sizeof(&arr3));
    //4/8(&arr3为整个数组的地址,是地址那就是4/8个字节)
    printf("%d\n", sizeof(&arr3 + 1));
    //4/8(&arr3为整个数组的地址,&arr3 + 1跳过整个数组后的地址,是地址那就是4/8个字节)
    printf("%d\n", sizeof(&arr3[0] + 1));
    //4/8(&arr3[0]是首元素的地址,&arr3[0] + 1是第二个元素的地址,是地址那就是4/8个字节)

    printf("%d\n", strlen(arr3));
    //6(计算字符串的长度,为6)
    printf("%d\n", strlen(arr3 + 0));
    //6(arr3为首元素地址,arr3 + 0还是首元素地址,从首元素地址开始访问,统计字符串长度,字符串长度为6)
    printf("%d\n", strlen(*arr3));
    //非法访问(*arr3为数组首元素的值,非法访问)
    printf("%d\n", strlen(arr3[1]));
    //非法访问(arr3[1]为第二个元素'b',ASCII码值就是98,地址为98,开始统计字符串长度,非法访问)
    printf("%d\n", strlen(&arr3));
    //6(&arr3整个数组的地址,也是首元素地址,字符串长度为6)
    printf("%d\n", strlen(&arr3 + 1));
    //随机值(&arr3 + 1是跳过整个数组后的地址,然后开始访问,统计字符串长度,为随机值)
    printf("%d\n", strlen(&arr3[0] + 1));
    //5(&arr3[0] + 1是第二个元素的地址,从第二个元素开始统计字符串长度,长度为5)

    char* p = "abcdef";
    printf("%d\n", sizeof(p));
    //4/8(p是一个指针变量)
    printf("%d\n", sizeof(p+1));
    //4/8(p+1指向第二个元素的地址)
    printf("%d\n", sizeof(*p));
    //1(第一个元素,大小为1个字节)
    printf("%d\n", sizeof(p[0]));
    //1(数组法,第一个元素,大小为1个字节)
    printf("%d\n", sizeof(&p));
    //4/8(&p指向的是p的地址,类型是char**,是地址那就是4/8个字节)
    printf("%d\n", sizeof(&p + 1));
    //4/8(&p + 1指向的是‘\0’后面的地址,是地址那就是4/8个字节)
    printf("%d\n", sizeof(&p[0] + 1));
    //4/8(&p[0] + 1指向第二个元素的地址,得到的是‘b’的地址,是地址那就是4/8个字节)


    printf("%d\n", strlen(p));
    //6(p指向字符串首地址)
    printf("%d\n", strlen(p+1));
    //5(p+1指向字符串第二个元素首地址)
    printf("%d\n", strlen(*p));
    //非法访问(*p是—>‘a’,以‘a’为地址访问,统计字符串长度,非法访问)
    printf("%d\n", strlen(p[1]));
    //非法访问(p[1]为第二个元素‘b’,以‘b’为地址访问,统计字符串长度,非法访问)
    printf("%d\n", strlen(&p));
    //随机值(&p指向的是p的地址,类型是char**)
    printf("%d\n", strlen(&p + 1));
    //随机值(&p+1,指向的是字符串‘\0’后面的地址,)
    printf("%d\n", strlen(&p[0] + 1));
    //5(&p[0] + 1第二个元素的地址,从第二个元素地址统计字符串长度,长度为5)
    return 0;
}

三、二维数组

#include <stdio.h>
int main()
{
    int a[3][4] = { 0 };
    printf("%d\n", sizeof(a));
    //3*4*4=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内部,没有&,那么a[0]表示数组的首元素地址,也就是a[0][0]的地址,所以a[0]+1是第一行第二个元素的地址,是地址那就是4/8个字节)
    printf("%d\n", sizeof(*(a[0]+1)));
    //4(计算第一行第二个元素的大小)
    printf("%d\n", sizeof(a+1));
    //4/8(a是数组首元素地址,是第一行的地址;a+1就是第二行的地址,类型是int(*)[4])
    printf("%d\n", sizeof(*(a+1)));
    //16(*(a+1)->a[1]->sizeof(*(a+1))->sizeof(a[1]),计算的是第二行的大小;a+1是第二行的地址,类型int(*)[4],*(a+1)访问的是第二行的数组)
    printf("%d\n", sizeof(&a[0]+1));
    //4/8(&a[0]是第一行的地址,&a[0]+1是第二行的地址,是地址那就是4/8个字节)
    printf("%d\n", sizeof(*( &a[0] + 1)));
    //16(第二行的大小)
    printf("%d\n", sizeof(*a));
    //16(a是数组首元素的地址,就是第一行的地址,*a就是第一行,*a—>*(a+0)—>a[0])
    printf("%d\n", sizeof(a[3]));
    //16(不访问,只看类型)
    return 0;
}

表达式有两个属性:

  1. 值属性:9
  2. 类型属性:s=a+2——>short
#include <stdio.h>
int main()
{
    int a = 7;
    short s = 4;
    printf("%d\n", sizeof(s = a + 2));
    printf("%d\n", s);
    return 0;
}

打印:
2
4

四、指针题目

题目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>
//结构体大小为20个字节
struct test
{
    int num;
    char* pc;
    short date;
    char cha[2];
    short ba[4];
}*p;
int main()
{
    printf("%d\n", sizeof(struct test));
    printf("%p\n", p);
    printf("%p\n", p + 0x1);//p是结构体类型的指针,占20个字节,加1就是跳过一个结构体
    printf("%p\n", (unsigned long)p + 0x1);//无符号长整型是数值
    printf("%p\n", (unsigned int*)p + 0x1);//整型指针占4个字节
    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 %x\n", *ptr1, ptr1[-1], *ptr2);
    return 0;
}

C语言——指针和数组练习题解析,C语言,c语言,算法,开发语言
分析:
C语言——指针和数组练习题解析,C语言,c语言,算法,开发语言
题目4:

#include <stdio.h>
int main()
{
    int a[3][2] = { (0,1),(2,3),(4,5) };
    int* p;
    p = a[0];//没有&,也不在sizeof内部,表示第一行首地址表示&a[0][0]
    printf("%d\n", p[0]);//打印   1(p[0]->*p,*p的值是1)
    return 0;
}

题目5:

#include <stdio.h>
int main()
{
    int a[5][5];//定义一位二维数组(类型为int(*)[5])
    int(*p)[4];//定义一个数组指针(类型为int(*)[4])
    p = a;
    printf("%p,%b\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);//打印 ff ff ff fc      -4
    //-4
    //10000000 00000000 00000000 00000100原码
    //11111111 11111111 11111111 11111011反码
    //11111111 11111111 11111111 11111100补码
    //打印0xff ff ff fc
    return 0;
}

C语言——指针和数组练习题解析,C语言,c语言,算法,开发语言
分析:
C语言——指针和数组练习题解析,C语言,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\n", *(ptr1 - 1), *(ptr2 - 1));//打印  10,5
    return 0;
}

题目7:

#include <stdio.h>
int main()
{
    char* a[] = { "work","at","alibaba"};
    char** pa = a;//a的首地址
    pa++;
    printf("%s\n", *pa);//打印at
    return 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 );
    printf("%s\n",*--*++cpp+3 );
    printf("%s\n", *cpp[-2]+3);
    printf("%s\n", cpp[-1][-1]+1);
    return 0;
}

C语言——指针和数组练习题解析,C语言,c语言,算法,开发语言
分析:
C语言——指针和数组练习题解析,C语言,c语言,算法,开发语言文章来源地址https://www.toymoban.com/news/detail-602810.html

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

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

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

相关文章

  • C语言练习题解析:挑战与突破,开启编程新篇章!(1)

    💓博客主页:江池俊的博客 ⏩收录专栏:C语言刷题专栏 👉专栏推荐:✅C语言初阶之路 ✅C语言进阶之路 💻代码仓库:江池俊的代码仓库 🎉欢迎大家点赞👍评论📝收藏⭐ 🤝表情分享:🔎📷🥇🎈🐬🍁💯⭕️💮📍🚩👀🚨🧩💥📌🌴 🎈前言: 本专栏每篇练习将包

    2024年02月10日
    浏览(34)
  • C语言练习题解析:挑战与突破,开启编程新篇章!(2)

    💓博客主页:江池俊的博客 ⏩收录专栏:C语言刷题专栏 👉专栏推荐:✅C语言初阶之路 ✅C语言进阶之路 💻代码仓库:江池俊的代码仓库 🎉欢迎大家点赞👍评论📝收藏⭐ 🎈前言: 本专栏每篇练习将包括 5个选择题 + 2个编程题 ,将涵盖C语言的不同方面,包括基础语法、

    2024年02月10日
    浏览(36)
  • 树状数组练习题

    为什么大佬们一眼看出是树状数组呢? 不是一眼看出树状数组,而是 要把 【找两个相邻的最小值之间还有几个数没删掉】 的问题转变成动态区间和问题,这个转化过程才是最重要的 , 至于你用什么数据结构求动态区间和是次要的,很多数据结构都能做,最常用的树状数组

    2024年02月03日
    浏览(31)
  • 数组练习题,数组的动态初始化

    定义一个数组,求和 定义一个数组,统计数组里面一共有多少能够被3 整除的数字: 定义一整数类型数组,如果该数字是奇数,则将当前数字扩大两倍,如果是偶数,则将该数字变成该数字的1/2. 一个循环尽量只做一件事情,虽然把打印写的同一个循环里面可以,结果一样,

    2024年02月15日
    浏览(38)
  • 【JAVA】数组的概念;数组的使用;引用;内存分区;数组练习题

    🍉内容专栏:【JAVA从0到入门】 🍉本文脉络:数组的概念;数组的使用;引用;内存分区;数组练习题 🍉本文作者:Melon_西西 🍉发布时间 :2023.7.20 目录 1. 数组的基本概念 2数组的创建及初始化 2.1 数组的创建: T [ ] 数组名 = new T[N]; 2.2 数组的初始化 : 动态初始化和静态初

    2024年02月16日
    浏览(34)
  • Java练习题-用冒泡排序法实现数组排序

    ✅作者简介:CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1🏆 📃个人主页:hacker707的csdn博客 🔥系列专栏:Java练习题 💬个人格言:不断的翻越一座又一座的高山,那样的人生才是我想要的。这一马平川,一眼见底的活,我不想要,我的人生

    2024年02月08日
    浏览(40)
  • Vue练习题(带解析)

    Vue基础入门 一、 填空题 Vue是一套构建 __ 用户界面 _____ 的渐进式框架。 MVVM主要包含3个部分,分别是Model、View和____ ViewModel ___。 Vue中通过 ___ refs ____ 属性获取相应DOM元素。 在进行Vue调试时,通常使用 ___ vue-devtools ___ 工具来完成项目开发。 Vue中页面结构以 ___ 组件  ___ 形式

    2024年02月05日
    浏览(47)
  • Vue课后练习题及答案解析

    第一章 Vue.js基础入门 填空题 Vue是一套构建________的渐进式框架。 MVVM主要包含3个部分,分别是Model、View和________。 Vue中通过________属性获取相应的DOM元素。 在进行Vue调试时,通过使用________工具来完成项目开发。 Vue中页面结构以________形式存在。 判断题 Vue与Angular和React框架

    2024年02月09日
    浏览(39)
  • 【技能树笔记】网络篇——练习题解析(十)

    【技能树笔记】网络篇——练习题解析(一)-CSDN博客 【技能树笔记】网络篇——练习题解析(二)-CSDN博客 【技能树笔记】网络篇——练习题解析(三)-CSDN博客 【技能树笔记】网络篇——练习题解析(四)-CSDN博客 【技能树笔记】网络篇——练习题解析(五)-CSDN博客 【

    2024年02月08日
    浏览(31)
  • 【技能树笔记】网络篇——练习题解析(七)

    目录 前言 一、RIP 1.1 VLAN数据帧 二、OSPF 2.1 OSPF 分组类型 2.2 OSPF 区域划分 2.3 OSPF状态交互链路 2.4 OSPF特殊区域 三、ISIS 3.1 ISIS动态路由协议 3.2 ISIS路由器分类 3.3 ISIS DIS 四、BGP 4.1 BGP基本信息 4.2 BGP属性 4.3 BGP路由通告 五、路由策略 5.1 路由策略作用 5.2 路由策略应用

    2024年02月08日
    浏览(30)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包