C语言-参数-返回值-局部变量-数组

本文详细探讨了C语言中函数的返回值类型、参数传递机制,以及数组在内存分配和操作中的行为。通过反汇编分析,揭示了数据在堆栈中的存储和传递细节,包括char函数返回值的处理、参数的4字节传输规则,以及数组越界和排序算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言-参数-返回值-局部变量-数组:

返回值

char Funtion(){
    //10000行代码
    return 10;
}
//c语言角度:这里定义的函数类型是char(字符型),表示我将返回的的数据是一个字符型数据
//汇编语言角度:我创建了个函数,函数的返回值是一个字节
int main(){
    char i = Funtion();
    return 0;
}
//因为我们设置的是返回一个字符型返回值,所以对应的用一个字符型变量去接收
对应的反汇编:
call Funtion
		......//保存现场,提升堆栈等
		mov al,0Ah		//0Ah对应的二进制就是10,意思就是向寄存器al中存入10这个数。
		......//恢复现场,恢复堆栈等
mov byte ptr [ebp-4],al

这里的类型可以是任意的,char,short,int.long,long long在计算机看来只是大小不同而已。所以在正向编程的时候,只要不用小的数据类型去接收一个大的数据,程序就还是正常运行的。

关于这个用更小的数据类型去接收一个超过其容量的返回值,它也不会有错误,只是在传输数据的时候,它只会取返回值的低位放入我们声明的数据变量中。

特别注意的是long long类型的数据,long long类型是8个字节也就是16位二进制,在传输的时候一个寄存器eax是肯定存不下的了,所以它用到了两个寄存器eax和edx,各8位就刚好16位。eax中存低八位,edx中存高八位。

在这里插入图片描述

在这里插入图片描述

参数传递的本质

​ 将上层函数的变量或者是表达式的值,通过寄存器或堆栈传递给下层函数。

参数在传递的过程中,传输的都是四个字节。与设置的参数的数据类型是没有关系的。

int ADD(int x){
    x = x+1;
}
int main(){
    int x = 2;
    ADD(x);
    printf("%d",x);
}
//最后输出的x是多少?
//正向学习的时候,这个形参和实参比较绕,但是学会反汇编之后。妈妈再也不用担心我学习!!!

函数创建时分配的空间大小

​ 在创建函数时,编译器会有一个默认的大小给到堆栈,在这个默认大小的基础下,根据函数中设置的局部变量的多少来扩充堆栈的大小(无论你是创建什么类型的局部变量,它都会单独给分配 一个堆栈地址空间。一个堆栈地址空间就是4个字节)

参数和局部变量都是堆栈中的值。区别就是内存分配的时间。参数是在函数调用前在堆栈中存储的值,局部变量是在调用函数时在堆栈中存储的值。

赋值语句的本质

​ 复制的本质就是将值存储到变量中的过程。

数组的本质

​ (这里是静态数组)在堆栈中连续的存储一系列的值。在创建的时候,计算机要知道数组多大才好分配空间。

int ADD(x,y){
    return x+y;
}
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];
    r = arr[arr[1]+arr[2]];
    r = arr[ADD(1,2)];
    r = arr[100];
}
int main(){
	Function();
    return 0;
}
//看反汇编,了解值的传递

在这里插入图片描述

在这里插入图片描述

数组越界(arr[100])。在编译时是可以执行的,但是它找的对应位置就是不确定的。但是我觉得这有很大的开发潜力。

​ 桶排序

创建一个数组,数组大小是待排序数中的最大值。根据数的值到对应数组位置进行加一操作,最后通过数组把排列数对应着打印出来。(排列数映射到对应数组的下标)

多维数组

​ 和一维数组的反汇编一样的。

//多维数组
int arr[3][4]={
    {1,2,3,4},
    {5,6,7,8},
    {9,10,11,12}
}

//一维数组
int brr[12]={1,2,3,4,5,6,7,8,9,10,11,12}

多维数组会 3乘4来得出这个多维数组需要的空间大小,在堆栈中发分配方式和一维数组一样。(CPU没有多维的概念)

​ 对应反汇编代码

在这里插入图片描述

在这里插入图片描述

对比这两个反汇编的不同处,我们应该着重关注:

①、堆栈分配的大小。因为在函数中只声明了两个数组作为局部变量,且数组的大小都一样(3*4=12),所以CPU分配的堆栈空间也是一样的。

②、数据放在堆栈的位置。因为两个数组我们设置的数据顺序都是一样的,所以连存放的位置都是一样的。

编译器创建数组时的小特点:

1、自动补零。当我发现我的数组还有空余时,我会把空挡补零。

2、自动分组。我在创建多维数组时,我可以不确定组数,也可以不确定每组个数。(两者需要确定一个)在确定好一个之后,编译器会自动分组,不足补零。

3、多维数组的查找方法:arr[1] [3] = arr[1*个数+3]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿拉垮神登

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值