C语言 指针的字符数组可以存储字符串吗?

ztmd8pv5  于 2023-03-07  发布在  其他
关注(0)|答案(4)|浏览(208)

我正在学习C中指向数组的指针。一切都很好,直到我遇到了这段代码。*names是指针数组,它应该存储指向char的地址,但它存储的是字符串。有人能给我解释一下吗?

#include <stdio.h>

const int MAX = 4;

int main () {
    char *names[] = {
        "Zara Ali",
        "Hina Ali",
        "Nuha Ali",
        "Sara Ali"
    };
    int i = 0;

    for (i = 0; i < MAX; i++) {
        printf("Value of names[%d] = %s\n", i, names[i]);
    }

    return 0;
}

输出:

Value of names[0] = Zara Ali
 Value of names[1] = Hina Ali
 Value of names[2] = Nuha Ali
 Value of names[3] = Sara Ali
jvidinwx

jvidinwx1#

这一点:

char *names[] = {
  "Zara Ali",
  "Hina Ali",
  "Nuha Ali",
  "Sara Ali"
};

声明名称为指向char的指针数组,并使用四个字符串的第一个元素的地址初始化其元素。
用双引号括起来的字符串是一种书写指向无名数组的指针的简便方法,该数组已经用引号之间的字符和一个额外的空字节(标记字符串的结尾)初始化。
names是一个指针数组,它应该存储那些指向char的地址,但它存储的是string。
是的,它是一个指向char的指针数组,而不是指向字符串,它的元素指向字符串的第一个元素,也就是char
在内存中,数组的第一个元素如下所示:

+-------+
names[0]: |   *   |
          +---|---+
              |
              V
            +---+---+---+---+---+----+---+---+---+
            |'Z'|'a'|'r'|'a'|' '|'A'|'l'|'i'|'\0'|
            +---+---+---+---+---+----+---+--+----+

注意这个内存是不可变的,也就是说你可以改变指针指向其他地方,但是你不能改变指向的数据,否则你的代码会调用未定义的行为,因此,最好用const限定符声明指向字符串常量的指针:

const char *names[] = {
  "Zara Ali",
  "Hina Ali",
  "Nuha Ali",
  "Sara Ali"
};

使用const有助于保持字符串的完整性,因为您只能使用指向字符串的新指针或通过将其传递给修改字符串的函数来修改它。

ztigrdn8

ztigrdn82#

在本声明中

char *names[] = {
  "Zara Ali",
  "Hina Ali",
  "Nuha Ali",
  "Sara Ali"
    };

具有数组类型char[9]和静态存储持续时间的用作初始化器的串文字量被隐式转换为指向其第一元素的类型char *的指针。
你甚至可以写

char *names[] = {
  &"Zara Ali"[0],
  &"Hina Ali"[0],
  &"Nuha Ali"[0],
  &"Sara Ali"[0]
    };

注意,例如字符串字面值"Zara Ali"作为数组存储在内存中,如

{ 'Z', 'a', 'r', 'a', ' ', 'A', 'l', 'i', '\0' }
oprakyz7

oprakyz73#

字符串文字的类型为char[N]。
但除非数组与 &sizeof 运算符一起使用,否则它将转换为指向其元素的指针。
因此,如果你写char *str = "Hello, World!",“Hello,World!”的实际类型是char[14],它存储在内存中的某个地方。
但是在str初始化时会转换为char*

4zcjmb1e

4zcjmb1e4#

它存储指针....字符串(字符串常量)位于names之外的某个内存中。编译器会处理这个问题。
你可以把代码想象成这样:

// Strings as global variables
  char str1[] = "Zara Ali";
  char str2[] = "Hina Ali";
  char str3[] = "Nuha Ali";
  char str4[] = "Sara Ali";
    
 int main () {

    char *names[] = {
        &str1[0],     // Storing pointers
        &str2[1],
        &str3[2],
        &str4[3]
    };

这里,4个字符串显然存储在names之外的存储器中,并且names保存指向字符串的第一个字符的指针。
当你这样做

char *names[] = {
  "Zara Ali",
  "Hina Ali",
  "Nuha Ali",
  "Sara Ali"
    };

这是一样的,编译器只是在幕后处理它。
顺便说一句:
由于您有一个指针数组,因此可以执行以下操作:

char *names[] = {
  "Zara Ali",
  "Hina Ali",
  "Nuha Ali",
  "Sara Ali"
};
size_t MAX = sizeof names / sizeof names[0];

而不是硬编码const int MAX = 4;。然后,当新字符串添加到数组中时,MAX将自动获得正确的值。

相关问题