- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在学习c语言,练习自己。我想知道 c 如何为数组分配内存。因为我有这样的代码:
#include<stdio.h>
int main(void)
{
char a[] = {1,2,3,4,5,6,7,8,9,10};
int i = 578;
char * p1;
int * p2;
printf("\nAddress of pointer p1 : %p", &p1);
printf("\nAddress of pointer p2 : %p", &p2);
printf("\nAddress of int i : %p", &i);
p1 = 0x0028FF34;
p2 = 0x0028FF35;
/* Print the Addresses */
for (i = 0; i < 10; i++)
{
printf("\nAddress of a[%d] : %p", i, (void *) &a[i]);
}
printf("\nThe content in the address 0x0028FF34: %x", *p1);
printf("\nThe content in the address 0x0028FF35: %x", *p2);
return 0;
}
在我的计算机上运行此代码会得到如下输出
Address of pointer p1 : 0028FF2C
Address of pointer p2 : 0028FF28
Address of int i : 0028FF30
Address of a[0] : 0028FF36
Address of a[1] : 0028FF37
Address of a[2] : 0028FF38
Address of a[3] : 0028FF39
Address of a[4] : 0028FF3A
Address of a[5] : 0028FF3B
Address of a[6] : 0028FF3C
Address of a[7] : 0028FF3D
Address of a[8] : 0028FF3E
Address of a[9] : 0028FF3F
The character content in the addresss 0x0028FF34: ffffff80
The character content in the addresss 0x0028FF35: 3020100
字符指针p占32位,即4个字节。因此,指针 p2 到指针 p1 的距离是 4 个字节长,指针 p1 到 int i 的距离也是如此。在我的系统中 int i 也是 4 个字节。在我看来,int i 与数组 a[] 的距离应该是 4 个字节。数组a[]的起始地址应该是0028FF34,为什么是0028FF36?
0028FF34和0028FF35的内容是什么意思? 0028FF34 指向一个字符,输出为 ffffff80,0028ff35 指向一个 int,输出为 3020100。
最佳答案
您想知道 C 如何为数组和其他数据类型分配内存。好的。嗯,这取决于数组(或其他变量)的定义方式。在您的例子中,您已将它们定义为自动分配的(“本地”)变量,因此它们存储在 C 运行时堆栈中。 (从技术上讲,可以有另一种自动存储变量的分配机制,但实际上大多数系统都使用运行时堆栈。)如果您在 int main(void) 上面的几行中定义了数组和其他变量
code>,它们将是“全局变量”,并且将通过外部链接静态分配,因此它们对其他编译单元(其他 .c 文件)可见。如果将关键字static
放在它们前面,它们仍然会被静态分配,但它们的链接将是内部的,因此它们对其他编译单元(.c 文件)不可见。无论您在函数体内部还是外部定义变量,最后一部分都是如此;如果您在函数体外部将它们定义为static
,则它们可供同一编译单元中的其他函数使用;如果您在函数体内将它们定义为static
,则编译器只允许该函数访问它们;事实上,它们仅在定义它们的范围内可见。
至于它们的具体放置位置,编译器/链接器可以自由地将它们放置在其选择的存储类区域内的任何位置;在这种情况下,编译器将它们放置在运行时堆栈上,但它们的顺序和相对位置不是由语言定义的,因此编译器可以自由地以任何它喜欢的方式排列它们。
通常会在变量之间分配填充,以确保它们对齐,以便它们从数据大小的最佳边界开始,因为(由于硬件问题)在与其匹配的字节边界上访问数据通常会更快数据宽度,这正是这里发生的情况。您可能会说,“但是 i
以 4 字节边界结束,并且 a[]
没有对齐要求,那为什么要在 i 之后添加填充呢?
在分配a[]
之前?”但这是因为您正在考虑按内存地址递增的顺序进行分配。您是否注意到您的变量似乎是“向后”分配在内存中的?事实上他们不是!在大多数系统上,堆栈在内存中从高地址向低地址增长。考虑到这一点,很明显,分配的变量集中的第一个变量是 a[]
,后面是 i
(位于较低的地址)。因为a[]
后面的字节地址不是4的倍数,所以编译器在分配i
之前,添加了2个字节的填充!
现在,至于您在 0x0028FF34 和 0x0028FF35 处读取的值:无论是什么,都只是上次写入这些地址的内容留下的垃圾。 0x0028FF34 处的字节是 0x80,它通过 ...
varargs 作为整数传递给 'printf()',并且在您的系统上 char
必须经过签名,因此当它被提升为经过符号扩展的整数,并且由于 0x80 的高位为 1,因此结果值为 0xFFFFFF80。您读取的整数 0x0028FF35 显示该地址处的字节是 0x00,其他字节是 03、02 和 01,您应该注意到它们是 a[]
的前 3 个字节。我们还可以从中看出您的系统是小尾数法(如 x86),因为整数的高位字节位于较高字节可寻址位置。
关于c - c语言在内存中存储数组的机制是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58456339/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!