【C语言】深入解开指针(三)

  🌈write in front :

🔍个人主页 : @啊森要自信的主页

真正相信奇迹的家伙,本身和奇迹一样了不起啊!

欢迎大家关注🔍点赞👍收藏⭐️留言📝>希望看完我的文章对你有小小的帮助,如有错误,可以指出,让我们一起探讨学习交流,一起加油鸭。 请添加图片描述

文章目录

  • 前言
  • ▶️、 数组名的理解
  • ▶️、 使⽤指针访问数组
  • ➡️、⼀维数组传参的本质
  • ➡️、⼆级指针
  • 🔼、指针数组
  • 🅿️总结


前言

本小节,我们继续深入理解指针,阿森将在本小节带你理解数组名,怎么使用指针访问数组,一维数组传参的本质,冒泡排序的方法,还有我们的二级指针创建,指针数组的,生命,创建和运用。接下来让我们启程!


▶️、 数组名的理解

  1. %d:用于打印整数。
  2. %f:用于打印浮点数。
  3. %c:用于打印单个字符。
  4. %s:用于打印字符串。
  5. %p:用于打印指针地址。
  6. %x:用于以十六进制格式打印整数。
  7. %o:用于以八进制格式打印整数。
  8. %e:用于以科学计数法打印浮点数。
  9. %u:用于以无符号整数格式打印整数。

对于数组名,我们在学习函数的时候,我们就了解到数组名arr就是数组首元素的地址,当然也可以取地址数组首元素&arr[0].

#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("&arr[0]=%p\n", &arr[0]);//数组首元素printf("arr=    %p\n", &arr);//数组名return 0;
}

运行结果:
在这里插入图片描述
我们看到运行结果可以看出数组名和数组首元素的地址一模一样。因此,数组名就是数组首元素(第一个元素)的地址

既然arr是是首元素的地址,那sizeof(arr)计算的也应该是计算的是数组首元素的大小,单位字节。那么他应该计算的是首元素的大小,也就是4或者8(因为分别是32位或64位环境),事实真的如此吗?

sizeof是一个运算符,用于获取数据类型或变量的大小(以字节为单位)。它的语法如下:

sizeof(type)
sizeof(variable)

其中,type可以是任何数据类型,比如int、char、float等,而variable可以是任何变量名。

sizeof返回的是一个size_t类型的值,表示对应类型或变量所占用的字节数。在实际编程中,sizeof经常用于在程序中动态计算数组的大小,或者确保在处理内存分配和复制时不会出现越界的情况。
在这里插入图片描述
其实不然,并没有打印我们想要的? 那这怎么解释呢?
输出的结果是:40,如果arr是数组⾸元素的地址,那输出应该的应该是4/8才对。
其实数组名就是数组⾸元素(第⼀个元素)的地址是对的,但是有两个例外:

  • 1️⃣ sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰(整个数组),计算的是整个数组的⼤⼩,单位是字节
  • 2️⃣ &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的)
    除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。
    在这里插入图片描述
#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("%d\n", sizeof(arr));printf("%p\n", &arr[0]);printf("%p\n", arr);printf("%p\n", &arr);return 0;
}

运行结果:
在这里插入图片描述
打印结果⼀模⼀样,这时候⼜纳闷了,那arr&arr有啥区别呢?

#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("&arr[0] =   %p\n", &arr[0]);printf("&arr[0]+1 = %p\n", &arr[0] + 1);printf("arr =       %p\n", arr);printf("arr+1 =     %p\n", arr + 1);printf("&arr =      %p\n", &arr);printf("&arr+1 =    %p\n", &arr + 1);return 0;
}

在这里插入图片描述
这⾥我们发现&arr[0]&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,是因为&arr[0] 和 arr 都是⾸元素的地址,+1就是跳过⼀个元素。
但是&arr&arr+1相差40个字节,这就是因为&arr是数组的地址,+1 操作是跳过整个数组的。
在C语言中,arr&arr有着不同的含义和用法。

  1. arr:表示数组的名称,它代表数组的首元素的地址。在大多数情况下,当使用数组名arr时,它会被隐式转换为指向数组第一个元素的指针。因此,arr表示的是数组的地址,而不是整个数组的内容。

  2. &arr:表示对整个数组的取地址操作。它得到的是整个数组的地址,而不是数组的第一个元素的地址。因此,&arr表示的是整个数组的地址,而不是数组的内容。

