微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C中的字符串表是什么? const char* p = "one two three";const char a[] = "one two three";

如何解决C中的字符串表是什么? const char* p = "one two three";const char a[] = "one two three";

char *p = "one two three";

显然,这段代码中的字符串常量存储在字符串表中。什么是“字符串表”?是在中还是在中?

信息背景:我在第 6 章(使用指针)的 Teach Yourself C,by Hilbert Schildt 中找到了此信息。

如您所知,C 允许在程序中使用双引号括起来的字符串常量。当编译器遇到这样的字符串时,它会将它存储在程序的字符串表中并生成一个指向该字符串的指针。出于这个原因,下面的程序是正确的并打印 - 一二三。

#include<stdio.h>
int main(void){
  char*p = "one two three";
  printf(p);
  return 0;
}

解决方法

引用段落的意思是程序的一个单独部分。这些字符串常量既不在堆栈中也不在堆中。

考虑一下程序可能用来存储内容的这些类型的节(括号中以可执行文件格式定义的节的通用名称):

  • 要执行的机器码 (.text);
  • 静态只读值,例如 static const 变量 (.rodata);
  • 具有非零初始值的静态读写变量 (.data);
  • 具有零初始值 (.bss) 的静态读写变量;
  • 保存返回地址、函数参数、局部变量等的堆栈;有时这些是分开的;
  • 堆,如果有的话。

字符串常量通常属于“静态只读值”类别。一些编译器系统将它们与非字符串值分开。

任何编译器系统都可能有或没有这些部分,但它们很常见。

无论如何,从这个实现细节中抽象出来。只有当您需要深入了解时,它才会对您有所帮助,并且您需要了解您的特定编译器系统是如何工作的。

在抽象层面上,我们可以区分两种情况:

const char* p = "one two three";

字符串常量存储在某处,其地址分配给p。如果你用另一个值覆盖这个变量,你将丢失地址。

变量 p 需要额外的空间。这是在哪里,取决于变量。

const char a[] = "one two three";

字符串常量也存储在某处。数组在这个地方分配。只要 a 可见,您就可以访问其字符。

最后一点:字符串常量的字符是只读的。始终使用 const char 声明您各自的变量。

,

这里有两种可能的答案:

  1. 语言要求什么
  2. 通常是如何实现的

@thebusybee's answer 重点讲第二点,我重点讲第一点。

从语言的角度来看,栈和堆不存在:它们只是实现细节,一些旧的实现使用了多个堆(本地堆#全局堆)。该语言仅定义持续时间:

  • 静态持续时间:生命周期就是程序的生命周期
  • 动态持续时间:生命周期在分配后以 malloc 开始,以 free 结束
  • 自动:生命周期从声明变量的块的开头开始,到块的结尾结束。

一个字串(用双引号括起来)是一个常量。这意味着尝试修改它会调用未定义行为,并且常量生命周期是程序的持续时间。如果您多次使用同一个字串,则不确定它们是否具有相同的地址:

const char *p = "abc";
...
const char *q = "abc"; // p == q may be true or false

注意,字符串也可用于初始化数组:

char s[] = "abc";    // array initialization

这里的 s 是一个真正的数组(并且可以修改,因为它没有声明为 const),并且根据它的声明方式,它可以具有自动或静态持续时间。字符串litteral 是否存在本身(独立于数组)又是一个实现细节。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。