数组和指针教程 [英] Array and Pointer Tutorial

查看:64
本文介绍了数组和指针教程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有些程序员像指针一样处理数组(有些人甚至认为

他们完全等价)。我将展示不同之处。


首先,让我们假设我们正在开发一个具有

跟随的平台属性:


1)char'是8位。 (char是与byte的同义词。)

2)int'是32位。 (sizeof(int)== 4)。

3)指针是64位。 (sizeof(int *)== 8)。

首先让我们做两个声明:


int main(无效)

{

int array [5];


int * const pointer =(int *)malloc(5 * sizeof(int));

}

现在我将演示如何数组和指针是不同的:

我会从简单的分析表达开始:


================ ================================== ================ ==========

|表达|类型和访问说明符|用英语写的|

====================================== ============ ==========================

| | | |

|数组| int [5] |一个由五个int组成的数组。|

| | | |

| ---------------------------------------- -----------------------------------

| | |一个const指针|

|指针| int * const |指向可修改的|

| | | INT。 |

| ---------------------------------------- ---------------------------------- |

| | |一个const指针|

| & array | int(* const)[5] |指向可修改的|

| | |五个int的数组。 |

| ---------------------------------------- ---------------------------------- |

| | |一个const指针,其中|

| &指针| int * const * const |指向const |

| | |指针,指向|

| | |一个可修改的int。 |

========================================= ========= ==========================

这是'如何的sizeof"与他们合作:

====================================== ============ =========

|表达| sizeof(exp)|但为什么? |

========================================= ========= =========

| | | |

|数组| 20 |这是五个int'。 |

| | (5 * 4)| |

| ---------------------------------------- ----------------- |

| | | |

|指针| 8 |它只是一个指针。|

| | (只是8)| |

| ---------------------------------------- ----------------- |

| | | |

| & array | 8 |它只是一个指针。|

| | (只是8)| |

| ---------------------------------------- ------------------

| | | |

| &指针| 8 |它只是一个指针。|

| | | |

| | (只是8)| |

========================================= ========= =========

好​​的接下来要讨论的是使用方括号和

解除引用运算符。其中两个仅供指针使用。那么

为什么我们可以将它们用于数组,如下所示?:


array [0] = 4;


* array = 6;


原因是以下类型的表达式:


int [5]


可以隐式转换为以下类型的表达式:


int * const


它做什么转换为指向数组第一个元素的指针。

因此,第一个例子:


array [0] = 4;


隐式转换数组到一个普通的指针,然后使用链式支架

访问与原始地址相差一定距离的内存。


另外第二个例子:


* array = 6;


隐式转换数组到正常的指针,然后取消引用它。

注意:你必须记住一个数组隐式转换为指向

的指针,它的第一个元素,而不是指向数组的指针。这个事实有一些

的影响。这就是一个这样的含义:

*(数组+3)= 6;

以上代码行的作用如下:


1)隐式转换数组到:int * const

2)向地址添加3 * sizeof(int)。

3)取消引用结果指针,并为其指定6。 />
如果是数组隐式转换为:int(*)[5]

而不是指向第一个元素的指针,然后上面的步骤2将是

不同,具体来说:

2)在地址中添加3 * sizeof(int [5])。

我们知道sizeof(int [5])在这个平台上是20(不是8!)。

所以你可能会问,指向数组的指针是什么意思? - 好吧

这里它可以派上用场:

void SomeFunc(int(* const p_array)[5])

{

(* p_array)[0] = 99;

(* p_array)[1] = 98;

(* p_array) [2] = 97;

(* p_array)[3] = 96;

(* p_array)[4] = 95;


/ *这个函数不接受任何其他尺寸的
阵列! * /

}

这里是一个C ++ - 具体参考的例子:


void SomeFunc(int(&)数组)[5])

{

array [0] = 99;

array [1] = 98;

数组[2] = 97;

数组[3] = 96;

数组[4] = 95;


/ *这个函数不接受其他尺寸的任何

的数组! * /

}

同样在C ++中,你可以利用模板:


模板< class T,unsigned long len>

void KeepCopy(const T(& array)[len])

{

static my_array [len];


/ *做一些其他的事情* /

}

我已经把它发布到几个新闻组,所以如果你''如果想回复,请将

发布到comp.lang.c,因为它是共同点。如果您的帖子是C ++ -

具体,请发布到comp.lang.c ++。


我是否遗漏了什么?


-Tomás


[见 http://www.gotw.ca/resources/clcm.htm 有关的信息]

[comp.lang.c ++。moderated。第一次海报:做到这一点! ]

-

comp.lang.c.moderated - 审核地址: cl ** @ plethora.net - 您必须

在您的标题中有适当的新闻组行,以便查看您的邮件,

或方括号中的新闻组名称主题。对不起。

Some programmers treat arrays just like pointers (and some even think that
they''re exactly equivalent). I''m going to demonstrate the differences.

Firstly, let''s assume that we''re working on a platform which has the
following properties:

1) char''s are 8-Bit. ( "char" is synomonous with "byte" ).
2) int''s are 32-Bit. ( sizeof(int) == 4 ).
3) Pointers are 64-Bit. ( sizeof(int*) == 8 ).
First let''s make two declarations:

