0%

10-参数_返回值_局部变量_数组

参数返回值局部变量_数组

  1. 本机尺寸:如果本机是32位的,那么对32位的数据支持最好,如果是64位的,那么对64位的支持最好.
  2. 编译器遵守了这个规则:char类型或者short类型的参数不但没有节省空间,反而浪费了多余的操作.

结论:整数类型的参数,一律使用int类型

参数传递的本质:将上层函数的变量,或者表达式的值“复制一份”,传递给下层函数.

  1. 小于32位的局部变量,空间在分配时,按32位分配.
  2. 使用时按实际的宽度使用.
  3. 不要定义char/short类型的局部变量.
  4. 参数与局部变量没有本质区别,都是局部变量,都在栈中分配.
  5. 完全可以把参数当初局部变量使用

赋值的本质: 将某个值存储到变量中的过程就是赋值.

练习题

  1. 返回值超过32位时,存在哪里?用long long(__int64)类型做实验

  2. char arr[3] = {1,2,3};与 char arr[4] = {1,2,3,4};哪个更节省空间,从反汇编的角度来说明你的观点

  3. 找出下面赋值过程的反汇编代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void Function()
    {
    int x = 1;
    int y = 2;
    int r;
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};

    r = arr[1];
    r = arr[x];
    r = arr[x+y];
    r = arr[x*2+y];
    }
  1. 选做题: 桶排序,学校c语言老师教过了,不搞了

第一题解答

高位存在edx, 低位存在eax里

实验证明

c语言代码:

1
2
3
4
5
6
7
8
9
10
11
__int64 test()
{
__int64 x = 0x1234567890;
return x;
}

int main(int argc, char* argv[])
{
test();
return 0;
}

汇编代码:

第二题解答

char arr[4] = {1,2,3,4};更节省空间,因为char arr[3]虽然只用了三个空间,而实际还是占用一个单元,4个字节,剩余的一个字节不会被使用,浪费了

第三题解答

1
2
# int x =1;
mov dword ptr [ebp-4],1
1
2
# int y=2;
mov dword ptr [ebp-8],2
1
2
3
4
5
6
7
8
9
10
11
# int arr[10] = {1,2,3,4,5,6,7,8,9,10};
mov dword ptr [ebp-34h],1
mov dword ptr [ebp-30h],2
mov dword ptr [ebp-2Ch],3
mov dword ptr [ebp-28h],4
mov dword ptr [ebp-24h],5
mov dword ptr [ebp-20h],6
mov dword ptr [ebp-1Ch],7
mov dword ptr [ebp-18h],8
mov dword ptr [ebp-14h],9
mov dword ptr [ebp-10h],0Ah
1
2
3
# r = arr[1];
mov eax,dword ptr [ebp-30h]
mov dword ptr [ebp-0Ch],eax
1
2
3
4
# r = arr[x];
mov ecx,dword ptr [ebp-4]
mov edx,dword ptr [ebp+ecx*4-34h]
mov dword ptr [ebp-0Ch],edx
1
2
3
4
5
#r = arr[x+y];
0041073C mov eax,dword ptr [ebp-4]
0041073F add eax,dword ptr [ebp-8]
00410742 mov ecx,dword ptr [ebp+eax*4-34h]
00410746 mov dword ptr [ebp-0Ch],ecx
1
2
3
4
5
6
# r = arr[x*2+y];
00410749 mov edx,dword ptr [ebp-4]
0041074C mov eax,dword ptr [ebp-8]
0041074F lea ecx,[eax+edx*2]
00410752 mov edx,dword ptr [ebp+ecx*4-34h]
00410756 mov dword ptr [ebp-0Ch],edx

对比分析结果:

  1. 越先定义的越靠近栈底
  2. 数组寻址,如果是一个常量,他直接通过ebp-几完成
  3. 数组寻址,如果是一个变量,他通过计算这个变量的值后,通过[ebp-34+变量值*4]寻址,解释,ebp-34是数组的第一个元素地址,而 *4是因为这是int型数组,一个int占4个字节

多维数组

多维数组跟一维数组在内存中是一样的

练习

  1. 假设现在有5个班,每个班10个人,设计一个二维数组存储这些人的年龄.
  2. 如果想知道第二个班的第6个人的年龄,应该如何获取?编译器该如何获取?
  3. 打印所有班级,所有学生的年龄(每个班级打印一行).
  4. 将第二个班级的超过20岁的学生的年龄修改为21岁.
  5. 打印出每个班级学生的年龄的和.
  6. 数组一:[3,5,7,9,12,25,34,55] 数组二:[4,7,9,11,13,16] 将两个数组中所有数据进行从小到大的排序,存储到另一个数组中.

解答

1-5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
int age[5][10] = 
{
{1,2,3,4,5,6,7,8,9,10},
{1,21,22,23,5,6,7,8,9,10},
{1,2,3,4,5,6,7,8,9,10},
{1,2,3,4,5,6,7,8,9,10},
{1,2,3,4,5,6,7,8,9,10}
};

void Printf(int array[][10], int num, int per)
{
for(int i=0; i< num; i++) //class
{
for(int j=0; j<per; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
}

void setAge(int array[][10], int age)
{
for(int j=0; j<10; j++)
{
if(array[1][j] > 20)
array[1][j] = 21;
}
}

void getAverage(int array[][10], int num, int per)
{
for(int i=0; i< num; i++) //class
{
int average=0;
for(int j=0; j<per; j++)
{
average += array[i][j];
}
printf("%d班:%d\n", i, average/per);
}
}
int main(int argc, char* argv[])
{
int a = age[1][5]; // age[1*10*4 + 5*4 ]
Printf(age, 5, 10);
printf("\n");
setAge(age, 20);
Printf(age, 5, 10);
printf("\n");
getAverage(age, 5, 10);

return 0;
}

6 严格意义并不算归并排序,这里已经有序了,所以只是归并排序的一部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
int array2[8]={3,5,7,9,12,25,34,55};
int array1[6]={4,7,9,11,13,16};

int main(int argc, char* argv[])
{
int result[14];
int *p = array1;
int *k = array2;
int i=0;
while(i < 14)
{
if(*p > *k)
{
if(*k)
{
result[i] = *k;
k++;
}
else
{
result[i] = *p;
p++;
}
}
else
{
if(*p)
{
result[i] = *p;
p++;
}
else
{
result[i] = *k;
k++;
}

}
i++;
}
for(i=0; i < 14; i++)
{
printf("%d ", result[i]);
}

return 0;
}

本文作者:NoOne
本文地址https://noonegroup.xyz/posts/8f78d50e/
版权声明:转载请注明出处!