鱼C论坛

 找回密码
 立即注册
查看: 7479|回复: 23

一个在调试时的奇怪问题。。。

[复制链接]
发表于 2013-7-22 23:07:36 | 显示全部楼层 |阅读模式
1鱼币
先上我的源码
#include<stdio.h>
int main()
{   
        int i;
    char *country[]=
        {
          "China",
          "Japan",
          "Russia",
          "Germany",
          "Switzerland"
        };
       
        for(i=0;i<5;i++)
                printf("%s\n",country[i]);
        return 0;
}

因为以前听说用指针数组可以节约空间,所以想知道是如何存储的,可在调试过程中有这么一个问题

调试中的显示

调试中的显示
现在更迷惑了,到底是什么情况阿,还有是怎么存储的阿???

最佳答案

查看完整内容

1、是 2、country[j]保存的是第i个字符串的第j个字符,在静态存储区,按你图上,country[0][0]~[5]就是在编号1004~1009的内存单元 3、格式标记%s表示字符串输出,给出起始地址,读到'\0'为止。如果是字符,对应%c读取单字节就结束了。 4、对于你在一楼的例子,一维指针数组,字符串都是在静态存储区的,单个字符串内各字符之间一定是连续存放的;但各字符串之间未必是连续存放(未必不等于一定不)。只不过你这张图上前两个 ...
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-22 23:07:37 | 显示全部楼层

1、是
2、country[i][j]保存的是第i个字符串的第j个字符,在静态存储区,按你图上,country[0][0]~[5]就是在编号1004~1009的内存单元
3、格式标记%s表示字符串输出,给出起始地址,读到'\0'为止。如果是字符,对应%c读取单字节就结束了。
4、对于你在一楼的例子,一维指针数组,字符串都是在静态存储区的,单个字符串内各字符之间一定是连续存放的;但各字符串之间未必是连续存放(未必不等于一定不)。只不过你这张图上前两个字符串也是连续存放的。如果是二维数组,那各个字符串之间一定是连续存放的。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-22 23:08:10 | 显示全部楼层
拜托各位了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-23 09:47:03 | 显示全部楼层
这是啥调试工具?求问
另外你哪儿迷惑啊
第一个china在内存中存放不是对的么~[0][5]之后的别管就是了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-23 09:59:33 | 显示全部楼层
tsembrace 发表于 2013-7-23 09:47
这是啥调试工具?求问
另外你哪儿迷惑啊
第一个china在内存中存放不是对的么~[0][5]之后的别管就是了

为什么指针数组保存字符串可以节约空间,
而且这样定义的是一个二维数组吗,看着像一维。。。
而且以这个程序为例,country[0]保存的是 'C' 的地址,那其后的 "hina" 是如何存储的,是什么时候存储的,自动的吗,而且存储的是数据本身,还是地址,再靠地址去指向数据?
难道这就是指针的强大之处了??
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-23 10:00:11 | 显示全部楼层
tsembrace 发表于 2013-7-23 09:47
这是啥调试工具?求问
另外你哪儿迷惑啊
第一个china在内存中存放不是对的么~[0][5]之后的别管就是了

这是VC6.0++里面的一个调试功能
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-23 11:04:38 | 显示全部楼层
18740579579 发表于 2013-7-23 09:59
为什么指针数组保存字符串可以节约空间,
而且这样定义的是一个二维数组吗,看着像一维。。。
而且以这 ...

