【发布时间】:2021-06-17 09:18:36
【问题描述】:
character(20) :: a='', b
当我定义字符串 a='' 时,a 得到一个空字符串的值。我没有初始化b,所以b没有价值。我认为内存地址已按定义分配给 a 和 b。但是,空刺和无价值有什么区别呢?
【问题讨论】:
character(20) :: a='', b
当我定义字符串 a='' 时,a 得到一个空字符串的值。我没有初始化b,所以b没有价值。我认为内存地址已按定义分配给 a 和 b。但是,空刺和无价值有什么区别呢?
【问题讨论】:
请注意 Fortran 中的意外行为,即声明中的初始化意味着 save 属性,这意味着初始化将仅在第一次调用函数/子例程时有效,以及后来写入字符串的任何内容将在以后的通话中保留在那里。将函数设为纯函数、元素函数或递归函数将导致编译错误。
一般来说,你应该在声明之后初始化!
所以一般来说,一个变量应该只声明为character(20) :: a。现在a 被分配在内存中,通常在该内存序列中写入的任何内容都将是变量包含的内容,直到您分配给它。如果您在没有先分配的情况下打印它,您将看到这些内存字节的字符串解释。
例如
program t
character (20) :: hej
print*,hej
end program
在运行几次时(在带有 gcc 的 ubuntu 中)给出这些随机的东西:
�Ʋ
86+
^�K
VBd�
&��A
【讨论】:
在计算语言中,尤其是在内存方面,空或无值的概念没有任何意义,除非您定义了空的含义。正如我的编程老师曾经说过的那样,“在编程中,任何没有计划的事情都一定是有计划的”;这意味着您想要在变量中使用任何值,请确保您自己分配它,否则,它将为您分配给编译器、操作系统或其他正在运行的程序。他们放在那里的东西可能不是你想要的。
正如弗拉基米尔在他的回答中所说,如果你不定义字符串的值,它的值仍然是未定义的。这里的 undefined 仅仅意味着你对该值所做的任何事情都是不可预测的。换句话说,您应该对该变量执行的第一个操作是为其分配一个值。
字符串变量在编程中的特点是可以分配比实际使用更多的内存空间。您可以将其定义为character(20) :: a,为20个字符预留内存空间,然后使用少于20个字符;例如,通过分配单个字符a = '@',这就是用尾随空格填充的地方。在这种情况下,fortran 用空格 ' ' 字符填充剩余的 19 个字符。其他编程语言使用其他机制;例如,在 C/C++ 中,建议使用空字符来标记内存空间有用部分的结束;在 Pascal/Delphi 中,字符串变量携带字符串中实际字符的数量;等等
有了这个解释和你的声明character(20) :: a='', b; a 和 b 之间的区别在于,a 上的任何操作都是可预测的,而 b 上唯一可预测的操作是不解释其当前值的操作,例如分配值、查询长度等。 a 和 b 是分配的内存空间,a 显式填充尾随空格,而 b 中的值取决于编译器;它可以是默认值(尾随空格),也可以是任何值。
重要的是要记住乔纳森关于已保存属性的评论。因此,如果变量a 是在函数或子例程中定义的,则在声明处分配的值'' 仅在第一次调用时才得到保证。在任何其他调用中,a 将使用上一次调用设置的最后一个值。
【讨论】:
如果你没有定义字符串的值,它的值仍然是未定义的。您不能访问该值,也不能打印它。该内存地址实际发生的情况取决于实现的内部结构和字符串的位置。它可能是零个字符,也可能是一些完全的垃圾。
如果您将值定义为空 "",则字符串将用尾随空格填充,因为 Fortran 在您分配给字符串时会添加尾随空格。
【讨论】: