C字符串、字符和指针

5

我对C语言中以下概念存在误解。

据我所知,定义字符串可以采取以下方法之一:

像下面这样定义char数组:

char array[];

或者将一个字符串定义为字符数组。比如说这个:

char * str,

为什么有些书使用指针方法,而其他书则使用常规定义?

9
char * str 是指向 char 类型的指针,而不是 "字符串转字符数组"。 - t0mm13b
1
@sameerasy,这并不完全正确,char* str 也可能指向一个 char array[],所以这取决于它指向哪里。 - alain
1
@sameerasy 不是很确定。i 是什么?malloc()strcpy(),或者strdup()是什么? - Sourav Ghosh
@sameerasy,那并不正确。指向char的指针可以改变它们的引用地址,所以它是可变的。如果是一个const,则可以应用不可变性。 - t0mm13b
1
我认为人们会给你的问题投反对票,因为这个问题似乎非常宽泛和不准确。如果你能提供一些真实情况并说明如何在其中使用字符,那将更好。 - nayana
显示剩余4条评论
2个回答

16
一个简短的回答不能充分回答你的问题。你正在询问C语言中最重要但常常被误解的两个方面之一。
首先,在C语言中,根据定义,字符串是由一系列字符组成的数组,并以一个空字符'\0'作为结尾。
因此,如果你这样说:
char string1[] = "Hello";

就好像你说过的一样。

char string1[] = {'H', 'e', 'l', 'l', 'o', '\0'};
当你在程序中使用像 "Hello" 这样的字符串常量时,编译器会自动为你构建数组,以方便使用。
接下来是字符指针类型,char *。你把它称为“字符串到字符数组”的转换,但它实际上是一个指向单个 char 的指针。人们经常将 char * 称为 C 的“字符串类型”,在某种程度上是这样,但这可能是一种误导性的说法,因为并非每个 char * 都是一个字符串,并且更重要的是,C 几乎没有自动管理字符串的机制。(我所说的是,在 C 中,你不能像在 C++ 或 BASIC 中那样随意将字符串作为基本数据类型来回传递。通常需要担心它们存储的位置,如何分配。)
但让我们回到字符串的定义。如果字符串是字符的数组,那么为什么指向字符的指针对于操作字符串有用呢?答案是,在 C 中指针始终对于操作数组很有用;指针在操作数组方面非常强大,以至于有时似乎它们就是数组。(但不用担心,它们并不是。)
我无法在这里深入探讨 C 中数组和指针之间的关系,但必须说明几点:
如果你说类似于
char *string2 = "world";

实际上发生的事情(编译器自动为您完成的操作)就好像您已经写下了

static char __temporaryarray[] = "world";
char *string2 = __temporaryarray;

实际上,由于string2是一个指向字符的指针(也就是说,它所指向的是字符,而不是整个字符数组),因此它实际上是:

而且,实际上,由于string2是指向字符的指针(也就是说,它指向的是字符,而不是整个字符数组),所以它实际上是:

char *string2 = &__temporaryarray[0];
(也就是说,指针实际上指向数组的第一个元素。)因此,由于字符串始终是一个数组,当您在上下文中提到字符串“world”时,并不是在使用它来初始化一个数组,C会为您创建数组,然后使指针指向它。每当您的程序中有一个字符串常量时,C都会这样做。所以您以后可以这样说:
string2 = "sailor";

你还可以说像这样的话

if(strcmp(string1, "Goodbye") == 0) { ... }

只是不要做。

char *string3;

strcpy(string3, "Rutabaga");        /* WRONG!! *//

那是非常错误的,而且根本不可靠,因为没有人为 string3 分配任何内存来指向,供 strcpy 将字符串复制进去。


所以回答你的问题,有时候会看到字符串被创建或处理得像数组一样,因为它们实际上就是数组。但是通常会看到它们使用指针(char *)进行操作,因为这非常方便,只要你知道你在做什么。


2
为什么有些书使用指针方法,而其他书则使用常规定义?这两种方法都没有比另一种更“正常”。在C语言中,字符串是一个由char字符组成的连续序列,并以0字符结尾。你可以用char[]、char*、const char*等方式引用它。它们只是引用内存块中char字符序列的不同方式。每种方式在不同的上下文中都是适当的,具体取决于代码如何接收字符串以及对其进行的操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接