你这个就是一维的指针数组。
程序加载到内存时候,先把你字符串都放到静态存储区,再运行时候给你的country数组变量分配空间,同时给每个数组元素赋值为静态存储区中字符串首地址。
对于二维数组,比如char str[2[[4]={"ab","cdef"};
两个字符串一样在程序加载时候被放到静态存储区;程序运行到str这句定义时候为str1这个数组分配2×4个存储空间,对静态存储区的字符串内容进行复制,同时对str1的0行字符串不足的位置补‘\0’到最大列数。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-23 23:31:03 | 显示全部楼层
本帖最后由 18740579579 于 2013-7-23 23:33 编辑
tsembrace 发表于 2013-7-23 11:04
你这个就是一维的指针数组。
程序加载到内存时候,先把你字符串都放到静态存储区,再运行时候给你的coun ...


还是不清楚。。。是不是这个意思。。。这是一个一维数组,数组元素为 每个字符串的第一个字符的 地址?
那这个字符串的其余字符呢,是如何存储的,而且通过观察可以发现,是一个二维数组保存着其余字符阿,那这个二维数组是从哪里来的????

字符串除首字符其余的字符的存储

字符串除首字符其余的字符的存储
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-24 08:53:36 | 显示全部楼层
本帖最后由 Seandor 于 2013-7-24 09:05 编辑

解释楼上的问题char *country[] = {"", ""...}你这样定以后,country就是一个字符指针数组,也就是说country[0], country[1]...都是字符指针,是一个指向匿名字符串首字符的指针。比如country[0]是指向"China"中的'C', "China"后面的字符就紧跟着"C"存储啊,因为country[0]是指针,可以进行移位运算,所以country[0]+1这个地址存储'h',country[0]+2存储'i'..而country[0]+1和country[0][1]是等价的。
理解了吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-24 09:11:33 | 显示全部楼层
18740579579 发表于 2013-7-23 23:31
还是不清楚。。。是不是这个意思。。。这是一个一维数组,数组元素为 每个字符串的第一个字符的 地址? ...

“还是不清楚。。。是不是这个意思。。。这是一个一维数组,数组元素为 每个字符串的第一个字符的 地址?”
是。
“那这个字符串的其余字符呢,是如何存储的“
其他字符串依然是在静态存储区。整个字符串都在静态存储区。
“而且通过观察可以发现,是一个二维数组保存着其余字符阿,那这个二维数组是从哪里来的????”
不管是一维指针数组还是直接二维数组去定义,都可以用二维数组的下标方式去访问单个元素。
其实在6楼我觉得说得蛮清楚了,再直接给你举例吧。
char *s1[2]={"abc","aaab"};     
char s2[2][5]={"abc","aaab"};   
包含上述两句的程序在加载到内存后,先统一给“abc","aaab"两个字符串分配空间,假设两字符串首地址分别为sadd1\sadd2,空间大小分别为4、5个字节。
程序运行后,运行到s1定义时候,分别给s1[0]\s1[1]分配两处内存空间(因该数组元素为char *型,即该处内存空间大小为表示地址所需的空间),分别存储sadd1\sadd2。数组名s1表示第一处空间的地址,存放着sadd1。
运行到s2定义时候,先给s2各数组元素分配2×5=10处内存空间,大小为表示字符的单字节,同时将静态存储区内的字符(包含'\0')复制到这10处空间,而静态存储区中字符总共就9个(3+4+2个'\0'),这里的处理方式是将s2的0行字符串后面补足'\0'。数组名s2即表示10处内存空间的首地址。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-24 10:28:31 | 显示全部楼层
我看了半天似乎懂楼主的问题了。首先你是用“”这个引号将字符串括起来的,是引号说明就是字符串,所以编译器就当时字符串来处理,将一整个字符串存进了内存,你用的是一个1维的指针数组,每个指针指向字符串的首字母,这就相当于一个2维的字符数组了撒。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-24 11:34:29 | 显示全部楼层
Seandor 发表于 2013-7-24 08:53
解释楼上的问题char *country[] = {"", ""...}你这样定以后,country就是一个字符指针数组,也就是说countr ...

这是我想的,对吗

这是我想的,对吗
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-24 11:36:26 | 显示全部楼层
tsembrace 发表于 2013-7-24 09:11
“还是不清楚。。。是不是这个意思。。。这是一个一维数组,数组元素为 每个字符串的第一个字符的 地址? ...

非常感谢非常感谢!!

可我还是比较愚笨。。

可我还是比较愚笨。。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-24 11:37:17 | 显示全部楼层
wcc1314 发表于 2013-7-24 10:28
我看了半天似乎懂楼主的问题了。首先你是用“”这个引号将字符串括起来的,是引号说明就是字符串,所以编译 ...

我的疑惑。。

我的疑惑。。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-24 16:34:18 | 显示全部楼层
楼上正解,我没什么好说的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-24 17:47:49 | 显示全部楼层
额、你前面定义i变量为撒没用啊、还有楼下讨论好高深啊、表示不懂
  1. #include<stdio.h>
  2. int main()
  3. {   
  4.         int i;
  5.     char *country[]=
  6.         {
  7.           "China",
  8.           "Japan",
  9.           "Russia",
  10.           "Germany",
  11.           "Switzerland"
  12.         };
  13.         
  14.         for(i=0;i<5;i++)
  15.                 printf("%s\n",country[i]);                              //country后把i括上就行了
  16.                 getch();
  17.                 return 0;
  18. }
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-24 19:31:48 | 显示全部楼层
loner 发表于 2013-7-24 17:47
额、你前面定义i变量为撒没用啊、还有楼下讨论好高深啊、表示不懂

那个 i 忽略了吧,,。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-24 19:42:14 | 显示全部楼层
loner 发表于 2013-7-24 17:47
额、你前面定义i变量为撒没用啊、还有楼下讨论好高深啊、表示不懂

那个getch()什么用的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-24 19:42:50 | 显示全部楼层
Seandor 发表于 2013-7-24 16:34
楼上正解,我没什么好说的

感谢你啊{:1_1:}:D
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-24 21:46:58 | 显示全部楼层
18740579579 发表于 2013-7-24 19:42
那个getch()什么用的

停顿一下、能看清显示内容
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-18 16:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表