数组和C语言中的指针之间的区别到底是什么? [英] What's the difference between an array and a pointer in C exactly?

查看:285
本文介绍了数组和C语言中的指针之间的区别到底是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题听起来可能很愚蠢,但是我不太确定。我的意思是,

This question may sound stupid but I'm not really sure about it. I mean, what's the difference between:

char* line = (char*) malloc(MAX_LINE_LEN);

char line[MAX_LINE_LEN];

是吗?我知道前者是一个指针,后者是一个数组,但是系统如何分辨差异?

exactly? I know the former is a pointer and the latter is an array, but how can the system tell the difference? How is the memory allocated/stored?

此外,为什么要声明 line 占用的内存,为什么还要删除呢?作为指针,但不是当它是数组时?我认为数组存储在其他位置,并且超出范围时系统会自动重新分配其内存,在处理指针时不会发生这种情况,因此必须自己删除它。我错了吗?

Also, why can you delete the memory occupied by line when it's declared as a pointer, but not when it's an array? I think that an array is stored somewhere else and the system automatically deallocates its memory when it's out of scope, which doesn't happen when you are dealing with a pointer so you must delete it yourself. Am I wrong?

推荐答案

char* line = (char*) malloc(MAX_LINE_LEN);

这太差劲了;您无需在C中强制转换 malloc 。我们将其分为两部分,因为这样更易于描述和比较:

This is poor style; You don't need to cast malloc in C. Let's break this up into two sections, because it's easier to describe and compare that way:

char * line; 声明一个指向名为 line 的char的指针。您可以将其分配为指向一个对象(或不指向任何对象)。 sizeof 对象是其类型的大小,因此 sizeof(行) sizeof (char *),因系统而异。 & line char * 的地址,其类型为 char ** (指向char的指针)。它的存储持续时间取决于在哪里声明:

char *line; declares a pointer to char named line. You can assign it to point to an object (or nothing). The sizeof an object is the size of it's type, so sizeof (line) is sizeof (char *), which varies from system to system. &line is the address of a char *, which has the type char ** (pointer to pointer to char). It's storage duration depends upon where it is declared:


  • 如果在任何函数之外声明了它的静态存储持续时间,在程序的整个生命周期内持续有效。具有静态存储持续时间的对象将初始化为 0 ,除非存在显式初始化(​​例如,在您的情况下)。 0 空指针常量,表示如果该对象指向 nothing

  • If it's declared outside of any function, it has static storage duration, which lasts for the lifetime of the program. Objects with static storage duration are initialised to 0, unless an explicit initialisation exists (e.g. in your case). 0 is a null pointer constant, indicating that this object would point to nothing if it were declared outside of functions without an initialiser.

如果在代码块内部声明,则它具有自动存储期限,一直持续到执行结束为​​止该代码块。具有自动存储期限的对象必须在使用前明确初始化或分配给它们,因为否则它们的值是不确定的。

If it's declared inside of a block of code, it has automatic storage duration, which lasts until execution reaches the end of that block of code. Objects with automatic storage duration must be explicitly initialised or assigned to before they're used, because their value otherwise is indeterminate.

您的初始化为其分配了一个值,因此无论如何它都不会开始不确定。 malloc 返回一个具有动态存储持续时间的对象的指针,这意味着该指针所指向的对象将持续存在,直到它明确地免费 d。

Your initialisation assigns a value to it, so it won't start off indeterminate regardless. malloc returns a pointer to an object that has dynamic storage duration, which means the object that the pointer points to persists until it is explicitly freed.

想想这 ,就像邮件信封您可以在其中写一些东西,这将表明您可以找到对象(和人)的位置。邮政编码没有告诉您有关物体(或人员)大小的任何信息。

Think of this line like the postcode on a mail envelope; You can write something in there, and that something will indicate a location where you can find objects (and people). The postcode doesn't tell you anything about the size of the objects (or people).

char line[MAX_LINE_LEN];

这声明了一个 MAX_LINE_LEN 个字符的数组。

This declares an array of MAX_LINE_LEN chars.


  • 如果在任何函数外部声明,则它具有静态存储持续时间,并且整个数组为零填充。

  • If declared outside of any functions, it has static storage duration and the entire array is zero-filled.

如果在函数或代码块中声明,它将具有自动存储持续时间,并且数组中的值不确定;它们需要初始化(例如 char line [MAX_LINE_SIZE] = {0}; 将对其进行初始化)或分配给它们(例如 line [0 ] ='\0'; 将分配给数组的第一个元素)。