总结来说,arr表示数组的首元素地址,而&arr表示整个数组的地址。在大多数情况下,当我们需要传递数组给函数时,实际上传递的是数组的首元素地址,因此arr&arr在传递参数时的用法可能会有所不同。

▶️、 使⽤指针访问数组

知道了数组名,数组的地址,那我们不就可以用指针访问数组了,遍历数组的元素了,好接下来,启动!

#include <stdio.h>
int main()
{int arr[10] = { 0 };//输⼊int i = 0;//整个数组大小40/单个数组字节4=10int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素个数//输⼊int* p = arr;printf("请输入数组元素:\n");for (i = 0; i < sz; i++){/*scanf("%d", p + i);*///p每一次移动 i 个地址scanf("%d", arr+i);//既然数组名是首元素地址,理所应当也可以这样写//scanf("%d", &arr[0] + i);//那第一个地址也可以}//输出printf("输出:\n");for (i = 0; i < sz; i++){printf("%d ", *(p + i));//解引找到指针变量的空间的值进行访问}return 0;
}

每个都进行验证一下:

  1. 数组名访问地址

在这里插入图片描述

  1. 数组首元素地址访问

在这里插入图片描述
3. 使用指针访问数组
在这里插入图片描述

  • ⚠️ 这段代码弄清楚后,我们再试一下,如果我们再分析一下,数组名arr是数组首元素的地址,可以赋值给p,其实数组名arrp在这里是等价的。那我们可以使用arr[i]可以访问数组的元素,p[i]是否也可以访问数组呢?测试一下!

在这里插入图片描述

#include <stdio.h>
int main()
{int arr[10] = { 0 };//输⼊int i = 0;//整个数组大小40/单个数组字节4=10int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素个数//输⼊int* p = arr;printf("请输入数组元素:\n");for (i = 0; i < sz; i++){/*scanf("%d", p + i);*///p每一次移动 i 个地址scanf("%d", arr+i);//既然数组名是首元素地址,理所应当也可以这样写//scanf("%d", &arr[0] + i);//那第一个地址也可以}//输出printf("输出:\n");for (i = 0; i < sz; i++){printf("%d ", i[arr]);//这样子是否也可以呢?printf("%d ", i[p]);//}return 0;
}

在这里插入图片描述
哎,为什么i[arr]可以打印,其实i[p]也可以打印

  1. 在C语言中,数组名和指针的运算符[]是可以互换使用的。这是因为在C语言中,a[b]*(a + b)是等价的,即数组下标运算和指针运算是等效的。当然,如果你不太明白,可以尝试使用交换律来理解
 *(i+arr)-->*(arr+i)-->arr[i]arr[i] == *(arr+i)*(i+arr) == i[arr]p[i] == *(p+i)
  1. 因此,当你使用i[arr]时,它实际上等同于arr[i]。这是因为arr本身就代表数组的首元素地址,而i[arr]会被解释为*(arr + i),即数组首元素地址加上偏移量i,得到第i个元素的地址。同样,i[p]也等同于p[i],因为指针p也可以进行类似的偏移量运算。
  2. 虽然i[arr]i[p]在语法上是合法的,但通常不推荐这样的写法,因为它会增加代码的可读性和理解难度。更好的做法是直接使用arr[i]p[i],这样可以更清晰地表达代码的意图。

➡️、⼀维数组传参的本质

首先,让我们从一个问题开始。我们之前一直在函数外部计算数组的元素个数,但是我们能否将函数传递给另一个函数,在函数内部计算数组的元素个数呢?

