1. 主页
  2. 文档
  3. C语言教程
  4. C语言数组和字符串
  5. C中字符串的存储

C中字符串的存储

在 C 中,可以使用字符指针或字符数组来引用字符串。 
字符串作为字符数组  

char str[4] = "GfG"; /*One extra for string terminator*/
/* OR */
char str[4] = {‘G’, ‘f’, ‘G’, '\0'}; /* '\0' is string terminator */

当字符串被声明为字符数组时,它们的存储方式与 C 中其他类型的数组一样。例如,如果 str[] 是自动变量,则字符串存储在堆栈段中,如果是全局变量或静态变量,则存储在数据段中, 等等。

使用字符指针字符串
使用字符指针字符串可以存储在两个方面:

1)共享段中的只读字符串。 
当字符串值直接分配给指针时,在大多数编译器中,它存储在函数之间共享的只读块中(通常在数据段中)。 

char *str = "GfG"; 

在上述行中,“GfG”存储在共享只读位置,但指针 str 存储在读写存储器中。您可以将 str 更改为指向其他内容,但目前无法更改 str 的值。所以这种字符串应该只在我们不想在程序后期修改字符串时使用。

2)在堆段中动态分配。 

字符串像 C 中其他动态分配的东西一样存储,并且可以在函数之间共享。 

char *str;
int size = 4; /*one extra for ‘\0’*/
str = (char *)malloc(sizeof(char)*size);
*(str+0) = 'G'; 
*(str+1) = 'f'; 
*(str+2) = 'G'; 
*(str+3) = '\0'; 

让我们看一些例子来更好地理解上述存储字符串的方法。

示例 1(尝试修改字符串) 
下面的程序可能会崩溃(给出分段错误错误),因为 *(str+1) = ‘n’ 行尝试写入只读内存。 

int main()
{
char *str; 
str = "GfG"; /* Stored in read only part of data segment */
*(str+1) = 'n'; /* Problem: trying to modify read only memory */
getchar();
return 0;
}

下面的程序运行良好,因为 str[] 存储在可写堆栈段中。 

int main()
{
char str[] = "GfG"; /* Stored in stack segment like other auto variables */
*(str+1) = 'n'; /* No problem: String is now GnG */
getchar();
return 0;
}

下面的程序也可以正常工作,因为 str 处的数据存储在可写堆段中。 

int main()
{
int size = 4;

/* Stored in heap segment like other dynamically allocated things */
char *str = (char *)malloc(sizeof(char)*size);
*(str+0) = 'G'; 
*(str+1) = 'f'; 
*(str+2) = 'G'; 
*(str+3) = '\0'; 
*(str+1) = 'n'; /* No problem: String is now GnG */
getchar();
return 0;
} 

示例 2(尝试从函数返回字符串) 
下面的程序工作得非常好,因为字符串存储在共享段中,即使在 getString() 返回后,存储的数据仍保留在那里 

char *getString()
{
char *str = "GfG"; /* Stored in read only part of shared segment */

/* No problem: remains at address str after getString() returns*/
return str; 
} 

int main()
{
printf("%s", getString()); 
getchar();
return 0;
}

下面的程序也可以很好地工作,因为字符串存储在堆段中,并且即使在 getString() 返回后,存储在堆段中的数据仍然存在  


char *getString()
{
int size = 4;
char *str = (char *)malloc(sizeof(char)*size); /*Stored in heap segment*/
*(str+0) = 'G'; 
*(str+1) = 'f'; 
*(str+2) = 'G';
*(str+3) = '\0'; 

/* No problem: string remains at str after getString() returns */ 
return str; 
} 
int main()
{
printf("%s", getString()); 
getchar();
return 0;
}

但是,下面的程序可能会打印一些垃圾数据,因为字符串存储在函数 getString() 的堆栈帧中,并且 getString() 返回后数据可能不存在。 

char *getString()
{
char str[] = "GfG"; /* Stored in stack segment */

/* Problem: string may not be present after getString() returns */
/* Problem can be solved if write static before char, i.e. static char str[] = "GfG";*/
return str; 
} 
int main()
{
printf("%s", getString()); 
getchar();
return 0;
}

 

这篇文章对您有用吗?