int main(void)
{
int array[5];

int* const pointer = (int*)malloc( 5 * sizeof(int) );
}
Now I''ll demonstrate how "array" and "pointer" are different:
I''ll start off with simple analgous expressions:

================================================== ==========================
| Expression | Type and Access Specifiers | That in English |
================================================== ==========================
| | | |
| array | int[5] | An array of five int''s.|
| | | |
|---------------------------------------------------------------------------
| | |A const pointer which |
| pointer | int* const |points to a modifiable |
| | |int. |
|--------------------------------------------------------------------------|
| | |A const pointer which |
| &array | int (* const)[5] |points to a modifiable |
| | |array of five int''s. |
|--------------------------------------------------------------------------|
| | |A const pointer, which |
| &pointer | int* const* const |points to a const |
| | |pointer, which points to|
| | |a modifiable int. |
================================================== ==========================
Here''s how "sizeof" works with them:
================================================== =========
| Expression | sizeof( exp ) | But Why? |
================================================== =========
| | | |
| array | 20 | It''s five int''s. |
| | (5 * 4) | |
|---------------------------------------------------------|
| | | |
| pointer | 8 | It''s just a pointer.|
| | (just 8) | |
|---------------------------------------------------------|
| | | |
| &array | 8 | It''s just a pointer.|
| | (just 8) | |
|----------------------------------------------------------
| | | |
| &pointer | 8 | It''s just a pointer.|
| | | |
| | (just 8) | |
================================================== =========
Okay next thing to discuss is the usage of square brackets, and the
dereference operator. The two of these are to be used by pointers only. So
how come we can use them with arrays, as follows?:

array[0] = 4;

*array = 6;

The reason is that an expression of the following type:

int[5]

can implicitly convert to an expression of the following type:

int* const

What it does is convert to a pointer to the first element of the array.
Therefore, the first example:

array[0] = 4;

implicitly converts "array" to a normal pointer, then uses chain brackets to
access memory at a certain offset from the original address.

Also the second example:

*array = 6;

implicitly converts "array" to a normal pointer, then dereferences it.
NOTE: You must remember that an array implicitly converts to a pointer to
its first element, NOT to a pointer to the array. This fact has a few
implications. Here''s one such implication:
*(array + 3) = 6;
What the above line of code does is the following:

1) Implicitly converts "array" to an: int* const
2) Adds 3 * sizeof(int) to the address.
3) Dereferences the resulting pointer, and assigns 6 to it.
If "array" implicitly converted to: int (*)[5]
rather than a pointer to the first element, then Step 2 above would be
different, specifically:
2) Adds 3 * sizeof( int[5] ) to the address.
And we know that sizeof(int[5]) is 20 on this platform (not 8!).
So you may ask, "What''s the point in having a pointer to an array?" -- well
here''s where it may come in handy:
void SomeFunc ( int (* const p_array)[5] )
{
(*p_array)[0] = 99;
(*p_array)[1] = 98;
(*p_array)[2] = 97;
(*p_array)[3] = 96;
(*p_array)[4] = 95;

/* This function won''t accept an array of any
other size! */
}
And here''s a C++-specific example with references:

void SomeFunc ( int (&array)[5] )
{
array[0] = 99;
array[1] = 98;
array[2] = 97;
array[3] = 96;
array[4] = 95;

/* This function won''t accept an array of any
other size! */
}
Also in C++, you can exploit the use of templates:

template<class T, unsigned long len>
void KeepCopy( const T (&array)[len] )
{
static my_array[len];

/* Do some other stuff */
}
I''ve posted this to a few newsgroups, so if you''d like to reply, please post
to comp.lang.c because it''s the common denominator. If your post is C++-
specific, the please post to comp.lang.c++.

Did I leave anything out?

-Tomás

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
--
comp.lang.c.moderated - moderation address: cl**@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

推荐答案

"Tomás" < NU ** @ NULL.NULL>写道:
"Tomás" <NU**@NULL.NULL> wrote:
一些程序员将数组视为指针(有些人甚至认为它们完全相同)。我将展示差异。

首先,我们假设我们正在开发一个具有以下属性的平台:

1)char'是8位。 (char是与byte的同义词)。


char是_always_一个字节。你的意思是你假设一个char

(因此也是一个字节)等于一个八位字节。

2)int'是32位。 (sizeof(int)== 4)。
3)指针是64位。 (sizeof(int *)== 8)。


首先让我们做两个声明:

int main(void)
{int / int [5]; < br *> int * const pointer =(int *)malloc(5 * sizeof(int));
Some programmers treat arrays just like pointers (and some even think that
they''re exactly equivalent). I''m going to demonstrate the differences.

Firstly, let''s assume that we''re working on a platform which has the
following properties:

1) char''s are 8-Bit. ( "char" is synomonous with "byte" ).
A char is _always_ a byte. What you mean is that you are assuming a char
(and therefore also a byte) to be equal to an octet.
2) int''s are 32-Bit. ( sizeof(int) == 4 ).
3) Pointers are 64-Bit. ( sizeof(int*) == 8 ).
First let''s make two declarations:

int main(void)
{
int array[5];

int* const pointer = (int*)malloc( 5 * sizeof(int) );




* Boing *和这里的演示崩溃。


永远不要施放malloc()。没有必要。 void * s可以自由转换为任何对象指针类型的


从不使用malloc()(或任何其他函数) />
范围内的适当声明。它强制你的编译器假设

函数返回一个int,malloc()显然没有。


注意第一个错误隐藏了第二个错误。两个

的组合可能导致垃圾分配给你的指针。


为了方便维护,不是真正的错误,它更多

dabble-proof使用sizeof *指针而不是sizeof(type)。如果你的

指针的类型发生了变化,第一个表格保持正确,第二个表格可能会被欺骗性地(并且隐藏!)打破。

总而言之,该程序应该是这样的:


#include< stdlib.h>


int main(void)

{

int array [5];


int * const pointer = malloc(5 * sizeof *指针);

}


无论如何,指针和数组之间的差异最简单是使用年龄来证明[b $ b] 1] - 箭头和方框组合的方法。


Richard


[1]也就是说,在计算机世界中,有几个几十年



*Boing* and here the demonstration crashes.

Never cast malloc(). It is not necessary. void *s can be freely
converted to and from any object pointer type.
Never use malloc() (or any other function, for that matter) without a
proper declaration in scope. It forces your compiler to assume that the
function returns an int, which malloc() clearly does not.

Note that the first error hides the second. The combination of the two
can result in garbage being assigned to your pointer.

As a matter of convenient maintenance, not a true error, it is more
dabble-proof to use sizeof *pointer rather than sizeof (type). If your
pointer''s type changes, the first form stays correct, the second can
turn deceptively (and hiddenly!) broken.

All in all, that program should''ve looked like this:

#include <stdlib.h>

int main(void)
{
int array[5];

int* const pointer = malloc(5 * sizeof *pointer);
}

Anyway, the difference between pointers and arrays is most simply
demonstrated using the age[1]-old method of arrows and groups of boxes.

Richard

[1] I.e., in the computing world, a couple of decades


Tomás写道:
Tomás wrote:
一些程序员将数组视为指针(有些甚至认为它们是'/' '完全相同)。我将展示差异。
Some programmers treat arrays just like pointers (and some even think that
they''re exactly equivalent). I''m going to demonstrate the differences.




有些日子你还可以写一篇文章,证明整数

类型不是浮点类型。这将是人类进步的另一个伟大贡献




-

Salu2

Inviato da X-Privat.Org - Registrazione gratuita http:/ /www.x-privat.org/join.php


为方便维护,不是真正的错误,使用sizeof *指针而不是sizeof(类型)更能防止漏洞。如果你的指针的类型发生了变化,那么第一种形式就会保持正确,第二种形式会被欺骗性地(并且隐藏地!)打破。

总而言之,那个程序应该'看起来像这样:

int main(void)
{int / int int [5] ;

int * const pointer = malloc(5 * sizeof * pointer);


无论如何,指针和数组之间的区别最简单
使用箭头和盒子组的年龄[1] - 方法展示。

理查德

[1]即,在计算机世界,几十年
As a matter of convenient maintenance, not a true error, it is more
dabble-proof to use sizeof *pointer rather than sizeof (type). If your
pointer''s type changes, the first form stays correct, the second can
turn deceptively (and hiddenly!) broken.

All in all, that program should''ve looked like this:

#include <stdlib.h>

int main(void)
{
int array[5];

int* const pointer = malloc(5 * sizeof *pointer);
}

Anyway, the difference between pointers and arrays is most simply
demonstrated using the age[1]-old method of arrows and groups of boxes.

Richard

[1] I.e., in the computing world, a couple of decades




好​​的,我可能错过了这个。但是说我有以下内容:


/ *我省略了检查NULL和使用免费* /


#include< stdio.h> ;

#include< stdlib.h>


int main(void){

int array [5];


int * q = malloc(sizeof * array);


返回0;

}

现在,我改变了

int array [5];





double array [ 5];


这两个sizeof是不是会被截断为sizeof int?如果是这样,

这不会造成额外的错误吗?


Chad



Okay, I''m probably missing this. But say I have the following:

/*I omitted checking for NULL and using free*/

#include <stdio.h>
#include <stdlib.h>

int main(void) {
int array[5];

int *q = malloc(sizeof *array);

return 0;
}
Now, I change
int array[5];

to

double array[5];

Wouldn''t the sizeof double be truncated to the sizeof int? If so, the
wouldn''t this create an additional bug?

Chad

这篇关于数组和指针教程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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