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

查看:104
本文介绍了数组和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 (line)sizeof (char *),这随系统的不同而不同. &linechar *的地址,其类型为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,除非存在显式初始化(​​例如,在您的情况下). 0null pointer constant,表示如果在没有初始化程序的函数外部声明该对象,则该对象将指向 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返回指向具有动态存储持续时间的对象的指针,这意味着该指针所指向的对象将持续存在,直到将其明确地显示为free 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.

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

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 *restrict 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]中的pointer.你在问什么?为什么需要知道数组和指针之间的区别?

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?

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

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天全站免登陆