2)下标总是与指针的偏移量相同;
C语言中,把数组下标作为指针的偏移量。根本原因是指针和偏移量是底层硬件所使用的基本模型。
3)在函数参数的声明中,数组名被编译器当作指向该数组第一个元素的指针;
理解这句话首先要明白形参和实参的区别,
术语 定义 例子
形参(parameter) 它是一个变量,在函数定义或者函数声明的原型中定义。又称“形式参数(formal parameter)” int power(int base,int n);
base 和 n 都是形参
实参(argument) 在实际调用一个函数时所传递给函数的值。又称“实际参数(actual parameter)” i = power(10,j);
10和j都是实参。
在函数参数这种特殊情况下,编译器必须把数组名当作指向该数组第一个元素的指针形式。编译器只向函数传递数组的地址,而不是整个数组的拷贝。
(3)数组和指针可交换型总结
a)对于a [i]这种形式的访问数组,通常被解释为指针形式*(a + i) 也就是上文中所说的“表达式”的情形
b)指针就是指针,没有说指针转化为数组的情况,你可以用下标的形式去访问指针,但一般都是指针作为函数参数时,而且传入的是一个数组
c)在函数参数的声明中,数组可以看做指针,(也只有这种情况)
d)当把一个数组定义为函数参数时,可以定义为数组,也可以是指针
e)其他的所有情况,声明和定义必须匹配。如果定义了一个数组,在其他文件中对它也必须声明为数组。指针也一样。
(4)数组和指针参数是如何被编译器修改的
看到文章这里,可以说是到一个结束段落了,你基本理解了数组和指针的不同和相同,学习更多知识需要自己的实践操作!!!哦,忘了还有对引文中问题的解答,看下第四部分吧。
上部分中提到编译器对数组到指针的修改,所以这里补充一点东西。
“数组名被改写成一个指针参数”规则不是递归定义的。就是说数组的数组会被改写成“数组的指针”,而不是“指针的指针”。
实参
所匹配的形式参数
数组的数组 char c[8][10]; char(*)[10]; 数组指针
指针数组 char *c[15]; char **c; 指针的指针
数组指针(行指针) char (*c)[64]; char (*c)[64]; 不改变
指针的指针 char **c; char **c; 不改变
4 对引文中问题的解答
这里我们在内存中方式的不同来看这个问题。查看其汇编代码答案就一目了然了。
第一个程序:整型变量的
1: #include
1: 2212: main(){ 2: 00401000 push ebp 3: 00401001 mov ebp,esp 4: 00401003 sub esp,44h 5: 00401006 push ebx 6: 00401007 push esi 7: 00401008 push edi 8: 2213: int int_input; 9: 2214: cin>>int_input; 10: 00401009 lea eax,[ebp-4] 11: 0040100C push eax 12: 0040100D mov ecx,offset cin (00414c58) 13: 00401012 call istream::operator>> (0040b7c0) 14: 2215: cout<<(int_input+4)<
1: #include
2: int main(){ 3:
int *int_ptr = new int[1];
4: cin>>*int_ptr;
5: cout<< (*int_ptr + 4)<
7: return 0;
8: }汇编程序:
1: 2212: main(){ 2: 00401000 push
ebp 3: 00401001 mov
ebp,esp 4: 00401003 sub
esp,4Ch 5: 00401006 push
ebx 6: 00401007 push
esi 7: 00401008 push
edi 8: 2213:
int *int_ptr = new int[1];
9: 00401009 push
4 10: 0040100B call
operator new (004011b0)
11: 00401010 add
esp,4 12: 00401013 mov
dword ptr [ebp-8],eax
13: 00401016 mov
eax,dword ptr [ebp-8]
14: 00401019 mov
dword ptr [ebp-4],eax 15: 2214:
cin>>*int_ptr; 16: 0040101C mov
ecx,dword ptr [ebp-4] 17: 0040101F push
ecx 18: 00401020 mov
ecx,offset cin (00414c38)
19: 00401025 call
istream::operator>> (0040b8a0) 20: 2215:
cout<< (*int_ptr + 4)<
edx,dword ptr [ebp-4] 23: 00401032 mov
eax,dword ptr [edx] 24: 00401034 add
eax,4 25: 00401037 push
eax 26: 00401038 mov
ecx,offset cout (00414bf8) 27: 0040103D call
ostream::operator<< (0040b4c0) 28: 00401042 mov
ecx,eax 29: 00401044 call
ostream::operator<< (00401070) 30: 2216:
delete(int_ptr); 31: 00401049 mov
ecx,dword ptr [ebp-4] 32: 0040104C mov
dword ptr [ebp-0Ch],ecx 33: 00