void test(int arr[])//int* arr
{					//4/4int sz = sizeof(arr) / sizeof(arr[0]);printf("%d\n", sz);//
}int main()
{//数组传参的时候,传递的是并非是数组//传递的是数组首元素的地址int arr[12] = { 1,2,3,4,5,6,7,8,9,10,11,12 };int sz = sizeof(arr) / sizeof(arr[0]);test(arr);//这里的数组名就是数组首元素的地址return 0;
}
  1. 环境下debug,x86环境下,结果为1.

在这里插入图片描述

  1. 环境下debug,x64环境下,结果为2.

在这里插入图片描述
分析:

  • 当数组作为函数参数进行传递时,实际上传递的是数组的首元素地址,而不是整个数组。因此,在函数内部,无法通过sizeof操作符来获取数组的大小,因为此时的arr已经退化为指针

  • 在代码中,test函数的参数arr实际上是一个指针,因此在函数内部使用sizeof(arr)并不能得到数组的大小,而是得到指针的大小。因此,在32位环境下(x86),指针的大小为4字节,所以sizeof(arr) / sizeof(arr[0])的结果为1。(同理64位,指针大小字节为8字节)
    在这里插入图片描述

数组名是数组首元素的地址;因此在数组传参时,传递的是数组名,也就是说本质上数组传参本质上传递的是数组首元素的地址。

⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。
在这里插入图片描述

➡️、⼆级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪⾥?

在C语言中,二级指针是指一个指针变量,它存储的是另一个指针变量的地址。换句话说,它指向一个指针变量,而这个指针变量又指向某个数据的地址。在C语言中,我们通常使用二级指针来处理动态内存分配和多级数据结构。

下面是一个简单的示例,演示了如何声明和使用二级指针:

#include <stdio.h>int main() {int num = 10;int *ptr1 = &num; // 一级指针,指向int类型的数据int **ptr2 = &ptr1; // 二级指针,指向int*类型的数据// 通过二级指针访问num的值printf("Value of num: %d\n", **ptr2);return 0;
}

在这个示例中,ptr1是一个一级指针,它指向一个整数类型的数据numptr2是一个二级指针,它指向一个一级指针ptr1。通过**ptr2可以访问num的值。

二级指针在C语言中通常用于动态内存分配,例如在使用malloc函数分配内存时,可以返回一个指向指针的指针,以便在程序中对内存进行操作。此外,在处理多级数据结构(如多级指针数组或多级链表)时,二级指针也非常有用。
举个简单的例子:

int main()
{int a = 10;int* p = &a;//取出a的地址//p是指针变量,是一级指针int * * pp = &p;//pp是二级指针return 0;
}

在这里插入图片描述

对于⼆级指针的运算有:
• *ppa 通过对ppa中的地址进⾏解引⽤,这样找到的是 pa , *ppa 其实访问的就是 pa .

int b = 20;
*ppa = &b;//等价于 pa = &b;

• **ppa 先通过 *ppa 找到 pa ,然后对 pa 进⾏解引⽤操作: *pa ,那找到的是 a .

**ppa = 88;
//等价于*pa = 88;
//等价于a = 88;

在这里插入图片描述

🔼、指针数组

指针数组是指针还是数组?
我们类⽐⼀下,整型数组,是存放整型的数组,字符数组是存放字符的数组。
那指针数组呢?是存放指针的数组。

在C语言中,指针数组是一个数组,其中的每个元素都是一个指针。这意味着每个数组元素都存储着另一个变量的地址,而这个变量可以是任何类型的数据,包括整数、浮点数、字符,甚至是其他指针。

下面是一个简单的示例,演示了如何声明和使用指针数组:

#include <stdio.h>int main() 
{int num1 = 10, num2 = 20, num3 = 30;int *ptrArr[3]; // 声明一个包含3个指针的数组ptrArr[0] = &num1; // 将num1的地址存储在数组的第一个元素中ptrArr[1] = &num2; // 将num2的地址存储在数组的第二个元素中ptrArr[2] = &num3; // 将num3的地址存储在数组的第三个元素中// 通过指针数组访问num1、num2和num3的值printf("Value of num1: %d\n", *ptrArr[0]);printf("Value of num2: %d\n", *ptrArr[1]);printf("Value of num3: %d\n", *ptrArr[2]);return 0;
}

