c语言里啥变量存储在堆中啥变量存储在栈中啊!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言里啥变量存储在堆中啥变量存储在栈中啊!相关的知识,希望对你有一定的参考价值。

函数的局部变量、参数一般在栈中分配空间存储
也不是绝对的,编译器可能会优化使用寄存器传递参数
不过可以显式地规定函数的参数传递方式,可以查一下stdcall,fastcall等宏的具体定义和作用
局部变量中的静态变量的空间在数据段中,不在栈中
程序中动态分配的空间,如malloc分配的空间位于堆中
参考技术A 这是编译器的设定,局部变量在栈中,全局和静态变量在数据段中。调用函数的时候压栈分配空间,调用返回时出栈,即释放空间。修改变量只需利用ebp的位置改就行了,如,mov
eax,
-8(ebp)。

JS基础 - 变量 数组

一、值类型 VS 引用类型

值类型 引用类型

值直接存储在栈中

值存储在堆中,再将堆的地址存到栈中

number, string, boolean, undefined, symbol

object, array, null

变量之间赋值 a = b,是指直接将栈中变量a的值复制到变量b的栈空间里面;

之后对两个变量值的修改相互不影响

变量之间赋值 a = b,只复制栈中存储的变量a的值在堆里的地址,赋值以后ab指向堆中同一个地址;

改变任一变量的值,另一变量的值也随之改变

 

二、typeof类型判断

typeof用于判断变量类型,返回一个表示变量类型的string(首字母小写),其识别结果可分为以下三类:

  • typeof可识别所有基本类型
console.log(typeof 1);  //"number"
console.log(typeof "1"); //"string"
console.log(typeof true); //"boolean"
console.log(typeof undefined); //"undefined"
console.log(typeof aNewVar); //"undefined"
  • typeof可识别函数("function")
let myFun = function(){
    console.log("123");
}
console.log(typeof myFun); //"function"
  • typeof可判断一个变量是否是引用类型(只识别到"object",不再细分)
let arr = [1, 2, 3];
let obj = {
    a: 1,
    b: {
        x: 100
    }
}
console.log(typeof arr); //"object"
console.log(typeof obj); //"object"
console.log(typeof obj.b); //"object"
console.log(typeof null); //"object"

 

三、类型转换

显式类型转换:

let intA = parseInt("100");
let floatA = parseFloat(intA);

 

隐式类型转换:

console.log(100 + "10"); //"10010"
console.log(true + "10"); //"true10"

 

四、数组

1. split() 和 join()

split 将字符串根据指定字符拆分成数组,join将数组元素用指定字符连接成字符串。

console.log(‘1-2-3‘.split(‘-‘)); //[1,2,3]
console.log([1,2,3].join(‘-‘)); //‘1-2-3‘

 

2. pop(), push(), shift(), unshift()

  pop push shift unshift
功能 删除数组最后一个元素 在数组末尾插入一个元素 删除数组第一个元素 在数组开头插入一个元素
参数  arr.pop() arr.push(1) arr.shift() arr.unshift(1)
返回值 返回被删除的元素 返回length 返回被删除的元素 返回length
是否改变原数组

 3. 数组的纯函数API(不改变原数组,返回一个新的数组)

concat, map, filter, slice

const arr = [10, 20, 30];

//concat
const arrConcat = arr.concat([40, 50]); 
//map
const arrMap = arr.map(num => num*2);
//filter
const arrFilter = arr.filter(num => num % 3 === 0);
//slice
const arrSlice = arr.slice();//相当于深拷贝

 

4. 数组的非纯函数API

pop, push, shift, unshift 改变原数组

forEach, some, every, reduce 不返回新数组

 

5. slice vs splice

  • slice用法 - 纯函数
//slice
 const arr = [10, 20, 30, 40, 50, 60];
const arrSlice = arr.slice();//相当于深拷贝
const arrSlice2 = arr.slice(1, 4); //[20, 30, 40] 左闭右开
const arrSlice3 = arr.slice(2);//[30, 40, 50, 60]
const arrSlice4 = arr.slice(-2); //[50, 60]
  • splice用法 - 非纯函数
//splice 非纯函数
  const arr = [10, 20, 30, 40, 50, 60];
const spliceRes = arr.splice(1, 3, ‘a‘,‘b‘,‘c‘,‘d‘); //起点,删除个数,新插入的序列
console.log(spliceRes);//返回被删除的数组片段[20, 30, 40]
console.log(arr);//剪接后的数组[10, "a", "b", "c", "d", 50, 60]

//arr.splice(1, 0, ‘a‘, ‘b‘); //不剪切,从位置1开始直接插入[10, "a", "b", 20, 30, 40, 50, 60]
//arr.splice(1, 3);//只删除,不插入[10, 50, 60]

对比:

  slice splice
功能 截取数组片段 替换数组片段
参数

slice(1, 4)

截取起点,截取终点

左闭右开

splice(1, 4, ‘a‘, ‘b‘)

插入起点,删除个数,插入元素

返回值  截取的新数组  被删除的数组片段
是否为纯函数  是  否(原数组被改变)

 

 6. [10, 20, 30].map(parseInt)

  • parseInt函数

parseInt(string, radix)

string: 必需。被解析的字符串。

radix: 可选。解析的数字的奇数(将字符串按什么进制解析),值介于2-36。

  • map函数中传入的参数, 第一个为元素值,第二个为元素的索引
  • [10, 20, 30].map(parseInt)等效于:
const arr2 = [10, 20, 30];
const arr2Map = arr2.map((num, index) => parseInt(num, index));

const arr2Map = arr2.map((num, index) => {
    return parseInt(num, index);
});

即对10,20,30分别执行:

10 -> parseInt(‘10‘,  0); //传入0默认为10进制
20 -> parseInt(‘20‘,  1); //基数为1,不在2-36之间,返回NaN
30 -> parseInt(‘30‘,  2); //基数为2,但30不是二进制数,返回NaN

故最终返回新数组:[10, NaN, NaN]

 

以上是关于c语言里啥变量存储在堆中啥变量存储在栈中啊!的主要内容,如果未能解决你的问题,请参考以下文章

编程语言中的值数据类型和引用数据类型之间的区别

C语言中字符串常量到底存在哪了?

C语言里,哪些变量是存放在堆里,哪些是存放在栈里?

java中啥是栈啊?

C#-变量类型(值类型引用类型)

java变量存储