c中的数组名称究竟是什么? [英] What exactly is the array name in c?

查看:32
本文介绍了c中的数组名称究竟是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解 C 中数组名称的类型和用法.这可能看起来很长,但请耐心等待.

我了解以下语句声明 aint [] 类型,即整数数组.

int a[30];

虽然 a 也指向数组的第一个元素,但诸如 *(a+2) 之类的东西都是有效的.因此,使 a 看起来像一个 指向整数的指针.但实际上int []int*的类型是不同的;前者是数组类型,后者是整数指针.

当将 int [] 类型的变量传递给函数时,它也会被转换为 int* 类型的变量;就像在 C 中一样,数组是通过引用传递的(sizeof 运算符除外).

这里是让我摇摆不定的一点.看看下面的一段代码:

int main(){int (*p)[3];int a[3] = { 5, 4, 6 };p = &a;printf("a:%d\t&a:%d\n",a,&a);printf("%d",*(*p + 2));}

输出:

a:2686720 &a:26867206

那么,上面的代码是如何工作的呢?我有两个问题:

  1. a&a 具有相同的值.为什么?
  2. int (*p)[3]; 到底做了什么?它声明了一个指向数组的指针,我知道这一点.但是指向数组的指针指向数组第一个元素的指针数组名有何不同?

有人能澄清一下吗?我有很多困惑.

我知道我应该使用 %p 作为占位符而不是使用 %d 来打印指针变量的值.因为使用整数占位符可能会打印截断的地址.但我只想保持简单.

解决方案

  1. a 和 &a 具有相同的值.如何?

它们具有相同的值但类型不同.数组对象在元素之间(之前或之后)没有填充,因此数组的地址和数组的第一个元素的地址相同.

即:

(void *) a == (void *) &a

<块引用>

  1. 它到底做了什么 int (*p)[3];声明一个指向数组的指针,我知道这一点.但是,指向数组的指针与指向数组第一个元素和数组名称的指针有何不同?

这是两种不同的指针类型.以指针运算为例:

a + 1/* 数组第二个元素的地址 */&a + 1/* 数组最后一个元素后的地址 */

由于大众需求,我在下面添加了一些有关数组转换的信息.

除了三个例外,在表达式中,T 类型的数组对象被转换为指向数组第一个元素的 T 类型指针的值.例外情况是对象是 sizeof& 一元运算符的操作数,或者对象是初始化数组的字符串文字.

例如这个语句:

printf("a:%d\t&a:%d\n", a, &a);

实际上相当于:

printf("a:%d\t&a:%d\n", &a[0], &a);

另外请注意,d 转换说明符只能用于打印有符号整数;要打印指针值,您必须使用 p 说明符(并且参数必须是 void *).所以要正确地做事,请使用:

printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);

分别:

printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);

I am having a tough time understanding the type and use of the name of the array in C. It might seems a long post but please bear with me.

I understand that the following statement declares a to be of type int [] i.e array of integers.

int a[30];

While a also points the first element of array and things like *(a+2) are valid. Thus, making a look like a pointer to an integer. But actually the types int [] and int* are different; while the former is an array type and later is a pointer to an integer.

Also a variable of type int [] gets converted into a variable of type int* when passing it to functions; as in C arrays are passed by reference (with the exception of the sizeof operator).

Here comes the point which makes me dangle. Have a look at the following piece of code:

int main()
{
    int (*p)[3];
    int a[3] = { 5, 4, 6 };

    p = &a;

    printf("a:%d\t&a:%d\n",a,&a);
    printf("%d",*(*p + 2));
}

OUTPUT:

a:2686720       &a:2686720
6

So, how does the above code work? I have two questions:

  1. a and &a have the same values. Why?
  2. What exactly does int (*p)[3]; do? It declares a pointer to an array, I know this. But how is a pointer to an array different from the pointer to the first element of the array and name of the array?

Can anyone clarify things up? I am having a hell of a lot of confusions.

I know that I should use %p as a placeholder instead of using %d for printing the value of pointer variables. As using the integer placeholder might print truncated addresses. But I just want to keep things simple.

解决方案

  1. a and &a have the same values.How?

They have the same value but different types. Array objects have no padding between elements (before or after) so the address of the array and the address of the first element of the array are the same.

That is:

(void *) a == (void *) &a

  1. What exactly it does int (*p)[3]; Declares a pointer to an array,i know this.But,how a pointer to an array is different from the pointer to the first element of the array and name of the array?

These are two different pointer types. Take for example, pointer arithmetic:

a + 1   /* address of the second element of the array */
&a + 1  /* address one past the last element of the array */

EDIT: due to popular demand I added below some information about conversion of arrays.

With three exceptions, in an expression an object of type array of T is converted to a value of type pointer to T pointing to the first element of the array. The exceptions are if the object is the operand of sizeof or & unary operator or if the object is a string literal initializing an array.

For example this statement:

printf("a:%d\t&a:%d\n", a, &a);

is actually equivalent to:

printf("a:%d\t&a:%d\n", &a[0], &a);

Also please note that d conversion specifier can only be use to print a signed integer; to print a pointer value you have to use p specifier (and the argument must be void *). So to do things correctly use:

printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);

respectively:

printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);

这篇关于c中的数组名称究竟是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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