在这个示例中,ptrArr是一个包含3个指针的数组。每个数组元素都存储着一个整数类型变量的地址。通过ptrArr[i]可以访问第i个元素所指向的变量。

在这里插入图片描述

int main()
{
//char ch = ‘w’;
//char* pc = &ch;//pc就是字符指针

const char* p = "abcdef";//不是把字符串abcdef\0存放在p中,而是把第一个字符的地址存放在p中
//printf("%c\n", *p);//
//1. 你可以把字符串想象为一个字符数组,但是这个数组是不能修改的
//2. 当常量字符串出现在表达式中的时候,他的值是第一个字符的地址printf("%c\n", "abcdef"[3]);
printf("%c\n", p[3]);
//p[3] = 'q';//errreturn 0;

}

在C语言中,字符指针数组是一个数组,其中的每个元素都是一个指向字符的指针。这种数组通常用于存储字符串数组,其中每个元素指向一个以null结尾的字符数组。

下面是一个简单的示例,演示了如何声明和使用字符指针数组:

#include <stdio.h>int main() {char *strArr[3]; // 声明一个包含3个字符指针的数组strArr[0] = "Hello"; // 将指向字符串"Hello"的指针存储在数组的第一个元素中strArr[1] = "World"; // 将指向字符串"World"的指针存储在数组的第二个元素中strArr[2] = "C";     // 将指向字符串"C"的指针存储在数组的第三个元素中// 通过字符指针数组访问存储的字符串printf("String 1: %s\n", strArr[0]);printf("String 2: %s\n", strArr[1]);printf("String 3: %s\n", strArr[2]);return 0;
}

在这个示例中,strArr是一个包含3个字符指针的数组。每个数组元素都存储着一个指向以null结尾的字符数组的指针。通过strArr[i]可以访问第i个元素所指向的字符串。

但是也有例外
比如这个代码:
int main()
{

//char ch = ‘w’;
//char* pc = &ch;//pc就是字符指针

const char* p = "abcdef";//不是把字符串abcdef\0存放在p中,而是把第一个字符的地址存放在p中
//printf("%c\n", *p);//
//1. 你可以把字符串想象为一个字符数组,但是这个数组是不能修改的
//2. 当常量字符串出现在表达式中的时候,他的值是第一个字符的地址printf("%c\n", "abcdef"[3]);
printf("%c\n", p[3]);
//p[3] = 'q';//errreturn 0;

}
在这里插入图片描述

如果强行修改,他就会报错:
在这里插入图片描述


🅿️总结

本小节我们的学习总结:

1️⃣. 数组名的理解:

  • 数组名实际上是指向数组第一个元素的指针。在大多数情况下,数组名可以被解释为指向数组首元素的指针常量。
  • 例如,对于int arr[5]arr可以被视为指向arr[0]的指针。

2️⃣. 使用指针访问数组:

  • 数组名可以被解释为指向数组首元素的指针,因此可以使用指针算术或指针解引用来访问数组元素。
  • 例如,*(arr + i)或者arr[i]都可以用来访问数组arr的第i个元素。

3️⃣. 一维数组传参的本质:

  • 在C语言中,当将数组传递给函数时,实际上传递的是数组的首元素的地址。
  • 因此,函数参数声明中的数组形参实际上被解释为指向数组首元素的指针。

4️⃣. 二级指针:

  • 二级指针是指向指针的指针。它们用于处理指针的指针,通常用于动态内存分配和多级数据结构。
  • 例如,int **ptr是一个指向指向整数的指针的指针。

5️⃣. 指针数组:

  • 指针数组是一个数组,其中的每个元素都是一个指针。这些指针可以指向不同类型的数据,包括其他指针。
  • 例如,int *ptrArr[5]是一个包含5个整数指针的数组。

感谢你的收看,如果文章有错误,可以指出,我不胜感激,让我们一起学习交流,如果文章可以给你一个帮助,可以给博主点一个小小的赞😘

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

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

相关文章

业务流程图用什么软件画?这10款流程图软件,好用到飞起!

