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];