char指针数组和char 2d数组之间的区别?

问题描述

以下程序运行良好

#include<stdio.h>
#include <string.h>
int main() {
 char output[2][3];

 strcpy(output[0],"hello");
 
 printf("output[0] = %s\n",output[0]);
 printf("output[1] = %s\n",output[1]);

}

输出

output[0] = hello
output[1] = lo

可以观察到,如果字符串大小更多,则下一个元素会重叠

如果我按如下所示修改上述程序,则会显示警告和错误

#include<stdio.h>
#include <string.h>
int main() {
 char output[2][3];

 strcpy(output[0],"hello world");
 
 printf("output[0] = %s\n",output[1]);

}

输出 **

在大小为6的区域中写入12个字节会使目标溢出

**

但是,如果我使用char指针数组,则它适用于如下所示的任意长度的字符串

#include<stdio.h>
#include <string.h>
int main() {
 char *output[2] ;

output[0]="Hello World" ;
output[1]="Country" ;
 printf("output[0] = %s\n",output[1]);
 
 printf("address of output[0] = %p\n",&output[0]);
 printf("address of output[1] = %p\n",&output[1]);


}

输出

output[0] = Hello World
output[1] = Country
address of output[0] = 0x7ffe89dc4210
address of output[1] = 0x7ffe89dc4218

可以观察到output0的大小为8,我也尝试过使用大小为10的char指针数组,而不管输入到数组每个元素的字符数如何,元素地址之间的差仍然为8 正如在第一种情况下所观察到的,它也没有与数组的下一个元素重叠。

  • 这是怎么回事?
  • 如果是char指针数组,那么长字符串的内存来自哪里?
  • 使用char output[][]char *output[]哪个更好?

添加一个示例

#include<stdio.h>
#include <string.h>
int main() {
 char *output[2] ;

output[0]="Hello World" ;
output[1]="Country" ;
 printf("output[0] = %s\n",&output[1]);

output[0]="Text Parsing in c" ;
output[1]="text" ;
 printf("output[0] = %s\n",&output[1]);

}

输出

output[0] = Hello World
output[1] = Country
address of output[0] = 0x7fff5cf668e0
address of output[1] = 0x7fff5cf668e8
output[0] = Text Parsing in c
output[1] = text
address of output[0] = 0x7fff5cf668e0
address of output[1] = 0x7fff5cf668e8

解决方法

您声明了两个指针组成的数组。

char *output[2] ;
您系统中的

sizeof( char * )等于8。

为指针分配了具有静态存储持续时间的字符串文字的第一个字符的地址。

output[0]="Hello World" ;
output[1]="Country" ;

字符串文字本身没有被复制。

您可以通过以下方式想象此代码段

char string_literal1[] = "Hello World";
char string_literal2[] = "Country";

char *output[2] ;

output[0] = string_literal1;
output[1] = string_literal2;

最后两个任务等同于

output[0] = &string_literal1[0];
output[1] = &string_literal2[0];

关于你的问题

最好使用char output [] []或char * output []吗?

然后请记住,您不得更改字符串文字。任何更改字符串文字的尝试都会导致未定义的行为。

所以如果有例子

char *s = "hello";

那你可能不会写

s[0] = 'H';

但是如果您要声明一个由字符串文字初始化的字符数组,例如

char s[] = "hello";

那么你可以写

s[0] = 'H';