业务流程图是什么&#xff1f; 业务流程图是一种用于表示业务过程中活动流向的图形表示方法&#xff0c;它使用标准化的图形元素&#xff08;如箭头、椭圆、方框等&#xff09;来表达一个过程中各个环节之间的关系。在这个图形表示中&#xff0c;每个元素都有特定的含义和功能…

Python实现视频字幕时间轴格式转换

自己喜欢收藏电影&#xff0c;有时网上能找到的中文字幕文件都不满足自己电影版本。在自己下载的压制版电影中已内封非中文srt字幕时&#xff0c;可以选择自己将srt的时间轴转为ass并替换ass中的时间轴。自己在频繁 复制粘贴改格式的时候想起可以用Python代码完成转换这一操作&…

2.4 矩阵的运算法则

矩阵是数字或 “元素” 的矩形阵列。当矩阵 A A A 有 m m m 行 n n n 列&#xff0c;则是一个 m n m\times n mn 的矩阵。如果矩阵的形状相同&#xff0c;则它们可以相加。矩阵也可以乘上任意常数 c c c。以下是 A B AB AB 和 2 A 2A 2A 的例子&#xff0c;它们都是 …

Postman:API测试之Postman使用完全指南

Postman是一个可扩展的API开发和测试协同平台工具&#xff0c;可以快速集成到CI/CD管道中。旨在简化测试和开发中的API工作流。 Postman工具有Chrome扩展和独立客户端&#xff0c;推荐安装独立客户端。 Postman有个workspace的概念&#xff0c;workspace分personal和team类型…

mybatis、mysql 创建时间(create_time)异常自动更新为当前时间

目录标题 一、问题二、原因三、解决 一、问题 bug: mybatis更新代码没有修改时间&#xff0c;但是时间会自动更新为当前时间。 。。。 被坑了挺久 二、原因 可能是创建表的时候&#xff0c; Navicat Premium 等可视化工具给你整活了。。。 三、解决 取消勾选。 注意&…

【超好用的工具库】hutool-all工具库的基本使用

简介&#xff08;可不看&#xff09;&#xff1a; hutool-all是一个Java工具库&#xff0c;提供了许多实用的工具类和方法&#xff0c;用于简化Java开发过程中的常见任务。它包含了各种模块&#xff0c;涵盖了字符串操作、日期时间处理、加密解密、文件操作、网络通信、图片处…

【漏洞复现】NUUO摄像头存在远程命令执行漏洞

漏洞描述 NUUO摄像头是中国台湾NUUO公司旗下的一款网络视频记录器&#xff0c;该设备存在远程命令执行漏洞&#xff0c;攻击者可利用该漏洞执行任意命令&#xff0c;进而获取服务器的权限。 免责声明 技术文章仅供参考&#xff0c;任何个人和组织使用网络应当遵守宪法法律&…

单片机FLASH下载算法的制作

环境 硬件使用正点原子STM32F407探索者V2开发板 编程环境使用MDK 下载工具使用JLINK FLASH芯片使用W25Q128 什么是下载算法 单片机FLASH的下载算法是一个FLM文件&#xff0c;FLM通过编译链接得到&#xff0c;其内部包含一系列对FLASH的操作&#xff0c;包括初始化、擦除、写…

【flink理论】动态表:关系查询处理流的思路:连续查询、状态维护;表转换为流需要编码编码

文章目录 一. 使用关系查询处理流的讨论二. 动态表 & 连续查询(Continuous Query)三. 在流上定义表1. 连续查询2. 查询限制2.1. 维护状态2.2. 计算更新 四. 表到流的转换1. Append-only 流2. Retract 流3. Upsert 流 本文主要讨论了&#xff1a; 讨论通过关系查询处理无界流…

Window MongoDB安装

三种NOSQL的一种,Redis MongoDB ES 应用场景: 1.社交场景:使用Mongodb存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人,地点等功能 2.游戏场景:使用Mongodb存储游戏用户信息,用户的装备,积分等直接以内嵌文档的形式存储,方便查询,高效率存储和访问…

