Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中数组、指针和字符串之间的差异_C_Arrays_String_Pointers - Fatal编程技术网

C中数组、指针和字符串之间的差异

C中数组、指针和字符串之间的差异,c,arrays,string,pointers,C,Arrays,String,Pointers,只是心里有一个困扰我的问题 我知道指针和数组在C语言中是不同的,因为指针存储一个地址,而数组存储实值 但是当涉及到字符串时,我感到困惑 char *string = "String"; 我读到这一行有几个功能: 编译器创建了一个字符数组,其值为字符串 char *string = "String"; 然后,该数组被视为指针,程序为指针字符串指定一个指针,该指针指向编译器创建的数组的第一个元素 这意味着,数组被视为指针 那么,这个结论是真是假,为什么 如果为false,那么指针和数组之间有什么

只是心里有一个困扰我的问题

我知道
指针
数组
在C语言中是不同的,因为
指针
存储一个
地址
,而
数组
存储
实值

但是当涉及到
字符串时,我感到困惑

char *string = "String";
我读到这一行有几个功能:

编译器创建了一个字符数组,其值为
字符串

char *string = "String";
然后,该数组被视为
指针
,程序为指针字符串指定一个指针,该指针指向编译器创建的数组的
第一个元素

这意味着,
数组
被视为
指针

那么,这个结论是真是假,为什么

如果为false,那么
指针
数组
之间有什么区别?
谢谢。

我们可以创建一个名为“string”的数组

char string[] = "Hello";
我们可以分配一个指向该字符串的指针

char* stringPtr = string;
数组名为

因此,数组名类似于指针。但是,它们并不相同,因为数组是一个连续的内存块,而指针只引用内存中的一个位置(地址)

char *string = "String";
此声明创建数组并设置指向用于存储数组的内存块的指针地址

这意味着,数组被视为指针。那么,这个结论是真是假

False,数组不是指针。但是,为了混淆(!),由于解引用运算符[],指针可能看起来像数组

char *string = "String";
char letter = string[2];
在本例中,字符串[2]首先转换为指向数组第一个字符的指针,并使用指针算法返回相关项。

指针包含对象的地址(或者是不指向任何对象的空指针)。指针具有特定类型,指示它可以指向的对象的类型

数组是元素的连续有序序列;每个元素都是一个对象,数组的所有元素都是相同类型的

字符串被定义为“由第一个空字符终止并包括该空字符的连续字符序列”。C没有字符串类型。字符串是数据布局,而不是数据类型

数组和指针之间的关系可能令人困惑。我所知道的最好的解释是在报告的第6节。要记住的最重要的事情是数组不是指针

<>数组在某种意义上说是C和C++中的“二等公民”。它们不能被赋值、作为函数参数传递或进行相等性比较。操纵数组的代码通常使用指向数组各个元素的指针,并使用一些明确的机制指定数组的长度

造成混淆的一个主要原因是,在大多数上下文中,数组类型的表达式(例如数组对象的名称)被隐式转换为指针值。转换后的指针指向数组的初始(第零个)元素。如果阵列为以下任一类型,则不会发生此转换:

  • sizeof
    的操作数(
    sizeof array\u object
    产生数组的大小,而不是指针的大小)
  • 一元
    &
    的操作数(
    &array\u object
    产生整个数组对象的地址);或
  • 初始值设定项中的字符串文字,用于初始化数组对象

    char*string=“string”

为了避免混淆,我将对您的示例进行一些更改:

const char *ptr = "hello";
字符串literal
“hello”
创建一个类型为
char[6]
(在C++中)或
const char[6]
(在C++中)的匿名对象,其中包含字符
{h',e',l',l',o','\0'

在此上下文中,对该表达式的求值将生成指向该数组初始字符的指针。这是一个指针值;没有隐式创建的指针对象。该指针值用于初始化指针对象
ptr

任何时候都不能将数组“视为”指针。数组表达式转换为指针类型

另一个引起混淆的原因是,看起来是数组类型的函数参数实际上是指针类型的;类型在编译时进行调整。例如,这:

void func(char param[10]);
真正的意思是:

void func(char *param);
10
被静默忽略。所以你可以这样写:

void print_string(char s[]) {
    printf("The string is \"%s\"\n", s);
}
// ...
print_string("hello");

这看起来像是在操纵数组,但实际上数组“hello”
被转换成一个指针,该指针就是传递给
print\u string
函数的指针。

您必须了解内存中发生了什么

字符串是以特殊值(空终止符)终止的连续内存单元块。如果您知道这段内存的开始,并且知道它的结束位置(通过被告知内存单元的数量或者通过读取它们直到达到空值),那么您就可以开始了

指针只不过是内存块的开始、第一个内存单元的地址或指向第一个元素的指针。所有这些术语的意思都是一样的。它就像电子表格中的单元格引用,如果你有一个巨大的网格,你可以通过它的X-Y坐标告诉你一个特定的单元格,所以单元格B5告诉你一个特定的单元格。在计算机术语(而不是电子表格)中,内存实际上是一个非常非常长的单元格列表,如果您愿意,它是一个一维电子表格,单元格引用看起来像0x12345678,而不是B5

最后一点是理解计算机程序是由操作系统加载到内存中的数据块,编译器将计算出字符串相对于程序开始的位置,因此您可以自动知道它位于哪个内存块中

这与分配一块备忘录完全相同
char* mystring = new char(7);
copy_some_memory(mystring, "string", 7);
char *string = "String";  
char string[] = "String";    
char s[] = "String"; // char[7]
char *p = s;
char *p = &s[0];