C语言字符串使用指针形式和数组形式的区别

C语言字符串使用指针形式和数组形式的区别

  • 字符串的初始化
  • 那么用指针形式和数组形式有什么区别呢?
    • 在内存分配上的区别
    • 在使用时的区别
  • 字符串指针数组——高效使用内存

字符串的初始化

一.数组形式

  1. 指定大小的
const char word[6] = "wdnmd";

2.不指定大小,有编译器计算大小,这种形式只能在初始化时使用,如果要创建一个稍后再填充的数组,则必须指定大小

const char word[] = "wdnmd";

二.指针形式

const char * p1 = "wdnmd"

那么用指针形式和数组形式有什么区别呢?

在内存分配上的区别

当以数组形式初始化时,计算机为其分配一个六个元素的内存单元。通常字符串都作为可执行文件的一部分储存在数据段中,当把程序载入内存时,也载入了程序中的字符串,但是,程序要等到运行时才会为数组分配内存,此时才将字符串拷贝到数组中。此后,内存中的字符串有两个副本,一个存储在静态存储区,一个存储在数组中。

当以指针形式初始化时,与数组形式相同的是,编译器也为字符串在静态存储区预留六个元素的空间,不同的是,他还会为指针变量留出一个存储位置,将字符串的地址给他

总而言之,以数组形式初始化是将字符串拷贝给他,而指针形式是将字符串的地址给他

在使用时的区别

众所周知,C语言中字符串是静态存储类别,所以将字符串字面量视为const类型,所以指针应该声明为指向const数据的指针。而涉及const的类型,使用指针必定会不可避免的犯一些错误。

接下来我们看一下,用未使用const限定符的指针初始化:

#include
void main(void)
{
 char* p = "wdnmd";
 
 p[1] = 'f';
 puts(p);
 return}

 

运行结果如下:
C语言字符串使用指针形式和数组形式的区别_第1张图片
很明显,我们的代码通过了编译器,但是执行时并没有任何结果,这是为什么呢?

要解释这个问题,我们先来看一下下面的代码

#include
#define STRING "I'm special"
void main(void)
{
 char word[] = STRING;
 const char * pt = STRING;
 
 printf("address of \"I'm special\": %p \n", "I'm special");
 printf("         address of word: %p\n", word);
 printf("       address of STRING: %p\n", STRING);
 printf("address of \"I'm special\": %p \n", "I',special");

 return;
 }

运行结果如下:
C语言字符串使用指针形式和数组形式的区别_第2张图片

这个程序的输出中有个很奇怪的地方,I‘m special在连个printf函数中出现了两次,但是确实两个不同的地址,这说明了什么,编译器可以使用内存中的一个副本来表示完全相同的字符串字面量。

清楚了这个以后,我们继续讨论上面的问题。实际上,这种行为的结果C语言是未定义,很有可能会导致内存访问错误,例如,下面的语句引用字符串“I will fuck your wife”的一个内存位置:

char * p = "I will fuck your wife";
p[0]='c';
printf(“I will fuck your wife");
printf(":Be careful ,%ss!\n","I will fuck your wife");

输出结果可能为:c will fuck your wife:Be careful ,c will fuck your self(之所以说可能,是因为编译器不同,结果也会不一样)

也就是说,编译器可以用相同的地址替换没个I will fuck your wife实力,如果编译器使用这种单词副本表示法,而且允许p[0]修改I,那么僵影响所有使用该字符串的代码

所以建议在指针初始化时加上const限定符

总而言之,如果打算修改数据,那么最好就不要用指针形式

字符串指针数组——高效使用内存

有以下代码

const char * word1[3]={
"ASDKFJ"
"AKDSJFLAKL"
"AKSDJFAL;KDSJF"
}

const word2[3][20] = {
"ASDKFJ"
"AKDSJFLAKL"
"AKSDJFAL;KDSJF"
}

word显然内存占用更少

原因之一是word1是一个内含三个指针的数组,分别指向三个字符串,它占的内存只不过是地址类型的大小;而word2储存字符串字面量的副本,所以每个字符串被存储了两次
第二个原因我觉得这样子理解比较形象,word2是一个规则的盒子,每行大小相同,为了每行都装的下,他必须能储存最长字符串的大小,一共3行,每行有15个char类型的值,总共占45个字节;而word1是一个不规则的盒子,每行有自己的空间,互不干扰,只要装的下这一行的字符串就ok了,它只占24个字节,共三个地址,每个地址占8个字节,显然word2所需的空间更大

你可能感兴趣的:(C语言,c语言,字符串,指针)