一阶低通滤波器(一阶巴特沃斯滤波器)

连续传递函数G(s) 离散传递函数G(z) 转换为差分方程形式 一阶巴特沃斯滤波器Filter Designer参数设计&#xff1a;参考之前的博客Matlab的Filter Designer工具设计二阶低通滤波器 设计采样频率100Hz&#xff0c;截止频率20Hz。 注意&#xff1a;设计参数使用在离散系统中&…

Python使用Mechanize库完成自动化爬虫程序

Mechanize是一个Python第三方库&#xff0c;它可以模拟浏览器的行为&#xff0c;实现自动化的网页访问、表单填写、提交等操作。下面是一个使用Mechanize库编写的爬虫的例子&#xff0c;它可以爬取百度搜索结果页面的标题和链接&#xff1a; import mechanize from bs4 import …

短期经济波动:均衡国民收入决定理论(三)

短期经济波动&#xff1a;国民收入决定理论(三) 文章目录 短期经济波动&#xff1a;国民收入决定理论(三)[toc]1 总需求曲线及其变动1.1 总需求曲线含义1.2 总需求曲线推导1.2.1 代数推导1.2.2 几何推导 1.3 AD曲线及其变动1.3.1 扩张性财政政策1.3.2 扩张性货币政策 2 总供给曲…

【星海出品】云存储 ceph

https://ceph.com/en/ ceph组件介绍 Monitor 一个Ceph集群需要多个Monitor组成的小集群&#xff0c;它们通过Paxos同步数据&#xff0c;用来保存OSD的元数据。 OSD OSD全称Object Storage Device&#xff0c;也就是负责响应客户端请求返回具体数据的进程。一个Ceph集群一般都有…

elasticsearch+canal增量、全量同步

目录 一、搭建环境&#xff1a; 1.1 下载软件上传到linux目录/data/soft下 1.2 把所有软件解压到/data/es-cluster 二、单节点&#xff08;多节点同理&#xff09;集群部署elasticsearch 2.1 创建es用户 2.2 准备节点通讯证书 2.3 配置elasticsearch&#xff0c;编辑/d…

C语言指针详解(1)(能看懂字就能明白系列)文章超长,慢慢品尝

目录 1、内存和地址 2、指针简介 与指针相关的运算符&#xff1a; 取地址操作符&#xff08;&&#xff09; 解引用操作符&#xff08;间接操作符&#xff09;&#xff08;*&#xff09; ​编辑 指针变量的声明 指针变量类型的意义 指针的基本操作 1、指针与整数相加…

leetcode栈和队列三剑客

用队列实现栈 队列是先进先出的&#xff0c;而栈是只能在栈顶进行出栈和入栈&#xff0c;那我们这道题要用队列来实现栈的话&#xff0c;这里给的思路是两个队列&#xff0c;因为两个队列的话就可以相互导数据&#xff0c;比如我们来实现这个题目的push函数&#xff0c;我们的栈…

PostgreSQL技术大讲堂 - 第34讲:调优工具pgBagder部署

PostgreSQL从小白到专家&#xff0c;是从入门逐渐能力提升的一个系列教程&#xff0c;内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容&#xff0c;希望对热爱PG、学习PG的同学们有帮助&#xff0c;欢迎持续关注CUUG PG技术大讲堂。 第34讲&#…

Niushop单商户及多商户v5商城系统第三方商业插件cps联盟视频购物及多包装库存转换的安装

一、后端安装 把video文件夹直接上传到addon目录下即可登录后台&#xff0c;设置->系统维护->插件管理->未安装插件&#xff0c;找到插件直接安装即可 3.在营销->营销中心->营销活动&#xff0c;找到视频列表这个插件&#xff0c;点击进去配置视频即可 4.装…

Vue h5页面手指滑动图片

场景&#xff1a; 四张图&#xff0c;要求随着手指滑动而滑动 代码&#xff1a; imgs是父盒子 poster-item是每个图片 .imgs {white-space: nowrap;overflow: hidden;overflow-x: auto;margin-bottom: 17px;.poster-item {display: inline-block;vertical-align: middle;wid…