生成三维数组生成不太明白,之后生成之后和索引值的代码连不起来
#include <stdio.h>
#include <stdlib.h>
int main() {
// 生成一个3x4x5的三维数组
int ***array_3d;
int i, j, k;
array_3d = (int ***) malloc(3 * sizeof(int **));
for (i = 0; i < 3; i++) {
array_3d[i] = (int **) malloc(4 * sizeof(int *));
for (j = 0; j < 4; j++) {
array_3d[i][j] = (int *) malloc(5 * sizeof(int));
for (k = 0; k < 5; k++) {
array_3d[i][j][k] = i + j + k;
}
}
}
// 输入索引值,获取对应的数组
i = 1;
j = 2;
k = 3;
int sub_array = array_3d[i][j][k];
printf("%d\n", sub_array); // 输出为整数值
// 释放动态内存
for (i = 0; i < 3; i++) {
for (j = 0; j < 4; j++) {
free(array_3d[i][j]);
}
free(array_3d[i]);
}
free(array_3d);
return 0;
}
在上面的示例代码中,首先使用 malloc 函数动态分配了一个3维数组,然后使用3个 for 循环遍历了整个数组,并将每个元素设置为其索引值之和。要查找特定索引处的数组,只需使用方括号运算符访问相应的元素即可。在上面的示例中,sub_array 存储了 array_3d 中位置为 (1, 2, 3) 的元素。最后,使用 free 函数释放了动态分配的内存,以避免内存泄漏。
C语言规定,int在内存中的最高位为符号位,0~30 位表示数值,31 位表示正负号。当然,如果明确数据的范围是正数,C语言也提供了无符号数,即只能表达正数范围的整数。无符号数没有符号位,相当于32位都是表示数值,所以无符号数表示正数的范围是有符号数的两倍。
加减法是最基本的运算,所以在计算机中直接由硬件提供,所以硬件的设计要尽量简单。有符号数因为有符号位,计算机要专门识别符号位和数值位,无疑加大了硬件电路的复杂度,所以,人们想出了两个优化目标:
1.让符号位也参与运算,简化电路
2.加法和减法统一
那如何优化呢?这要先从几个概念说起~
原码:
将一个整数转换成二进制形式,就是其原码。例如short a = 7;,a 的原码就是0000 0000 0000 0111。
通俗的理解,原码就是一个整数本来的二进制形式。
反码:
对于正数,它的反码就是其原码(原码和反码相同);负数的反码是将原码中除符号位以外的所有位(数值 位)取反,也就是 0 变成 1,1 变成 0。例如short a = 6;,a 的原码和反码都是0000 0000 0000 0110;更改 a 的值a = -18;,此时 a 的反码是1111 1111 1110 1101。
补码:
对于正数,它的补码就是其原码(原码、反码、补码都相同)。负数的补码是其反码加 1。例如short a = 6;,a 的原码、反码、补码都是0000 0000 0000 0110;更改 a 的值a = -18;,此时 a 的补码是1111 1111 1110 1110。
原码、反码、补码的概念只对负数有实际意义,对于正数,它们都一样。
所以,将整数写入计算机内存,会将原码转化为补码,读取整数的时候,会将补码转化为原码。
(以下为了方便,整数的表示使用1-2个字节表示)
如果要让符号位也参与运算,并且加法和减法统一,正数直接使用原码是没有问题的,但是如何有负数,就不正确了,例如:
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
显然是错误的。
为了解决原码做减法的问题, 出现了反码:
计算十进制的表达式: 1-1=0
1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
是不是反码就可以解决问题了呢?看下面例子:
13 - 5 = 13 + (-5)
= [0000 0000 0000 1101]原 + [1000 0000 0000 0101]原
= [0000 0000 0000 1101]反 + [1111 1111 1111 1010]反
= [1 0000 0000 0000 0111]反
= [0000 0000 0000 0111]反
= [0000 0000 0000 0111]原
= 7
显然是错的。但是5-13使用反码的计算结果是正确的,这个读者可以自行验证~~
上面的例子,其实是为了说明使用反码计算的两个明显的问题:
为了解决以上两个问题,勤劳勇敢更聪明的计算机设计者们设计出了补码。
使用补码计算13-5:
13 - 5 = 13 + (-5)
= [0000 0000 0000 1101]补 + [1111 1111 1111 1011]补
= [1 0000 0000 0000 1000]补
= [0000 0000 0000 1000]补
= [0000 0000 0000 1000]反
= [0000 0000 0000 1000]原
= 8
结果就是正确的了。为什么呢?
补码其实就是反码加1(针对负数而言),绝对值大的数减去绝对值小的数,结果为正数,整个过程负数反码转为补码只有一次(被减数转为补码),所以就是相当于反码计算的结果加1,。而绝对值小的数坚绝对值大的数,结果为负数,整个过程负数反码转为补码有1次,补码转为原码1次(1.被减数转为补码 2.结果补码转为元原码),相当于和直接使用反码计算的结果一样。
补码的出现, 还解决了0的符号以及两个编码的问题:
1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原
这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128。(但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示)
使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数。这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].
我可以为您解答生成三维数组及找到对应索引值的问题。
生成三维数组:
#define ROW 3
#define COL 4
#define LAYER 5
int arr[ROW][COL][LAYER];
这样就生成了一个3维数组,可以根据需要修改ROW、COL、LAYER即可。
找到对应索引值的三维数组元素,可以使用下标访问方式,例如:
int index1 = 0, index2 = 1, index3 = 2;
int value = arr[index1][index2][index3];
这样就能得到对应索引值的三维数组元素。
如果还需要在生成过程中给三维数组赋值,可以使用双重循环进行赋值,例如:
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
for (int k = 0; k < LAYER; k++) {
arr[i][j][k] = i * 100 + j * 10 + k; //示例赋值方式
}
}
}
以上是三维数组的基本操作,希望能对您有所帮助。