Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C s1与&;s1及;s1.a(结构)_C_Structure - Fatal编程技术网

C s1与&;s1及;s1.a(结构)

C s1与&;s1及;s1.a(结构),c,structure,C,Structure,当不与运算符一起使用时,结构变量包含什么 康涅斯特程序 #include<stdio.h> typedef struct{ char a; int b; } scratch; int main(){ scratch s1 = {2,4}; printf("%p",s1); o/p 000566000 printf(" %p",&s1); o/p 00000420 printf(" %p",&s1

当不与
运算符一起使用时,结构变量包含什么

康涅斯特程序

#include<stdio.h>
typedef struct{
          char a;
          int b;
        } scratch;

int main(){
  scratch s1 = {2,4};
  printf("%p",s1); o/p 000566000
  printf(" %p",&s1); o/p 00000420
  printf(" %p",&s1.a); o/p 00000420
  return 0;
}
#包括
类型定义结构{
字符a;
int b;
}刮擦;
int main(){
划痕s1={2,4};
打印件(“%p”,s1);o/p 000566000
printf(“%p”和&s1);o/p 00000420
printf(“%p”,&s1.a);o/p 00000420
返回0;
}
sturct变量
s1
及其第一个成员
s1.a
在与
一起使用时都返回相同的地址,但
s1
返回一些其他值。这是垃圾还是什么

结构s1包含什么?(当我使用oops语言执行此操作时,对象变量打印一些与java相关的地址,java中没有地址运算符)

有人能告诉我s1在这里干什么吗?或者仅仅是编译器问题?

这:

printf("%p",s1);
是无效的,可能是未定义的行为。格式说明符%p与结构不兼容。如果启用警告,GCC会告诉您:

format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘scratch’ [-Wformat]

您所有的
printf
语句都是非法的

printf中(“%p”,s1)void*
时,传递code>type
scratch
。这会导致未定义的行为

printf中(“%p”和&s1)void*
时,将传递code>type
scratch*
。这会导致未定义的行为。使用
printf(“%p”,(void*)&s1)取而代之

printf中(“%p”、&s1.a)void*
时,传递code>type
char*
。这会导致未定义的行为。使用printf(“%p”,(void*)和s1.a)

关于
printf(“%p”,s1)-它是一个垃圾值,因为它(结构)与格式说明符
%p
不兼容,因为它不是指针-它与编译器无关-它与函数
printf()
和varargs的行为有关-请注意,当您只键入
printf(“%d”)时
它将打印一个值,一个当时在堆栈内存中找到的随机值-
printf()
认为您传输了两个参数,一个格式字符串和一个与格式说明符匹配的值,所以他使用varargs来提取变量(这显然不存在,因为我们没有传输它)它提取了一个随机的垃圾值。关于
s1
s1.a
具有相同的地址-这是因为整数
a
是结构
scratch
中的第一个变量,因此当您请求
a
的地址时,您请求它开始的第一个字节(尽管这里是
char
,所以它只是一个字节),结构本身(作为结构)不会消耗一些额外的内存,因此
s1
s1.a
具有相同的地址,因为
s1.a
实际上是结构的第一个字节。

&s1是s1的地址。 &s1.a是s1.a的地址,与s1的地址相同,因为“a”是结构的第一个元素


现在,“%p”用于打印指针地址。s1是结构实例,不是地址,因此不应使用“%p”打印。是否确定此处的输出正确

printf("%p",s1) 
将取s1的值(即它表示的字节,具体取决于编译它的方式和目标机器体系结构),并将其视为指针。它在任何情况下都会生成编译器警告-

test.c:10:15: warning: format specifies type 'void *' but the argument has type 'scratch' [-Wformat]
对于未打包的结构,一个字符将占用4个字节(在大多数系统上,由实现定义)。结构布置如下所示

因此,s1内存中的布局是(在小端系统上) 0x02(字符)0x000000(3字节填充)0x04000000(整数)

如果您在64位little endian系统(64位指针)上打印出来,它将需要8个字节的指针地址,最小的字优先

因此,它将打印出来 0x400000002-在大多数现代系统上,如果填充字节初始化为零,或者堆栈恰好包含零。如果堆栈不包含零,则4到2之间的字节可能包含任何内容


当您打印出s1(&s1)或s1.a(&s1.a)的地址时,您打印出的是它们存储的实际内存地址,在这两种情况下都是相同的。这是正确的做法。

你的第一段主要是错的,这将使你很难回答这个问题。C没有“类”,一般来说,一个对象是在“堆栈”上分配还是在“堆”上分配取决于它的类型是如何定义的。不,类成员不是在“堆”上分配的。我说的是“对象是在“堆栈”上分配还是在“堆”上分配取决于它的类型是如何定义的”。你知道你把你的问题标记为C而不是Java吗?@user3205479你的代码是C。你标记了你的问题C。你在询问操作符的地址。然后你突然开始谈论java?有意思。你真的毫无意义。我在这里完成了。问题仍然是,当您将
s1
放在堆栈上调用
printf()
时,C编译器会做什么。它会复制结构吗?是的,它会复制结构。printf将不正确地使用它,调用未定义的行为。它不一定是copy。有些编译器在堆栈上进行复制,并在后台传递该副本的地址。它是合法的,只要它表面上看起来像是传递价值。请记住,C标准甚至不需要堆栈,所以幕后发生的是实现定义的,这是未定义的行为。任何事情都有可能发生。在我的系统中,我确实看到“指针”的低位字节是2,正如您所期望的那样。但也许你的系统给了你一个不同的未定义的行为。这是允许的。请注意,对于我来说,它的结果类似于
0x42ffa1b02
,而不是
0x02
b