在C中初始化字符串指针有什么意义

在C中初始化字符串指针有什么意义,c,string,pointers,initialization,C,String,Pointers,Initialization,这是我的问题。在C中,我看到如下代码: char *s = "this is a string"; 但是,s实际上并没有指向一个实际的内存,对吗? 如果尝试使用s修改字符串,则结果是未定义的 我的问题是,将字符串指定给指针有什么意义 那么 谢谢 char *s = "this is a string"; 这是一个字符串文本。因此,字符串存储在只读位置,该内存地址返回到s。因此,当您尝试写入只读位置时,您会看到未定义的行为,并且可能会看到崩溃 问题1:s实际上并没有指向实际内存,对吗 您错了s

这是我的问题。在C中,我看到如下代码:

char *s = "this is a string";
但是,s实际上并没有指向一个实际的内存,对吗? 如果尝试使用s修改字符串,则结果是未定义的

我的问题是,将字符串指定给指针有什么意义 那么

谢谢

char *s = "this is a string";
这是一个字符串文本。因此,字符串存储在只读位置,该内存地址返回到
s
。因此,当您尝试写入只读位置时,您会看到未定义的行为,并且可能会看到崩溃

问题1:s实际上并没有指向实际内存,对吗

您错了
s
正在保存存储此字符串的内存地址

问题2:那么,将字符串指定给指针有什么意义呢

s实际上并没有指向实际内存,对吗

从技术上讲,它指向只读存储器。但是编译器可以做它想做的任何事情,只要遵循“如果”规则。例如,如果从不使用
s
,则可以将其从代码中完全删除

由于它是只读的,因此任何修改它的尝试都是未定义的行为。您可以并且应该使用
const
指示指针的目标是不可变的:

const char* s = "Hello const";
我的问题是,给指针分配一个字符串有什么意义

就像将常数存储到任何其他类型一样。您并不总是需要修改字符串。但是,您可能希望将指向字符串的指针传递给不关心它们是指向文字还是指向您拥有的数组的函数:

void foo(const char* str) { 
  // I won't modify the target of str. I don't care who owns it.
  printf("foo: %s", str);
}

void bar(const char* str) {}

char* a = "Hello, this is a literal";
char b[] = "Hello, this is a char array and I own it";

foo(a);
bar(a);
foo(b);
请看以下代码:

char *s = "this is a string";
printf("%s",s);
如您所见,我使用了“将
字符串
分配给
指针
”。是否清楚?
要知道
s
指向的是实际内存,但它是只读的。

如果这样赋值

char *s = "this is a string";
它将存储在只读存储器中。这就是未定义行为的原因。在本例中,s将指向只读区域中的某个内存。 如果你像这样打印地址,你可以得到一些内存地址

 printf("%p",s);

因此,在本例中,如果分配内存并将值复制到该指针,则可以访问类似指针的数组。

执行
char*s=“这是一个字符串”,内存将自动分配并填充此字符串,指向该内存的指针将返回给调用者(您)。因此,您不需要显式地将字符串放入某些内存中

s实际上并没有指向实际内存,对吗

错误的是,它确实指向一个实际内存,它的分配实现对您是隐藏的。这个内存位于内存的只读扇区中,所以它不能被更改/修改。因此,关键字
const
,因为这些文字称为常量文字

如果尝试使用s修改字符串,则结果未定义

因为,您正试图修改标记为
只读的内存

那么,将字符串指定给指针有什么意义呢

实现这一目标的另一个途径是

char temp[260] = {0} ;
char *s ;
strcpy (temp, "this is a string");
s = temp ;
这里的内存
temp
由您管理

char *s = "this is a string" ;

这里,内存由操作系统管理。

使用
const char*
而不是
char[]
将字符串存储在
只读
内存空间中。这允许编译器消除字符串重复

尝试运行此程序:

#include <stdio.h>

int main()
{
    const char *s1 = "This is a string";
    const char *s2 = "This is a string";
    if (s1 == s2) {
        puts("s1 == s2");
    } else {
        puts("s1 != s2");
    }
}
这将输出
s1!=s2
这意味着编译器必须复制字符串内存

通过使用
char*
而不是
char[]
编译器可以进行这些优化,从而减小可执行文件的大小


还要注意的是,您不应该使用
char*s=“string”
。您应该改用
const char*s=“string”
char*s
已弃用且不安全。通过使用
constchar*
可以避免将字符串传递给试图修改字符串的函数的错误

其他人都告诉过您,如果您试图修改字符串,则可能会出现只读内存和未定义的行为,因此我将跳过这一部分并回答以下问题:“那么将字符串指定给指针有什么意义?”

原因有两个

1) 为了简单起见。将字符串指定给指针后,可以将该字符串称为
s
,而不是重复键入“this is a string”。当然,这假设您打算在多个函数调用中使用字符串

2) 因为您可能希望更改指针引用的字符串。例如,在下面的代码中,
s
被初始化,假设代码将成功,如果出现故障,则随后会被更改。最后,打印
s
指向的字符串

const char *s = "Yay, it worked!!!";

if ( openTheFile() == FAILED )
    s = "Dang, couldn't open the file";

else if ( readTheFile() == FAILED )
    s = "Oops, there's nothing in the file";

printf( "%s\n", s );

请注意,
const char*
表示不能更改
s
指向的字符串。这并不意味着
s
本身不能更改。

在您的例子中,指针s只是指向携带字符串第一个文本的位置。因此,如果我们想更改字符串,它会造成混淆,因为指针s指向上一个位置。如果要使用指针更改字符串,则应注意前一个字符串的结尾(即NULL)。

这并不是在回答问题。@juanchopanza正在添加详细信息。实际上,它确实回答了OP错误理解的问题,
s
没有包含我在回答中所说的任何内容,而是“在C中初始化字符串指针有什么意义”,您所做的只是提供一个链接。@juanchopanza这样做有多种好处。在链接中有一个很好的解释,我很乐意提供,而不是在这里列出相同的内容。你的意思是为什么不使用
chars[]=“我的字符串在这里”而不是?另外,你能详细说明你所说的“s”不是指ac的意思吗
const char *s = "Yay, it worked!!!";

if ( openTheFile() == FAILED )
    s = "Dang, couldn't open the file";

else if ( readTheFile() == FAILED )
    s = "Oops, there's nothing in the file";

printf( "%s\n", s );