notfornothing 发表于 2019-6-12 21:21:44

C语言 指针数组的问题

本帖最后由 notfornothing 于 2019-6-12 21:26 编辑

两个程序的区别
主要不懂在第一个程序printf 参数是*(name+i)
               第二个程序printf 参数是name+i的区别
我所理解的指针数组的赋值应该是一个意思,但是输出printf参数形式却不同

#include <stdio.h>
#include <conio.h>
main()
{
      int i;
      char *name[]={"jack",
                  "tom",
                  "lucy"};

      for (i=0;i<3;i++)
      {
                printf("%s\n",*(name+i));
      }
                getch();
}


#include <stdio.h>
#include <conio.h>
main()
{
      int i;
      char n = 'a';
      char *name={&n};
      for (i=0;i<3;i++)
      {
                printf("请输入第%d位的姓名:",i+1);
                scanf("%s",name+i);
      }
      for (i=0;i<3;i++)
      {
                printf("%s\n",name+i);
                }
               
                getch();
}

人造人 发表于 2019-6-12 21:56:16

第2个程序是哪来的?感觉最近几天看到过好多次
第2个程序是错误的,没有对指针分配存储空间
因为让scanf以%s输入到name + i,这会覆盖堆栈上面的这3个变量,变量i,变量n,变量name

newu 发表于 2019-6-12 21:58:12

https://cdn.sinaimg.cn.52ecy.cn/large/005BYqpgly1g3yppuxviyj30fh0c3jru.jpg

那么可以从这张图清晰的看到, 这三个字符串分别被当作常量,被存储在了内存中的静态区中,
name[]这个指针数组,只是存储了他们的地址而已。

个人理解指针实际就是内存地址的抽象概念。

有一种通用的方法,可以让你学的彻底一些 --> 不懂地方下断点,F5,右键查看反汇编。

人造人 发表于 2019-6-12 22:04:17

人造人 发表于 2019-6-12 21:56
第2个程序是哪来的?感觉最近几天看到过好多次
第2个程序是错误的,没有对指针分配存储空间
因为让scanf ...

好吧,在我的系统上变量i在低地址,变量name在高地址,不会导致覆盖变量i和变量n
变量name好像是会被覆盖,我再研究研究

notfornothing 发表于 2019-6-12 22:12:55

newu 发表于 2019-6-12 21:58
那么可以从这张图清晰的看到, 这三个字符串分别被当作常量,被存储在了内存中的静态区中,
name[]这 ...

好的,我不太懂汇编,我是直接接触C语言的.
你所说的存储了字符串常量的地址就是 第一个程序里 name+i 所对应的字符串常量的地址,因此*(name +i)就是取出里面的值printf输出出来.按道理来说第二个程序应该也是这样的printf的格式才能输出才对.或者是说scanf输入的值是直接是一个值?name[]里面不再是字符串常量的地址了吗?这点使我很迷惑

人造人 发表于 2019-6-12 22:15:09

人造人 发表于 2019-6-12 22:04
好吧,在我的系统上变量i在低地址,变量name在高地址,不会导致覆盖变量i和变量n
变量name好像是会被覆 ...

在我的系统上,name变量中的内容会被覆盖
注意,是name变量的内容

这意味着,name变量是作为3 * 8 = 24 个字节的内存空间来使用的,我的系统上一个指针8个字节

第3次输入,也就是name + 2
也就是让scanf把字符串输入到name这个位置,这个位置有8个字节的空间,也就是说第3次输入只能输入7个字符,超过7个字符就覆盖到name变量后面的内容了,在我这边会报错

notfornothing 发表于 2019-6-12 22:42:59

好的谢谢,大概就是name通过scanf存储的不再是指向一个常量区字符串的地址了,而是一个3*8字节的空间.也就顺应了后面:我如果仅仅输入那么多分配给我内存空间,输出的是参数是name+i对应的值了,而不是地址.
题外话,我想问一下:学c语言的话后面再学c++和python的话.需要很深入了解汇编的知识吗?我看你和楼上都有用到反编译的东西,不然光靠我从语法上面很难理解.但是也有的人说学语言这些也没有必要学汇编知识

人造人 发表于 2019-6-12 22:50:20

notfornothing 发表于 2019-6-12 22:42
好的谢谢,大概就是name通过scanf存储的不再是指向一个常量区字符串的地址了,而是一个3*8字节的空间. ...

想要深入理解C语言,汇编语言是必须的
学C++,尤其是深入理解C++,肯定需要汇编语言
对于python,如果你不去研究python的运行原理,只是调用一些别人写的代码,那你不需要汇编语言
如果你要研究python的运行原理,你也需要汇编语言
页: [1]
查看完整版本: C语言 指针数组的问题