If declared inside a function or block of code, it has automatic storage duration and the values in the array are indeterminate; They need to be initialised (e.g. char line[MAX_LINE_SIZE] = { 0 }; will initialise all of them) or assigned to (e.g. line[0] = '\0'; will assign to the first element of the array) before they're used.

类型为 char [MAX_LINE_SIZE] ,因此大小为 sizeof(char [MAX_LINE_SIZE]),可以通过指定的元素数反映出来。在这种情况下,& line 的地址是 char(*)[MAX_LINE_SIZE] (指向数组的指针)的 MAX_LINE_SIZE 个字符)。

The type is char[MAX_LINE_SIZE], so the size will be sizeof (char[MAX_LINE_SIZE]), reflected as you can see by the number of elements specified. The address of &line in this case is a char (*)[MAX_LINE_SIZE] (a pointer to an array of MAX_LINE_SIZE chars).

这个不能像上面的那样重新分配,因此与我们的邮政编码示例。当在编译器需要指针的地方使用数组时,该数组将隐式转换为指向第一个元素的指针。例如,让我们考虑:

This one can't be reassigned like the one above, so it differs from our postcode example. When an array is used in places where a compiler expects a pointer, the array will be implicitly converted to a pointer to the first element. For example, let us consider:

strcpy(line, "Hello, world!");

函数原型 char * strcpy(char * restrict s1,const char *限制s2); ,告诉我们 strcpy 接受两个 char * 指向char )参数的指针。在示例中,参数之一是 char [MAX_LINE_LEN] ,另一个参数是 char [14] 。两者都转换为 char *

The function prototype char *strcpy(char *restrict s1, const char *restrict s2);, tells us that strcpy accepts two char * (pointer to char) arguments. In the example, one of the arguments is a char[MAX_LINE_LEN], and the other is a char[14]. Both got converted to a char *.

此数组到指针的转换说明了为什么 char * line; line = hello; 有效,而 char line [MAX_LINE_LEN]; line = hello; 不是。您无法更改转换后的指针。

This array-to-pointer conversion explains why char *line; line = "hello"; is valid, while char line[MAX_LINE_LEN]; line = "hello"; isn't. You can't change the pointer that results from the conversion.


我知道前者是指针,后者是数组,但是
系统如何分辨差异?

I know the former is a pointer and the latter is an array, but how can the system tell the difference?

如前所述,当数组表达式被转换为指针表达式时,用在需要指针的地方。例如,将 array [x] 中的 array 转换为 pointer 指针[x] 中。你在问什么?为什么要知道数组和指针之间的区别?

As previously stated, an array expression is converted to a pointer expression when it's used in places where a pointer is expected. For example, array in array[x] is converted to pointer in pointer[x]. What are you asking? Why would it need to know the difference between an array and a pointer?


我认为数组存储在其他地方,系统
超出范围时会自动重新分配其内存,

I think that an array is stored somewhere else and the system automatically deallocates its memory when it's out of scope,

是。我早先解释了不同的存储时间。

Yes. I explained the different storage durations earlier.


在处理指针时不会发生,因此必须删除
它自己。我错了吗?

which doesn't happen when you are dealing with a pointer so you must delete it yourself. Am I wrong?

是的。您将指针的概念与存储期限的概念混淆了。 int * p = malloc(sizeof * p); p初始化为指向具有动态存储持续时间的 int 。在调用 free(p); 之前, int 不会被销毁。但是,以下两个变量都具有自动存储期限,因为它们在 main 中声明,而没有任何限定符,例如 static p 指向 i p 是一个指针。不要免费 p,因为它不会指向具有动态存储持续时间的对象。 免费仅用于销毁具有动态存储时间的对象。

Yes. You're confusing the concept of pointers with the concept of storage duration. int *p = malloc(sizeof *p); p is initialised to point to an int that has dynamic storage duration. That int won't be destroyed until free(p); is called. Both of the variables below, however, have automatic storage duration because they're declared within main, without any qualifiers such as static. p points to i; p is a pointer. Don't free p, because it doesn't point to an object that has dynamic storage duration. free is only defined to destroy objects that have dynamic storage duration.

int main(void) {
    int i = 42;
    int *p = &i;
}

这篇关于数组和C语言中的指针之间的区别到底是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