C语言中的变量有四种存储类型,这四种存储类型的关键字分别是auto(自动),extern(外部),static(静态)和register(寄存器)。
‘贰’ C语言中如何将未知个数的数存放在一个数组中
在C语言中数组的定义必须指明维数,即使没有指明维数,也必须进行初始化,编译器通过初始化列表中的元素个数来确定数组的维数,比如下面的代码:
int a[] = {1,2,3};
虽然没有指明数组的维数,但是编译知道数组a的维数是3(只有三个元素)。
要实现未知个数的元素存储于数组中,可以使用malloc()和free()来进行动态内存分配 。下面是一个使用动态内存的示例:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
intmain()
{
intsize;
printf("输入建立元素的个数:");
scanf("%d",&size);
int*p=(int*)malloc(sizeof(int)*size);
if(p==0){
printf("不能分配内存 ");
return0;
}
//初始化内存
memset(p,0x00,sizeof(int)*size);
//释放内存
free(p);
return0;
}
‘叁’ 请教变量数据在内存中的存储方式,比如int a=2,那么在内存中是怎么存储的呢
额 你理解错了 。 跟本就不存在a的ASCII码值。
这样看:定义了一个变量,给它取个名字叫a,这个名字是给你程序员看的,计算机跟本不看这个a,a对计算机来说只是一个标识,它标识着在内存中所占用的一个大小为4B的内存空间,并且!这4B的空间存放一个整数,其值为2. 而在存储的时候是这样存的
由于内存的最小单位是字节,也就是1B是最小的单位,而一个int类型的数据在32的系统中要占用32位大小, 换算一个 8位=1字节 即8bit=1B 那么32位=4字节。 这个2转换成二进制数是10 ,但计算机要求用32位的数来存放这个2 ,咋办? 补0呗。在哪补? 肯定不能在后边补啊,那就变成别的数了—— 那,那就在前补。
所以是00000000 00000000 00000000 00000010
以上便是2这个数在计算机内存中的形式, 每8位一组分成4组刚好是4B大小,所以内存中就有连着的4个内存单元 来存放这个数值2. 而这一内存单元我们把它叫做a, 计算机也正是通过这个名字来标识这个数。
综上,总结一下,a这个字母是给程序员看的, 计算机不认识a这字母,a在计算机中仅仅是转换为一个计算机用于标识这个数值2的其它的什么东西。 具体是什么东西你不必要了解,其实我也不知道。而这个2在内存中存放的形式是占用4个内存单元的空间。
楼主想更深入了解这方面,建议把C语言学一遍后学学汇编语言就很清楚了
‘肆’ 【求助c语言】,凡是函数中未指定存储类别的全局变量,其隐含的存储类别为
全局变量其默认储存类型都是extern
,
而局部变量的默认储存类型是
auto,
函数中声明的变量是局部变量,所以原题中说
“函数中未指定存储类别的全局变量”
这句本身就有问题。
记着:
全局变量
extern
局部变量
auto
‘伍’ 变量的存储类型是什么
量有4种存储类型,分别是auto(自动型)、static(静态型)、register(寄存器型)和extern(外部型)。在定义或说明一个变量时可以加上存储类型关键字,以限定其存储类别。
存储类型决定了系统将在哪一个数据存储区为变量分配存储空间。
‘陆’ float变量在内存当中是怎样存储的或是怎样的一种存储格式
浮点型变量在计算机内存中占用4字节(Byte),即32-bit。遵循IEEE-754格式标准。
一个浮点数由2部分组成:底数m 和 指数e。
±mantissa × 2exponent
(注意,公式中的mantissa 和 exponent使用二进制表示)
底数部分使用2进制数来表示此浮点数的实际值。
指数部分占用8-bit的二进制数,可表示数值范围为0-255。但是指数应可正可负,所以IEEE规定,此处算出的次方须减去127才是真正的指数。所以float的指数可从 -126到128.
底数部分实际是占用24-bit的一个值,由于其最高位始终为 1 ,所以最高位省去不存储,在存储中只有23-bit。
到目前为止, 底数部分 23位 加上指数部分 8位 使用了31位。那么前面说过,float是占用4个字节即32-bit,那么还有一位是干嘛用的呢? 还有一位,其实就是4字节中的最高位,用来指示浮点数的正负,当最高位是1时,为负数,最高位是0时,为正数。
浮点数据就是按下表的格式存储在4个字节中:
Address+0 Address+1 Address+2 Address+3
Contents SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM S: 表示浮点数正负,1为负数,0为正数
E: 指数加上127后的值的二进制数
M: 24-bit的底数(只存储23-bit)
主意:这里有个特例,浮点数 为0时,指数和底数都为0,但此前的公式不成立。因为2的0次方为1,所以,0是个特例。当然,这个特例也不用认为去干扰,编译器会自动去识别。
通过上面的格式,我们下面举例看下-12.5在计算机中存储的具体数据:
Address+0 Address+1 Address+2 Address+3
Contents 0xC1 0x48 0x00 0x00 接下来我们验证下上面的数据表示的到底是不是-12.5,从而也看下它的转换过程。
由于浮点数不是以直接格式存储,他有几部分组成,所以要转换浮点数,首先要把各部分的值分离出来。
Address+0 Address+1 Address+2 Address+3
格式 SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
二进制 11000001 01001000 00000000 00000000
16进制 C1 48 00 00
可见:
S: 为1,是个负数。
E:为 10000010 转为10进制为130,130-127=3,即实际指数部分为3.
M:为 10010000000000000000000。 这里,在底数左边省略存储了一个1,使用 实际底数表示为 1.10010000000000000000000
到此,我们吧三个部分的值都拎出来了,现在,我们通过指数部分E的值来调整底数部分M的值。调整方法为:如果指数E为负数,底数的小数点向左移,如果指数E为正数,底数的小数点向右移。小数点移动的位数由指数E的绝对值决定。
这里,E为正3,使用向右移3为即得:
1100.10000000000000000000
至次,这个结果就是12.5的二进制浮点数,将他换算成10进制数就看到12.5了,如何转换,看下面:
小数点左边的1100 表示为 (1 × 23) + (1 × 22) + (0 × 21) + (0 × 20), 其结果为 12 。
小数点右边的 .100… 表示为 (1 × 2-1) + (0 × 2-2) + (0 × 2-3) + ... ,其结果为.5 。
以上二值的和为12.5, 由于S 为1,使用为负数,即-12.5 。
所以,16进制 0XC1480000 是浮点数 -12.5 。
上面是如何将计算机存储中的二进制数如何转换成实际浮点数,下面看下如何将一浮点数装换成计算机存储格式中的二进制数。
举例将17.625换算成 float型。
首先,将17.625换算成二进制位:10001.101 ( 0.625 = 0.5+0.125, 0.5即 1/2, 0.125即 1/8 如果不会将小数部分转换成二进制,请参考其他书籍。) 再将 10001.101 向右移,直到小数点前只剩一位 成了 1.0001101 x 2的4次方(因为右移了4位)。此时 我们的底数M和指数E就出来了:
底数部分M,因为小数点前必为1,所以IEEE规定只记录小数点后的就好,所以此处底数为 0001101 。
指数部分E,实际为4,但须加上127,固为131,即二进制数 10000011
符号部分S,由于是正数,所以S为0.
综上所述,17.625的 float 存储格式就是:
0 10000011 00011010000000000000000
转换成16进制:0x41 8D 00 00
所以,一看,还是占用了4个字节。
下面,我做了个有趣的实验,就是由用户输入一个浮点数,程序将这个浮点数在计算机中存储的二进制直接输出,来看看我们上面所将的那些是否正确。
有兴趣同学可以到VC6.0中去试试~!
#include<iostream.h>
#define uchar unsigned char
void binary_print(uchar c)
{
for(int i = 0; i < 8; ++i)
{
if((c << i) & 0x80)
cout << '1';
else
cout << '0';
}
cout << ' ';
}
void main()
{
float a;
uchar c_save[4];
uchar i;
void *f;
f = &a;
cout<<"请输入一个浮点数:";
cin>>a;
cout<<endl;
for(i=0;i<4;i++)
{
c_save[i] = *((uchar*)f+i);
}
cout<<"此浮点数在计算机内存中储存格式如下:"<<endl;
for(i=4;i!=0;i--)
binary_print(c_save[i-1]);
cout<<endl;
}
好了,我想如果你仔细看完了以上内容,你现在对浮点数算是能比较深入的了解了。
‘柒’ 函数中未指定存储类别的局部变量,其隐含的存储类别为()
函数中未指定存储类别的局部陪袜变量,其隐含的存储类别为自动存储类别。
函数中的局部变量,如果不专门声明为static存储类别,都是动态的分配存储空间的,数租唯据存储在动态存储区中。
这类变量叫做自动变量,自动变量可以用关键字auto作为存储类别的声明,实际上关键字auto是可以省略的(一般都是不写的),不写则自动隐含为“自动存储类别“。
(7)未知变量的存储格式扩展阅读:
默认情况下,在代码块内声明的变量都是自动变量,但芦型激亦可用自动变量的关键字auto明确标识存储类;而如若使用register(而非auto)存储类标识代码块内的变量,编译器就会将变量缓存于处理器内的寄存器中,此种情况下不能对该变量或其成员变量使用引用操作符&以获取其地址,因为&只能获取内存空间中的地址。
除此以外,由于寄存器的数量及其所能存储的数据类型受硬件限制而可能无法存储指定变量,编译器可以忽略声明内的register关键字。对于一个未初始化的自动变量来说,在为其赋值之前其值都为undefined(未定义)。
在C++中,如谚语“资源获取即初始化”(Resource Acquisition Is Initialization,常缩写为RAII)所述,自动变量的构造函数在程序运行至声明部分的时候才会被调用,而当程序运行至所给的程序块末端的时候则调用析构函数,这一特性常应用于资源的分配与释放管理,如自动关闭已开启的文件或自动释放空闲内存。
‘捌’ C语言中变量的存储类型有哪几种,存储方式哪几种谢喽
在C语言中,对变量的存储类型说明有以下四种:
1、auto 自动变量
2、register 寄存器变量
3、extern 外部变量
4、static 静态变量
所谓存储类型是指变量占用内存空间的方式,也称为存储方式。
变量的存储方式可分为“静态存储”和“动态存储”两种。
1、静态存储变量通常是在变量定义时就在存储单元并一直保持不变,直至整个程序结束。
2、动态存储变量是在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放。典型的例子是函数的形式参数,在函数定义时并不给形参分配存储单元,只是在函数被调用时,才予以分配,调用函数完毕立即释放。
如果一个函数被多次调用,则反复地分配、释放形参变量的存储单元。从以上分析可知,静态存储变量是一直存在的,而动态存储变量则时而存在时而消失。
(8)未知变量的存储格式扩展阅读:
变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。
一、从作用域看:
1、全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量的定义的源文件需要用extern关键字再次声明这个全局变量。
2、静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束一直存在,它和全局变量的区别在于全局变量对所有函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
3、局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
4、静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它文件里,不能作用到其他文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
二、从分配空间看:
全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。
全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。
而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一个源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。
1、静态变量会放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
参考资料来源:网络-变量-存储类型