Python:整数在写内存整数型中是怎样存储的

Python多进程处理:如何将大量数据放入有限内存 - Python - 伯乐在线
& Python多进程处理:如何将大量数据放入有限内存
这是一篇有关如何将大量的数据放入有限的内存中的简略教程。
与客户工作时,有时会发现他们的数据库实际上只是一个csv或Excel文件仓库,你只能将就着用,经常需要在不更新他们的数据仓库的情况下完成工作。大部分情况下,如果将这些文件存储在一个简单的数据库框架中或许更好,但时间可能不允许。这种方法对时间、机器硬件和所处环境都有要求。
下面介绍一个很好的例子:假设有一堆表格(没有使用Neo4j、MongoDB或其他类型的数据库,仅仅使用csvs、tsvs等格式存储的表格),如果将所有表格组合在一起,得到的数据帧太大,无法放入内存。所以第一个想法是:将其拆分成不同的部分,逐个存储。这个方案看起来不错,但处理起来很慢。除非我们使用多核处理器。
这里的目标是从所有职位中(大约1万个),找出相关的的职位。将这些职位与政府给的职位代码组合起来。接着将组合的结果与对应的州(行政单位)信息组合起来。然后用通过word2vec生成的属性信息在我们的客户的管道中增强已有的属性。
这个任务要求在短时间内完成,谁也不愿意等待。想象一下,这就像在不使用标准的关系型数据库的情况下进行多个表的连接。
referencenumber
description
Sales Associate
Company Name
Our Sales Associates are…
“表格太长,请到查看。”
Pediatricians, General
area_title
naics_title
后略…
Cross-industry
“表格太长,请到查看。”
2010 SOC Code
2010 SOC Title
2010 SOC Direct Match Title
llustrative Example
Chief Executives
下面的是一个示例脚本,展示了如何使用multiprocessing来在有限的内存空间中加速操作过程。脚本的第一部分是和特定任务相关的,可以自由跳过。请着重关注第二部分,这里侧重的是multiprocessing引擎。
#import the necessary packages
import pandas as pd
import numpy as np
from multiprocessing import Pool,cpu_count,Queue,Manager
# the data in one particular column was number in the form that horrible excel version
# of a number where '12000' is '12,000' with that beautiful useless comma in there.
# did I mention I excel bothers me?
# instead of converting the number right away, we only convert them when we need to
def median_maker(column):
return np.median([int(x.replace(',','')) for x in column])
# dictionary_of_dataframes contains a dataframe with inform e.g title is 'Data Scientist'
# related_title_score_df is the dataframe of infor columns = ['title','score']
### where title is a similar_title and score is how closely the two are related, e.g. 'Data Analyst', 0.871
# code_title_df contains columns ['code','title']
# oes_data_df is a HUGE dataframe with all of the Bureau of Labor Statistics(BLS) data for a given time period (YAY FREE DATA, BOO BAD CENSUS DATA!)
def job_title_location_matcher(title,location):
related_title_score_df = dictionary_of_dataframes[title]
# we limit dataframe1 to only those related_titles that are above
# a previously established threshold
related_title_score_df = related_title_score_df[title_score_df['score']&80]
#we merge the related titles with another table and its codes
codes_relTitles_scores = pd.merge(code_title_df,related_title_score_df)
codes_relTitles_scores = codes_relTitles_scores.drop_duplicates()
# merge the two dataframes by the codes
merged_df = pd.merge(codes_relTitles_scores, oes_data_df)
#limit the BLS data to the state we want
all_merged = merged_df[merged_df['area_title']==str(us.states.lookup(location).name)]
#calculate some summary statistics for the time we want
group_med_emp,group_mean,group_pct10,group_pct25,group_median,group_pct75,group_pct90 = all_merged[['tot_emp','a_mean','a_pct10','a_pct25','a_median','a_pct75','a_pct90']].apply(median_maker)
row = [title,location,group_med_emp,group_mean,group_pct10,group_pct25, group_median, group_pct75, group_pct90]
#convert it all to strings so we can combine them all when writing to file
row_string = [str(x) for x in row]
return row_string
# if it doesnt work for a particular title/state just throw it out, there are enough to make this insignificant
'do nothing'
<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac
#import the necessary packagesimport pandas as pdimport usimport numpy as npfrom multiprocessing import Pool,cpu_count,Queue,Manager&# the data in one particular column was number in the form that horrible excel version # of a number where '12000' is '12,000' with that beautiful useless comma in there. # did I mention I excel bothers me?# instead of converting the number right away, we only convert them when we need todef median_maker(column):&&&&return np.median([int(x.replace(',','')) for x in column])&# dictionary_of_dataframes contains a dataframe with inform e.g title is 'Data Scientist'# related_title_score_df is the dataframe of infor columns = ['title','score'] ### where title is a similar_title and score is how closely the two are related, e.g. 'Data Analyst', 0.871# code_title_df contains columns ['code','title']# oes_data_df is a HUGE dataframe with all of the Bureau of Labor Statistics(BLS) data for a given time period (YAY FREE DATA, BOO BAD CENSUS DATA!)&def job_title_location_matcher(title,location):&&&&try:&&&&&&&&related_title_score_df = dictionary_of_dataframes[title]&&&&&&&&# we limit dataframe1 to only those related_titles that are above &&&&&&&&# a previously established threshold&&&&&&&&related_title_score_df = related_title_score_df[title_score_df['score']&80]&&&&&&&&&#we merge the related titles with another table and its codes&&&&&&&&codes_relTitles_scores = pd.merge(code_title_df,related_title_score_df)&&&&&&&&codes_relTitles_scores = codes_relTitles_scores.drop_duplicates()&&&&&&&&&# merge the two dataframes by the codes&&&&&&&&merged_df = pd.merge(codes_relTitles_scores, oes_data_df)&&&&&&&&#limit the BLS data to the state we want&&&&&&&&all_merged = merged_df[merged_df['area_title']==str(us.states.lookup(location).name)]&&&&&&&&&#calculate some summary statistics for the time we want&&&&&&&&group_med_emp,group_mean,group_pct10,group_pct25,group_median,group_pct75,group_pct90 = all_merged[['tot_emp','a_mean','a_pct10','a_pct25','a_median','a_pct75','a_pct90']].apply(median_maker)&&&&&&&&row = [title,location,group_med_emp,group_mean,group_pct10,group_pct25, group_median, group_pct75, group_pct90]&&&&&&&&#convert it all to strings so we can combine them all when writing to file&&&&&&&&row_string = [str(x) for x in row]&&&&&&&&return row_string&&&&except:&&&&&&&&# if it doesnt work for a particular title/state just throw it out, there are enough to make this insignificant&&&&&&&&'do nothing'
这里发生了神奇的事情:
#runs the function and puts the answers in the queue
def worker(row, q):
ans = job_title_location_matcher(row[0],row[1])
q.put(ans)
# this writes to the file while there are still things that could be in the queue
# this allows for multiple processes to write to the same file without blocking eachother
def listener(q):
f = open(filename,'wb')
m = q.get()
if m =='kill':
f.write(','.join(m) + 'n')
def main():
#load all your data, then throw out all unnecessary tables/columns
filename = 'skill_TEST_POOL.txt'
#sets up the necessary multiprocessing tasks
manager = Manager()
q = manager.Queue()
pool = Pool(cpu_count() + 2)
watcher = pool.map_async(listener,(q,))
#titles_states is a dataframe of millions of job titles and states they were found in
for i in titles_states.iloc:
job = pool.map_async(worker, (i, q))
jobs.append(job)
for job in jobs:
q.put('kill')
pool.close()
pool.join()
if __name__ == "__main__":
<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac<div class="crayon-num crayon-striped-num" data-line="crayon-58e7ac<div class="crayon-num" data-line="crayon-58e7ac
#runs the function and puts the answers in the queuedef worker(row, q):&&&&&&&&ans = job_title_location_matcher(row[0],row[1])&&&&&&&&q.put(ans)&# this writes to the file while there are still things that could be in the queue# this allows for multiple processes to write to the same file without blocking eachotherdef listener(q):&&&&f = open(filename,'wb')&&&&while 1:&&&&&&&&m = q.get()&&&&&&&&if m =='kill':&&&&&&&&&&&&&&&&break&&&&&&&&f.write(','.join(m) + 'n')&&&&&&&&f.flush()&&&&f.close()&def main():&&&&#load all your data, then throw out all unnecessary tables/columns&&&&filename = 'skill_TEST_POOL.txt'&&&&&#sets up the necessary multiprocessing tasks &&&&manager = Manager()&&&&q = manager.Queue()&&&&pool = Pool(cpu_count() + 2)&&&&watcher = pool.map_async(listener,(q,))&&&&&jobs = []&&&&#titles_states is a dataframe of millions of job titles and states they were found in&&&&for i in titles_states.iloc:&&&&&&&&job = pool.map_async(worker, (i, q))&&&&&&&&jobs.append(job)&&&&&for job in jobs:&&&&&&&&job.get()&&&&q.put('kill')&&&&pool.close()&&&&pool.join()&if __name__ == "__main__":&&&&main()
由于每个数据帧的大小都不同(总共约有100Gb),所以将所有数据都放入内存是不可能的。通过将最终的数据帧逐行写入内存,但从来不在内存中存储完整的数据帧。我们可以完成所有的计算和组合任务。这里的“标准方法”是,我们可以仅仅在“job_title_location_matcher”的末尾编写一个“write_line”方法,但这样每次只会处理一个实例。根据我们需要处理的职位/州的数量,这大概需要2天的时间。而通过multiprocessing,只需2个小时。
虽然读者可能接触不到本教程处理的任务环境,但通过multiprocessing,可以突破许多计算机硬件的限制。本例的工作环境是c3.8xl ubuntu ec2,硬件为32核60Gb内存(虽然这个内存很大,但还是无法一次性放入所有数据)。这里的关键之处是我们在60Gb的内存的机器上有效的处理了约100Gb的数据,同时速度提升了约25倍。通过multiprocessing在多核机器上自动处理大规模的进程,可以有效提高机器的利用率。也许有些读者已经知道了这个方法,但对于其他人,可以通过multiprocessing能带来非常大的收益。顺便说一句,这部分是这篇博文的延续。
打赏支持我翻译更多好文章,谢谢!
打赏支持我翻译更多好文章,谢谢!
任选一种支付方式
关于作者:
可能感兴趣的话题
性能瓶颈问题
关于 Python 频道
Python频道分享 Python 开发技术、相关的行业动态。
新浪微博:
推荐微信号
(加好友请注明来意)
&#8211; 好的话题、有启发的回复、值得信赖的圈子
&#8211; 分享和发现有价值的内容与观点
&#8211; 为IT单身男女服务的征婚传播平台
&#8211; 优秀的工具资源导航
&#8211; 翻译传播优秀的外文文章
&#8211; 国内外的精选文章
&#8211; UI,网页,交互和用户体验
&#8211; 专注iOS技术分享
&#8211; 专注Android技术分享
&#8211; JavaScript, HTML5, CSS
&#8211; 专注Java技术分享
&#8211; 专注Python技术分享
& 2017 伯乐在线Python 整数对象实现原理 - 我的成长之路 http://foofish.net - ITeye技术网站
博客分类:
整数对象在Python内部用PyIntObject结构体表示:
typedef struct {
PyObject_HEAD
PyObject_HEAD宏中定义的两个属性分别是:
struct _typeobject *ob_
这两个属性是所有Python对象固有的:
ob_refcnt:对象的引用计数,与Python的内存管理机制有关,它实现了基于引用计数的垃圾收集机制
ob_type:用于描述Python对象的类型信息。
由此看来PyIntObject就是一个对C语言中long类型的数值的扩展,出于性能考虑,对于小整数,Python使用小整数对象池small_ints缓存了[-5,257)之间的整数,该范围内的整数在Python系统中是共享的。
#define NSMALLPOSINTS
#define NSMALLNEGINTS
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
而超过该范围的整数即使值相同,但对象不一定是同一个,如下所示:当a与b的值都是10000,但并不是同一个对象,而值为1的时候,a和b属于同一个对象。
&&& a = 10000
&&& b = 10000
&&& print a is b
&&& print a is b
对于超出了[-5, 257)之间的其他整数,Python同样提供了专门的缓冲池,供这些所谓的大整数使用,避免每次使用的时候都要不断的malloc分配内存带来的效率损耗。这块内存空间就是PyIntBlock。
struct _intblock {
struct _intblock *
PyIntObject objects[N_INTOBJECTS];
typedef struct _intblock PyIntB
static PyIntBlock *block_list = NULL;
static PyIntObject *free_list = NULL;
这些内存块(blocks)由一个单向链表表示,表头是block_list,block_list始终指向最新创建的PyIntBlock对象。next指针指向下一个PyIntBlock对象,objects是一个PyIntObject数组(最终会转变成单向链表),它是真正用于存储被缓存的PyIntObjet对象的内存空间。 free_list单向链表是所有block的objects中空闲的内存。所有空闲内存通过一个链表组织起来的好处就是在Python需要新的内存来存储新的PyIntObject对象时,能够通过free_list快速获得所需的内存。
创建一个整数对象时,如果它在小整数范围内,就直接从小整数缓冲池中直接返回,如果不在该范围内,就开辟一个大整数缓冲池内存空间:
[intobject.c]
PyObject* PyInt_FromLong(long ival)
register PyIntObject *v;
#if NSMALLNEGINTS + NSMALLPOSINTS & 0
//[1] :尝试使用小整数对象池
if (-NSMALLNEGINTS &= ival && ival & NSMALLPOSINTS) {
v = small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v);
return (PyObject *)
//[2] :为通用整数对象池申请新的内存空间
if (free_list == NULL) {
if ((free_list = fill_free_list()) == NULL)
return NULL;
//[3] : (inline)内联PyObject_New的行为
free_list = (PyIntObject *)v-&ob_
PyObject_INIT(v, &PyInt_Type);
v-&ob_ival =
return (PyObject *)
fill_free_list就是创建大整数缓冲池内存空间的逻辑,该函数返回一个free_list链表,当整数对象ival创建成功后,free_list表头就指向了v-&ob_type,ob_type不是所有Python对象中表示类型信息的字段吗?怎么在这里作为一个连接指针呢?这是Python在性能与代码优雅之间取中庸之道,对名称的滥用,放弃了对类型安全的坚持。把它理解成指向下一个PyIntObject的指针即可。
[intobject.c]
static PyIntObject* fill_free_list(void)
PyIntObject *p, *q;
// 申请大小为sizeof(PyIntBlock)的内存空间
// block list始终指向最新创建的PyIntBlock
p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
((PyIntBlock *)p)-&next = block_
block_list = (PyIntBlock *)p;
//:将PyIntBlock中的PyIntObject数组(objects)转变成单向链表
p = &((PyIntBlock *)p)-&objects[0];
q = p + N_INTOBJECTS;
while (--q & p)
// ob_type指向下一个未被使用的PyIntObject。
q-&ob_type = (struct _typeobject *)(q-1);
q-&ob_type = NULL;
return p + N_INTOBJECTS - 1;
不同的PyIntBlock里面的空闲的内存是怎样连接起来构成free_list的呢?这个秘密放在了整数对象垃圾回收的时候,在PyIntObject对象的tp_dealloc操作中可以看到:
[intobject.c]
static void int_dealloc(PyIntObject *v)
if (PyInt_CheckExact(v)) {
v-&ob_type = (struct _typeobject *)free_
free_list =
v-&ob_type-&tp_free((PyObject *)v);
原来PyIntObject对象销毁时,它所占用的内存并不会释放,而是继续被Python使用,进而将free_list表头指向了这个要被销毁的对象上。
Python中的int对象就是c语言中long类型数值的扩展
小整数对象[-5, 257]在python中是共享的
整数对象都是从缓冲池中获取的。
整数对象回收时,内存并不会归还给系统,而是将其对象的ob_type指向free_list,供新创建的整数对象使用
lantian_123
浏览: 830845 次
来自: 广州
学会了recording,感谢~~
看完了才发现这篇文章果然是你写的
看完了,才发现时部长写的,真爱啊2353人阅读
python(3)
相信学过c的人,对变量和内存了解的差不多,明白了变量的类型(int, float , double),知道列它们所占内存的大小可是,python中他们是一样的吗???
No,No, No&&&&& 它们并不一样(尽管说,python就是用c写的)
一& :python下的变量
&&&&& 不需要预先声明变量的类型,变量的类型和&#20540;在赋&#20540;的那一刻被初始化(声明和定义的过程一起完成)
&&&&& 在python中, 每一个变量在内存中创建,我们可以通过变量来查看内存中的&#20540;
哈哈,这里是不是很熟悉,跟c中的指针一样啊(访问内存中的&#20540;)
& & & & &首先大家需要了解一点:在python中:
& & & & & x =5之后,我们要了解它的过程:系统先是找了一块内存,将5存储了进去,紧接着x指向了当前的这块内存
预测1:&&&&& python下的变量是一个指针
&&& print x
&&& print y
从上面我们可以看到:
x = 4 & & & &说明x指向了内存中存储为4的那个地址,那个地址是
y = 5 & & & &说明y指向了内存中存储为5的那个地址,那个地址是
也就是说在执行x = 4,y = 5之后,x,y分别指向了不同的地址,当执行 x = y之后:
也就是说,x指向了y所指向的内存了,这里我们知道,它们都指向同一块内存
哈哈,原来跟c里面的指针真的一样哎!!!哈哈哈
(但是,但是,但是 & & :就这些吗??)
&&& print x
&&& print x
好,我们大家接着看:
也就是说:开始的时候,x指向了这块内存,里面存储的是4
当执行了x = 5之后,也就变成了这样:
&好,ok就是这样了,
不知道大家注意到了吗?
在python中,一开始初始化存储在内存的东西是不可以更改的,我们所能更改的只是它的指向,
但是,但是,在c中,对于int&&&x=&4;&&&也就是说x的地址是定的,里面存储的东西可以更改#include &stdio.h&
int main(){
int x = 4;
printf(&%p
%d\n&, &x, x);
printf(&%p
%d\n&, &x, x);
}我们大家再看一下运行结果:
从上面可以看到,地址并没有变,好了,这一点,python和c的区别较大,希望大家注意。
二: 内存大小
& & &我们来看一下这样的代码:
& & &&&& x = 6
&&& 从上面的程序中,我们知道系统给分配的地址分别是:
所以我们大胆推测,python中应该给这些整数的字节有可能就是12(哈哈,纯属个人推测)
有可能内存中就是这样了的:
哈哈,也该就是这样子了,
至于其他的大小,有兴趣的朋友可以研究研究
三:python内存
& & & & 是不是说:在python中,系统将每一个&#20540;都放在了一个固定的位置,不然为什么,每一次探究内存地址的时候,结果都是一样的(数&#20540;相等,地址也相等)
&&& 假如系统为4分配了一块内存,遵循某种规则(类&#20284;于c里面的内存对齐),那么接下来为5分配了另一块内存,权且分配到了
那么下面这个如何解释:
&&& 假如遵循某种规则的话,应该是6也分配到了去了,可是,他被分配到了
我们再来看:
&&& 这,哈哈,应该就是这样的了的吧!!!!
也就是说:python中,系统还是python本身为其分配内存的时候就已经根据这个&#20540;是多少,确定了内存的位置了。。。
欢迎大家前来提问,共同学习,谢谢
学术问题吗《,,都是推测&#43;验证&&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:100473次
积分:1957
积分:1957
排名:第17503名
原创:98篇
转载:60篇
评论:15条
(1)(10)(15)(29)(20)(5)(9)(10)(26)(12)(14)(5)(4)

我要回帖

更多关于 整数在内存中的存储 的文章

 

随机推荐