结构数组成员地址问题
structure array member address problems
#include<stdio.h>
struct Book {
char * name;
int page;
};
void demo(struct Book bookArr[]);
int main(){
struct Book bookArr[] = {{"c struct",1},{"c struct",2}};
printf("bookArr address from main: %p\n",&bookArr);
printf("bookArr[0] address from main: %p\n",&bookArr[0]);
demo(bookArr);
return 0;
}
void demo(struct Book bookArr[]){
printf("bookArr address from demo: %p\n",&bookArr);
printf("bookArr[0] address from demo: %p\n",&bookArr[0]);
}
The output:
bookArr address from main: 0x1040bb350
bookArr[0] address from main: 0x1040bb350
bookArr address from demo: 0x1040bb328
bookArr[0] address from demo: 0x1040bb350
Program ended with exit code: 0
demo中的bookArr在启动时复制了main中的bookArr,所以我能理解为什么两个函数的bookArr地址不同,但我不能理解为什么两个函数的bookArr[0]地址相同.演示不是已经分配了完整的 BookKarr 吗? bookArr[0] 和 bookArr[1] 都是指针吗?但事实并非如此
main
函数中的bookArr
是数组
表达式中的大多数数组会自动转换为指向其第一个元素的指针,但一元 &
运算符的操作数是其中的一个例外。
通常情况下,数组的位置及其第一个元素在内存中的地址相同。 (数组中第一个元素之前没有多余的space。)
bookArr[0]
和 bookArr[1]
不是指针而是结构(struct Book`)。
事实上,只有一个 Book 数组存在,并且两个函数都引用同一个数组。但是,每个函数都通过不同的局部变量访问该数组。
在任一函数中,&bookArr
都不是数组开始的地址。它是 局部变量 的地址,它保存指向数组开头的指针。
如果你要打印 bookArr
本身,它本身就是一个指针,你会看到它们都指向相同的内存位置。
对于初学者来说,考虑一个简单的例子:
#include <stdio.h>
void f( int *px )
{
printf( "in f &( *px ) = %p\n", ( void * )&( *px ) );
}
int main(void)
{
int x = 10;
printf( "in main &x = %p\n", ( void * )&x );
f( &x );
return 0;
}
程序输出可能如下所示:
in main &x = 0x7ffccc31de34
in f &( *px ) = 0x7ffccc31de34
也就是说,变量 x 通过指向它的指针通过引用传递给函数 f。
取消引用函数 *px
中的指针,您可以直接访问存储变量 x
的内存。变量 x
本身没有传递给函数。它是指向已传输变量的指针。
因此使用表达式 &( *px )
或 &( px[0] )
或只是 px
你将在 main 中获得原始变量 x 的地址。
当您传递数组时,它会隐式转换为指向其第一个元素的指针。另一方面,具有数组类型的函数参数也被调整为指向数组元素类型的类型指针。
也就是这个函数声明:
void demo(struct Book bookArr[]);
相当于:
void demo(struct Book * bookArr);
所以数组本身并没有被复制到函数中。它是指向传递给函数的第一个元素的指针。
所以参数bookArr的值得到的是数组第一个元素的地址。事实上,参数 bookArr 获取表达式 book &bookArr[0] 的值,其中 bookArr 在 main 中声明。所以实际上在 main 中声明的数组的所有元素都通过引用传递给函数,因为使用指针算法你可以获得数组中每个元素的地址。即bookArr是数组第一个元素的地址 *表达式你也可以这样写 &bookArr[0]), bookArr + 1 是数组第二个元素的地址,依此类推
注意这个调用中的main
printf("bookArr address from main: %p\n",&bookArr);
表达式 &bookArr
没有类型 struct Book *
。它的类型为 struct Book ( * )[2] 因为在 main 中你有一个数组。另一方面,在函数演示中,bookarr 的类型为 struct Book *(由于将参数调整为指向数组元素类型的指针),表达式 &bookArr 的类型为 struct Book **
并产生参数的地址(本地函数的变量)。
#include<stdio.h>
struct Book {
char * name;
int page;
};
void demo(struct Book bookArr[]);
int main(){
struct Book bookArr[] = {{"c struct",1},{"c struct",2}};
printf("bookArr address from main: %p\n",&bookArr);
printf("bookArr[0] address from main: %p\n",&bookArr[0]);
demo(bookArr);
return 0;
}
void demo(struct Book bookArr[]){
printf("bookArr address from demo: %p\n",&bookArr);
printf("bookArr[0] address from demo: %p\n",&bookArr[0]);
}
The output:
bookArr address from main: 0x1040bb350
bookArr[0] address from main: 0x1040bb350
bookArr address from demo: 0x1040bb328
bookArr[0] address from demo: 0x1040bb350
Program ended with exit code: 0
demo中的bookArr在启动时复制了main中的bookArr,所以我能理解为什么两个函数的bookArr地址不同,但我不能理解为什么两个函数的bookArr[0]地址相同.演示不是已经分配了完整的 BookKarr 吗? bookArr[0] 和 bookArr[1] 都是指针吗?但事实并非如此
main
函数中的bookArr
是数组
表达式中的大多数数组会自动转换为指向其第一个元素的指针,但一元 &
运算符的操作数是其中的一个例外。
通常情况下,数组的位置及其第一个元素在内存中的地址相同。 (数组中第一个元素之前没有多余的space。)
bookArr[0]
和 bookArr[1]
不是指针而是结构(struct Book`)。
事实上,只有一个 Book 数组存在,并且两个函数都引用同一个数组。但是,每个函数都通过不同的局部变量访问该数组。
在任一函数中,&bookArr
都不是数组开始的地址。它是 局部变量 的地址,它保存指向数组开头的指针。
如果你要打印 bookArr
本身,它本身就是一个指针,你会看到它们都指向相同的内存位置。
对于初学者来说,考虑一个简单的例子:
#include <stdio.h>
void f( int *px )
{
printf( "in f &( *px ) = %p\n", ( void * )&( *px ) );
}
int main(void)
{
int x = 10;
printf( "in main &x = %p\n", ( void * )&x );
f( &x );
return 0;
}
程序输出可能如下所示:
in main &x = 0x7ffccc31de34
in f &( *px ) = 0x7ffccc31de34
也就是说,变量 x 通过指向它的指针通过引用传递给函数 f。
取消引用函数 *px
中的指针,您可以直接访问存储变量 x
的内存。变量 x
本身没有传递给函数。它是指向已传输变量的指针。
因此使用表达式 &( *px )
或 &( px[0] )
或只是 px
你将在 main 中获得原始变量 x 的地址。
当您传递数组时,它会隐式转换为指向其第一个元素的指针。另一方面,具有数组类型的函数参数也被调整为指向数组元素类型的类型指针。
也就是这个函数声明:
void demo(struct Book bookArr[]);
相当于:
void demo(struct Book * bookArr);
所以数组本身并没有被复制到函数中。它是指向传递给函数的第一个元素的指针。
所以参数bookArr的值得到的是数组第一个元素的地址。事实上,参数 bookArr 获取表达式 book &bookArr[0] 的值,其中 bookArr 在 main 中声明。所以实际上在 main 中声明的数组的所有元素都通过引用传递给函数,因为使用指针算法你可以获得数组中每个元素的地址。即bookArr是数组第一个元素的地址 *表达式你也可以这样写 &bookArr[0]), bookArr + 1 是数组第二个元素的地址,依此类推
注意这个调用中的main
printf("bookArr address from main: %p\n",&bookArr);
表达式 &bookArr
没有类型 struct Book *
。它的类型为 struct Book ( * )[2] 因为在 main 中你有一个数组。另一方面,在函数演示中,bookarr 的类型为 struct Book *(由于将参数调整为指向数组元素类型的指针),表达式 &bookArr 的类型为 struct Book **
并产生参数的地址(本地函数的变量)。