首先,不要掉头.。 。 除非您的汇编者文件具体指出,它支持<条码>,避免主(<>/代码>,使用<条码>,主要(不含)条码>或<条码>。
现在让我回下一分钟,谈谈点人和阵列之间的分歧。 首先要记住的是,阵列和点号是完全不同的东西。 你可能已经听到或读过一个阵列只是一个点;这是不正确的。 在多数情况下,一个阵列expression的型号将从“T”的“N-element range of T”改为“pointer to T”(至某一点类型)及其价值设定为阵列中第一件事时,其例外情形是,阵列的表述是sizeof
或地址(&
)的操作者,或阵列是用来确定另一阵列的直径。
阵列是保存T型N元件的记忆块;一个点子是保存T型单一价值的地址的顶点。 您不能给一阵标分配新的价值,即不允许:
int a[10], b[10];
a = b;
注:体字面(如“aaa”)也是阵列;类型为N-element阵列(C++的座标),N为护str的长度,加之0。 字面固定;在方案启动时分配,在方案退出之前就存在。 这些规定也是不可调和的(试图修改说明字面的内容,导致不明确的行为)。 例如,“aaa”一词的类型是静态的4个lement体。 与其他阵列一样,在多数情形下,字面从阵列类型到点式类型。 当你写文章时,你就写了类似的东西。
char *p = "aaa";
阵列“aa” decays from char [4]
to char *
,其价值为首个阵列的地址;address随即抄到p
。
但是,如果使用字面来初步确定一系列的果园:
char a[] = "aaa";
那么,这种类型没有转换;字面仍然作为阵列处理,阵列的contents被复制到a
(和a
被含蓄地大小,以掌握插图内容和0 决定因素)。 结果大致相当于写作
char a[4];
strcpy(a, "aaa");
当一系列类型的<代码>T a[N]是sizeof
的操作者时,结果就是整个阵列的规模:N*(T)大小。 当操作地址(&
)操作者操作时,结果就是整个阵列的指向者,而不是第一个要素的指点(在实践中,这些要素是相同的 Value,但类型不同):
Declaration: T a[N];
Expression Type "Decays" to Value
---------- ---- ----------- ------
a T [N] T * address of a[0]
&a T (*)[N] address of a
sizeof a size_t number of bytes in a
(N * sizeof(T))
a[i] T value of a[i]
&a[i] T * address of a[i]
sizeof a[i] size_t number of bytes in a[i] (sizeof (T))
请注意,阵列的表述<代码>a decays to category T*
,或点至T。 这与以下表述相同:<代码>&a[0]。 这两种表述都产生了阵列中第一个要素的论述。 The expression &a
is of category T (*)[N]
, or pointer to N-element range of T, and it produceds the address of the/2008/3 within, not the first content. 由于阵列的地址与阵列第1部分的地址相同,a
,&a[0]
和&a[0]
均产生相同的 /em>,但表达方式并非全部相同 bet>。 在试图将职能定义与职能要求相匹配时,这一点很重要。 如果您希望通过array<>,作为职能的一个参数,如:
int a[10];
...
foo(a);
因此,相应的职能定义必须相应地确定。
void foo(int *p) { ... }
收到的<条码>foo条码>是暗中点,而不是一阵列。 请注意,您可以将其称作foo(a)
或foo(&a[0]
(或甚至foo(&v)
,其中v
是一个简单的内变量,尽管foo
正在预计会出现引起问题的阵列。 请注意,就职能参数声明而言,int a[]
与int *a
相同,但仅为<> /em>在此种情况下适用。 坦率地说,我想int a[ ]
form负责对点人、阵列和职能进行大量混淆的思考,不应加以使用。
如果您希望通过点至阵列,以履行职务,例如:
int a[10];
foo(&a);
因此,相应的职能定义必须相应地确定。
void foo(int (*p)[10]) {...}
以及当你想提及某一具体内容时,你必须参照点名 <> <> >。 适用本说明:
for (i = 0; i < 10; i++)
(*p)[i] = i * i;
现在请把key子扔进工程中,并给工程阵列增加第二面:
Declaration: T a[M][N];
Expression Type "Decays" to Value
---------- ---- ----------- ------
a T [M][N] T (*)[N] address of a[0]
&a T (*)[M][N] address of a
sizeof a size_t number of bytes in a (M * N * sizeof(T))
a[i] T [N] T * address of a[i][0]
&a[i] T (*)[N] address of a[i]
sizeof a[i] size_t number of bytes in a[i] (N * sizeof(T))
a[i][j] T value of a[i][j]
&a[i][j] T * address of a[i][j]
请注意,在这种情况下,a <>/code>和a [i]
都是阵容表示,因此,它们各自的阵列类型在多数情况下将降至点类型;a
将从“M-element range of N-element range of T”类改为“pointer to N-element range of T”,将从“N-element range of T”改为“pointer to T”。 并且,<代码>a
,&a
a[0],&a[0]
, 和&a[0][0]
将产生相同的 Values。 (阵列开始的地址),但并非全部相同的 类型。 如果你想通过一个2个阵列来履行以下职能:
int a[10][20];
foo(a);
因此,相应的职能定义必须相应地确定。
void foo(int (*p)[20]) {...}
通知说,这同向1个阵列传递一个点(除了例子中阵列的规模不同外)。 然而,在这种情况下,你将像点人一样,对点人适用一个子则。
for (i = 0; i < 10; i++)
for (j = 0; j < 20; j++)
p[i][j] = i * j;
在此情况下,你不必明确引用<条码>p,因为<条码>p[i]隐含着的推论(p[i]=*(p+ i)
。
现在请看一下更重要的表述:
Declaration: T *p;
Expression Type Value
---------- ---- ------
p T * address of another object of type T
*p T value of another object of type T
&p T ** address of the pointer
sizeof p size_t number of bytes in pointer (depends on type and platform,
anywhere between 4 and 8 on common desktop architectures)
sizeof *p size_t number of bytes in T
sizeof &p size_t number of bytes in pointer to pointer (again, depends
on type and platform)
这完全是直截了当的。 标识类型包含另一个类型T的地址;参照点码(*p
)产生该地址的价值,并采用点码(&p
)的地址。 产生点物体的位置(点至点)。 将<>条码/代码>适用于点值,将产生点名中的tes数,而不是点人指出的 by数。
现在,假定你已经这样做了,但幸运的是死去了。
您希望创建“array号”点子,以三个字面字标示和开标,以便你宣布为
char *list[] = {"aaa", "bbb", "ccc"};
>>>>>>>。
您通过<条码>条码>,以履行职务,如:
foo(list);
(char * [4]
) to “pointer to pointer to char” (char **
), 因此,接收功能必须具有对接收功能的定义。
void foo(char **p) {...}
由于子描述是根据点算法界定的,你可以使用点码操作器as [,它是一系列<代码>char*:
for (i = 0; i < 3; i++)
printf("%s
", p[i]);
顺便提一句,这就是:main
receive argv
, as a pointer to char (char **
), not as an range of pointer to char. 在职能参数申报方面,a[]
与*/code>相同,因此,char*argv[]
与 **argv
相同。
现在,因为我似乎无法在上打字,回到工作。 (打破僵局是而不是),请利用点人和有活力地分配记忆。
如果你想在一段时间内积极分配你的名单(即,你掌握了在你名单上的多少处方),你将宣布<条码>为名单<<>>为点子,然后打电话<条码>小孔<>>,以实际分配记忆:
char **list;
size_t number_of_strings;
...
list = malloc(number_of_strings * sizeof *list);
list[0] = "aaa";
list[1] = "bbb";
list[2] = "ccc";
...
由于这些是任务,而不是初步确定,字面上的表述向点人转折,因此,我们将“aaa”、“bbb”的addresses/em>复制到list>/code>的条目。 在这种情况下,list
是not一个阵列类型;它只是一个点到另一个地方(在这种情况下,从小得)分配的记忆库。 再者,由于阵列说明是根据点算法界定的,你可以将子描述操作者应用到点值,因为“list [i]
为char*>。 不存在任何隐性转换成担忧;如果你将它变成一项职能的话。
foo(list)
然后,职能定义将是
void foo(char **list) {...}
页: 1
pssst... 是他做的?>
Yeah,我认为他做了。