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 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 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语言里啥变量存储在堆中啥变量存储在栈中啊!的主要内容,如果未能解决你的问题,请参考以下文章