Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >指向2D字符数组的指针与指向2D int数组的指针之间有什么区别?

指向2D字符数组的指针与指向2D int数组的指针之间有什么区别?
EN

Stack Overflow用户
提问于 2016-07-27 22:15:36
回答 2查看 6.1K关注 0票数 4
代码语言:javascript
运行
AI代码解释
复制
    #include <stdio.h>

    int main()
    {
        char str[3][15] = {"Pointer to","char","program"};
        char (*pt)[15] = str; // statement A
        char *p = (char *)str; // statement B
        printf("%s\n",p[3]); // statement C  - Seg Fault in this line
        printf("%s\n",p); // working properly displaying "Pointer to"
        printf("%s\n",p+1); // here it is pointing to second element of first array so displaying "ointer to"
        printf("%s\n",pt+1); // printing properly "char" as expected
        int num[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
        int (*nm)[3] = num[1];
        int *n = num;
        printf("n - %d\n",n[10]); // statement D
        printf("nm - %d\n",nm[0][0]);
        return 0;
    }

我的问题:

  1. 请帮助我清楚地了解字符数组和int数组情况下的数据存储机制。
  2. 在上面的程序中,我的理解是,当指向char数组的指针指向语句A中所示的二维字符数组时,它正在正确地显示,但是当它被普通的char指针指向并试图在语句C中打印该字符时,它将得到SegFault,而应该打印‘n’(第一个数组中的第三个数字字符“指针到”),这样会产生混淆,为什么在int数组中,我在语句D中得到了适当的元素n= 11,而在这种情况下(语句C),它没有正确的打印。
  3. 如果是char数组,数据将如何存储,是否以如下形式存储?
代码语言:javascript
运行
AI代码解释
复制
char str[3][15] = {{'P','o','i','n','t','e','r',' ','t','o'},
                   {'c','h','a','r'},
                   {'p','r','o','g','r','a','m'}};

如果它是这样存储的,那么它应该像语句D中显示的整数指针数组一样工作,请帮助我指导这个问题,并澄清我在char和int数组存储情况下的问题。

EN

回答 2

Stack Overflow用户

发布于 2016-07-28 00:40:20

让我们一步一步地查看您的代码。

代码语言:javascript
运行
AI代码解释
复制
char str[3][15] = {"Pointer to","char","program"};

在这里,您已经创建了一个由15个char的数组组成的数组。您正在用字符串文字初始化每个char数组。如果文字比数组短--最后一个元素填充了零,那么它与:

代码语言:javascript
运行
AI代码解释
复制
char str[3][15] = {
    {'P', 'o', 'i', 'n', 't', 'e', 'r', ' ', 't', 'o', 0, 0, 0, 0, 0},
    {'c', 'h', 'a', 'r', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {'p', 'r', 'o', 'g', 'r', 'a', 'm', 0, 0, 0, 0, 0, 0, 0, 0}
};

然后

代码语言:javascript
运行
AI代码解释
复制
char (*pt)[15] = str; // statement A

在这里,您创建pt作为指向15char的数组的指针,您正在用str[0]的地址初始化它,即ptstr指向第一个char[15]数组。

下一首

代码语言:javascript
运行
AI代码解释
复制
char *p = (char *)str; // statement B

这是不好的。据我所见-您正在尝试使p指向str占用的内存的第一个char。表达式str的类型为char (*)[15],即它是指向字符数组的指针,而不是指向char的指针(正因为如此,您被迫使用强制转换),而且不管str实际上指向存储'P'的单元格--您应该以更类型安全的方式指向它:

代码语言:javascript
运行
AI代码解释
复制
char *p = &str[0][0]; // the same as "p = str[0];"

str[0]指的是str的第一个元素,即str[0]类型是一个15char的数组,然后您只需引用第一个char并获取它的地址- &(str[0])[0],或者简单地使用带有“str[0]”类型的表达式来键入“指向第一个数组元素的指针”这一事实,这就是str[0]也能工作的原因。

我们走吧

代码语言:javascript
运行
AI代码解释
复制
printf("%s\n",p[3]); // statement C  - Seg Fault in this line

这一行会导致未定义的行为,因为格式说明符要求第二个参数为const char *,但您正在传递char。如果你想打印一个字符,那么就这样做:

代码语言:javascript
运行
AI代码解释
复制
printf("%c\n", p[3]); // prints "n"

然后

代码语言:javascript
运行
AI代码解释
复制
    printf("%s\n",p); // working properly displaying "Pointer to"
    printf("%s\n",p+1); // here it is pointing to second element of first array so displaying "ointer to"

这些操作很好,因为第二个参数的类型是正确的,而且我们知道字符串是以nul结尾的。

代码语言:javascript
运行
AI代码解释
复制
printf("%s\n",pt+1); // printing properly "char" as expected

坦率地说--这是不正确的,因为pt + 1是“指向char数组的指针”,但是您应该传递“指针到char”。它应改写为:

代码语言:javascript
运行
AI代码解释
复制
printf("%s\n",*(pt+1)); // or pt[1]

但是它似乎有效,因为不管类型不兼容,两个指针都指向相同的位置。

下一节是关于int的。

代码语言:javascript
运行
AI代码解释
复制
int num[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*nm)[3] = num[1];
int *n = num;

这里有两个错误:nm不应该使用num[1]初始化,因为它们有不兼容的类型:“指向三个int的数组”和“四个int /指向int的数组”(感谢衰减)。而且n也不能用num初始化,因为它们也有不兼容的类型。根据我对你想要什么的猜测,你应该从下一个角度看:

代码语言:javascript
运行
AI代码解释
复制
int num[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*nm)[4] = num + 1;
int *n = &num[0][0];

最后一个是:

代码语言:javascript
运行
AI代码解释
复制
printf("n - %d\n",n[10]); // statement D
printf("nm - %d\n",nm[0][0]);

解除引用是正确的,传递的参数也是正确的,但请记住,指针初始化错误。

霍普,我已经回答了你所有的问题。

票数 4
EN

Stack Overflow用户

发布于 2016-07-27 22:42:50

您的分段错误是由于您将错误的类型传递给printf。

写入p[3]时,您将延迟指向矩阵str第一行的第4行的指针。与*(p+3)相同

如果你想打印第三个字符,你应该

代码语言:javascript
运行
AI代码解释
复制
printf("%c\n",p[3]);

如果要打印第一个C-字符串(矩阵的第0行),则必须:

代码语言:javascript
运行
AI代码解释
复制
printf("%s\n",&p[3]);

因为%s想要char *

如果在命令中添加至少对于gcc的-Wall选项,编译器将向您显示一个好的、有用的警告:

代码语言:javascript
运行
AI代码解释
复制
test.c:8:9: warning: format ‘%s’ expects argument of type ‘char *, but argument 2 has type ‘int’ [-Wformat=]
         printf("%s\n",p[3]); // statement C  - Seg Fault in this line

关于问题3,您必须注意到正确的存储是:

代码语言:javascript
运行
AI代码解释
复制
char str[3][15] = {{'P','o','i','n','t','e','r',' ','t','o','\0'},
                   {'c','h','a','r','\0'},
                   {'p','r','o','g','r','a','m','\0'}};

由于C-字符串为空终止,因此,例如,字符串"Pointer to"将占用11字符。

最后一件事是关于int指针。它工作得很好,因为%d格式说明符需要一个int值,而不是地址。因此,写作:

代码语言:javascript
运行
AI代码解释
复制
printf("n - %d\n",n[10]);

完全正确,因为n[10]正在取消引用num矩阵的第11元素,即第3行的第3元素。与*(n+10)相同

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38628411

复制
相关文章
OpenAI老板推特说相声:嘲笑创投圈「募6轮资还没到A轮」
创业公司募资化缘一轮接一轮、同时迟迟不出货没进展的恶劣风气,现在已是妇孺皆知。虽然初创公司过去一般在筹集 A、B、C 等轮次之前先进行种子轮融资,但现在许多公司选择在其间进行额外的轮次。
新智元
2022/02/24
4480
OpenAI老板推特说相声:嘲笑创投圈「募6轮资还没到A轮」
MeshCloud 脉时云获 1 亿元 A+ 轮融资
2021年11月23日,出海融合云服务商MeshCloud脉时云(www.mesh.com.cn)宣布完成1亿元A+轮融资。 MeshCloud脉时云公司名为北京云联万维技术有限公司,成立于2017年,基于MeshCloud融合云SaaS平台、出海音视频/游戏/电商等行业垂直解决方案、高效的服务体系、海外公有云厂商的深度合作,以及自建海外云基础设施为中企出海提供高质量、低成本、敏捷部署的一站式产品和服务。 此轮融资由贵州省创新赋能大数据投资基金领投,老股东跟投。募集资金将投入到云架构师及产品研发团队扩充和
云头条
2022/03/18
4300
嘲笑资本退潮后的共享单车,或在嘲笑资本大潮下我们
ofo一出错,人们就发笑。或许是厌倦了共享单车造成的城市管理乱象,或许是出于对这个声称共享经济的厌倦,ofo只要出现一点负面消息便会引发人们的口诛笔伐。这正是当下的共享单车市场尴尬的地方,一旦资本输血停止,公司便会出现问题,用户便会纷纷倒戈。世态炎凉,或许只有真正参与其中的人们才会知道。回想共享单车大战刚刚兴起的时候,那种尔要战便战的豪气依然历历在目,对于共享单车也没有今天这么多的质疑声音。
孟永辉
2018/12/19
4120
嘲笑资本退潮后的共享单车,或在嘲笑资本大潮下我们
Hive补充之窗口函数
窗口函数 1、hive窗口函数语法 hive中的窗口函数over() ,over()窗口函数的语法结构
Maynor
2021/04/09
1.1K0
非公医院的“心病”与冠脉 AI 的“良药”
“医生提供的服务跟其他的服务业完全不一样,我们面对的是一个个鲜活的生命。如果我把一位患者治好了,挽回的不仅仅是一条生命,更可能是整个家庭的希望。”
AI掘金志
2019/09/26
4690
非公医院的“心病”与冠脉 AI 的“良药”
SQL之窗口函数
窗口函数,也叫OLAP函数(Online Anallytical Processing,联机分析处理),可以对数据库数据进行实时分析处理。 绝大多数情况,sql语句处理数据是行为基本单位,一行一行的对数据操作。窗口函数则是可以对行数据进行分组,将多行数据分成一组,然后进行组间操作或者组内操作。
cultureSun
2023/05/18
3850
SQL之窗口函数
WinForm之窗体应用程序
WinForm之窗体应用程序 基本简单数据库操作(增删改查) 1 using System; 2 using System.Collections.Generic; 3 using System.Windows.Forms; 4 5 namespace DataBaseOperation 6 { 7 static class Program 8 { 9 /// <summary> 10 /// 应用程序的主入口点。 11 /
用户1112962
2018/07/04
1.3K0
tkinter学习系列(二)之窗口的设置
目录 (一)窗体的最小框架 1.说明: 2.源代码: 3.实现效果: (二)窗体的基本设置 1.说明: 2.完整代码: 3.实现效果: (三)窗体的外形设置 1.说明: 2.完整代码: 3.实现效果: (四)窗体的三个方法: 1.获取屏幕的大小 2.获取窗体的大小 3.获取窗体的位置 目录: 1.窗体的最小框架 2.窗体的基本设置 3.窗体的外形设置 (一)窗体的最小框架 1.说明: 需要导入标准库: import tkinter 2.源代码: # 导入模块,并取别名 impor
py3study
2020/01/17
1.1K0
MFC学习之窗口基础
                          WinMain函数  1、句柄(HANDLE):{ 1. 定义:资源的标识 2. 句柄的作用: 操作系统通过句柄来找到对应的资源,从而对这些资源进行管理和操作。 3句柄的分类:(按资源){ 1.图标句柄(HICON) , 2.光标句柄(HCURSOR) ,             3. 窗口句柄(HWND) ,            4.应用程序实列句柄(HINSTANCE). } } 2、Windows应用程序,操作系统,计算机硬件之间的相互关系
Gxjun
2018/03/22
7380
MFC学习之窗口基础
快来,看看spring有多烂-来自jfinaL的嘲笑
脱离任何使用场景的比较,都是傻x行为。但我还是要当一回傻x,就当给新版本jfinal献礼了。
xjjdog
2019/07/10
1.6K1
快来,看看spring有多烂-来自jfinaL的嘲笑
BOM核心——window对象之窗口
浏览器对象模型BOM(Browser,Object,Model)是以window对象为基础的,这个对象代表了浏览器窗口,页面可视区域,它还被复用为Es的全局对象Global,所有的原生类型的构造函数和函数都从一开始就存在于这个对象之上。
大熊G
2022/11/14
9090
企业安全管理的“六脉神剑”
点击标题下「大数据文摘」可快捷关注 当考虑确定计算系统、数据和网络的可用性和完整性控制时,与可考虑潜在机会授权的管理员相比,普通用户拥有更少的特权。系统管理员、执行备份的操作人员、数据库管理员、维修技师甚至帮助台支持人员的运营商,都纷纷在网络中提升权限。为了确保你系统的安全性,还必须考虑可以防止管理员滥用特权的控制。用于管理日常事务以及组织内的数据访问的自动化控制不能保证自己的完整性和可用性,避免过度管理任务的控制。如果控制管理使用权限的控件也不强,那么任何其他的控件也会被削弱。下面一起来看企业安全管理的“
大数据文摘
2018/05/23
8020
5 脉神剑,杀无赦!
分享一个数据,我在 CSDN 上有 19 万多的读者关注了,这个数量应该能排到所有博主里面的 TOP 3(乐观点,自信点),就算是保守估计的话,至少应该是 TOP 10 吧!
沉默王二
2021/04/25
4190
5 脉神剑,杀无赦!
多级时间轮定时器_时间轮与哈希表定时
顾名思义,时间轮就像一个轮子,在转动的时候外界会指向轮子不同的区域,该区域就可以被使用。因此只要将不同时间的定时器按照一定的方法散列到时间轮的不同槽(即时间轮划分的区域)之中,就可以实现在运转到某个槽时,进行判断该定时器是否已经到达运行时间(需要判断是由于有的定时器并非在这一圈就需要运行,可能需要后面几圈才会运行。
全栈程序员站长
2022/11/10
1.2K0
多级时间轮定时器_时间轮与哈希表定时
Lucene 高阶查询的六脉神剑 —— QueryParser
上篇我们介绍了 Lucene 多样的查询模式,每一种都是相互独立的用来解决特定查询目标的 Query 对象。本节我们要将这些查询模式使用 QueryParser 组合起来进行合并查询 —— 用一个文本字符串表达式来表示所有的查询模式。
老钱
2019/09/17
2.6K1
Lucene 高阶查询的六脉神剑 —— QueryParser
flink时间系统系列之窗口函数中的应用分析
在flink中窗口划分可以基于时间、基于数量,我们这里所涉及到的窗口是针对时间类型窗口:processing-time window与event-time window,时间系统在时间窗口应用主要用来注册窗口触发时间点,来决定窗口什么时候开始执行窗口函数。接下来从源码的角度分析窗口是如何使用时间系统的。
Flink实战剖析
2022/04/18
6810
flink时间系统系列之窗口函数中的应用分析
秘籍:微服务设计的六脉神剑
介绍 “微服务”是一种新的软件开发模式,它来源于提高软件开发和管理效率的一系列工程实践。敏捷方法、DevOps文化、PaaS、应用容器、CI/CD文化和技术的广泛采用,使得构建真正的模块化、大规模服务系统成为可能。 什么是微服务? 微服务是一种架构方法,强调将应用拆分成由跨职能团队管理的单目标、松散耦合的多个服务,以满足如今数字时代对软件系统交付和维护速率与质量的要求。 微服务与编程语言、平台、操作系统无关。它将庞大的应用拆分成更小更简单的应用,这些庞大的应用一般都是打成一个软件包。每个应用只需要做好一件
DevOps时代
2018/02/02
8710
秘籍:微服务设计的六脉神剑
打通Python学习的任督二脉
Python的基础知识已经在上周全部更新完成,今天对之前的文章做一个汇总方便大家的查看【多图!加了好多思维导图】同时对有遗漏的知识点也已经做了补充,当然这一部分直接将自己的学习笔记给贴上了,文末加了四篇实战练习和一篇BAT面试题分享。今天更新的次条对LeetCode的1--20题做了汇总,发起了大家一起刷题的活动,后续刷题将不按顺序而是按照具体的知识点。
PM小王
2019/07/02
6850
打通Python学习的任督二脉
【干货】教你打通Git的任督二脉
分布式版本控制系统( Distributed Version Control System,简称 DVCS )。
狼王编程
2021/06/01
4310
【干货】教你打通Git的任督二脉
点击加载更多

相似问题

反应钩形与脉轮

14

如何转换/动画与脉轮-UI?

23

脉轮UI图标

144

脉轮UI,如何使组件与左边对齐?

37

脉轮用户界面图标作为变量

15
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档