关于C语言中一些类型变量在计算机存储的学习
2019-05-28 22:47
274 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42462966/article/details/90648790
我们都知道char型变量占一个字节,int型占用4个字节,long占用8个字节,double型变量占8个字节,那么这些变量和指针在计算机中存储在哪个地址单元呢?
#include <stdio.h> /* $end show-bytes */ #include <stdlib.h> #include <string.h> /* $begin show-bytes */ typedef unsigned char *byte_pointer; void show_bytes(byte_pointer start, size_t len) { size_t i; for (i = 0; i < len; i++) printf("%p\t0x%.2x\n", &start[i], start[i]); printf("\n"); } void show_int(int x) { show_bytes((byte_pointer) &x, sizeof(int)); } void show_float(float x) { show_bytes((byte_pointer) &x, sizeof(float)); } void show_pointer(void *x) { show_bytes((byte_pointer) &x, sizeof(void *)); } void test_show_bytes(int val) { int ival = val; double fval = (double) ival; int *pval = &ival; printf("Stack variable ival = %d\n", ival); printf("(int)ival:\n"); show_int(ival); printf("(float)ival:\n"); show_float(fval); printf("&ival:\n"); show_pointer(pval); } void simple_show_a() { /* $begin simple-show-a */ int val = 0x87654321; byte_pointer valp = (byte_pointer) &val; show_bytes(valp, 1); /* A. */ show_bytes(valp, 2); /* B. */ show_bytes(valp, 3); /* C. */ /* $end simple-show-a */ } void simple_show_b() { /* $begin simple-show-b */ int val = 0x12345678; byte_pointer valp = (byte_pointer) &val; show_bytes(valp, 1); /* A. */ show_bytes(valp, 2); /* B. */ show_bytes(valp, 3); /* C. */ /* $end simple-show-b */ } void float_eg() { int x = 3490593; float f = (float) x; printf("For x = %d\n", x); show_int(x); show_float(f); x = 3510593; f = (float) x; printf("For x = %d\n", x); show_int(x); show_float(f); } void string_ueg() { /* $begin show-ustring */ const char *s = "ABCDEF"; show_bytes((byte_pointer) s, strlen(s)); /* $end show-ustring */ } void string_leg() { /* $begin show-lstring */ const char *s = "abcdef"; show_bytes((byte_pointer) s, strlen(s)); /* $end show-lstring */ } void show_twocomp() { /* $begin show-twocomp */ short x = 12345; short mx = -x; show_bytes((byte_pointer) &x, sizeof(short)); show_bytes((byte_pointer) &mx, sizeof(short)); /* $end show-twocomp */ } int main(int argc, char *argv[]) { int val = 12345; if (argc > 1) { val = strtol(argv[1], NULL, 0); printf("calling test_show_bytes\n"); test_show_bytes(val); } else { printf("calling show_twocomp\n"); show_twocomp(); printf("Calling simple_show_a\n"); simple_show_a(); printf("Calling simple_show_b\n"); simple_show_b(); printf("Calling float_eg\n"); float_eg(); printf("Calling string_ueg\n"); string_ueg(); printf("Calling string_leg\n"); string_leg(); } return 0; }
结果如下:
hxl@hxl-virtual-machine:~/桌面/task/code$ ./sh calling show_twocomp 0x7ffd77301fc4 0x39 0x7ffd77301fc5 0x30 0x7ffd77301fc6 0xc7 0x7ffd77301fc7 0xcf Calling simple_show_a 0x7ffd77301fbc 0x21 0x7ffd77301fbc 0x21 0x7ffd77301fbd 0x43 0x7ffd77301fbc 0x21 0x7ffd77301fbd 0x43 0x7ffd77301fbe 0x65 Calling simple_show_b 0x7ffd77301fbc 0x78 0x7ffd77301fbc 0x78 0x7ffd77301fbd 0x56 0x7ffd77301fbc 0x78 0x7ffd77301fbd 0x56 0x7ffd77301fbe 0x34 Calling float_eg For x = 3490593 0x7ffd77301f9c 0x21 0x7ffd77301f9d 0x43 0x7ffd77301f9e 0x35 0x7ffd77301f9f 0x00 0x7ffd77301f9c 0x84 0x7ffd77301f9d 0x0c 0x7ffd77301f9e 0x55 0x7ffd77301f9f 0x4a For x = 3510593 0x7ffd77301f9c 0x41 0x7ffd77301f9d 0x91 0x7ffd77301f9e 0x35 0x7ffd77301f9f 0x00 0x7ffd77301f9c 0x04 0x7ffd77301f9d 0x45 0x7ffd77301f9e 0x56 0x7ffd77301f9f 0x4a Calling string_ueg 0x55dc9b616d34 0x41 0x55dc9b616d35 0x42 0x55dc9b616d36 0x43 0x55dc9b616d37 0x44 0x55dc9b616d38 0x45 0x55dc9b616d39 0x46 Calling string_leg 0x55dc9b616d3b 0x61 0x55dc9b616d3c 0x62 0x55dc9b616d3d 0x63 0x55dc9b616d3e 0x64 0x55dc9b616d3f 0x65 0x55dc9b616d40 0x66 hxl@hxl-virtual-machine:~/桌面/task/code$ ./sh 1 calling test_show_bytes Stack variable ival = 1 (int)ival: 0x7fff1c97f40c 0x01 0x7fff1c97f40d 0x00 0x7fff1c97f40e 0x00 0x7fff1c97f40f 0x00 (float)ival: 0x7fff1c97f40c 0x00 0x7fff1c97f40d 0x00 0x7fff1c97f40e 0x80 0x7fff1c97f40f 0x3f &ival: 0x7fff1c97f408 0x34 0x7fff1c97f409 0xf4 0x7fff1c97f40a 0x97 0x7fff1c97f40b 0x1c 0x7fff1c97f40c 0xff 0x7fff1c97f40d 0x7f 0x7fff1c97f40e 0x00 0x7fff1c97f40f 0x00
解释一下代码运行结果。不带参数运行时,调用show_twocomp()函数,这个函数再调用 show_bytes()函数,因为定义的是short型变量x=12345;转化成16进制是0x3039,则在计算机中就是0x30放在高地址区域,0x39放在低地址区域,这就是常说的小端模式,数据高有效部分放在高地址区域。同样的-12345存储时也是如此,需要注意的就是负数在计算机中存储是用补码表示,转化成16进制就是0xcfc7,后面代码也是如此,需要注意的就是,64位机指针是8个字节的,而且输出时如果高地址对应的数据高有效区位数不足,则需要用0x00来存。
再要说的就是浮点数在计算机中的存储,浮点数在64位机上一位表示符号,11位表示阶码,52位表示尾数,对于规格化的浮点数,11位阶码是由原数转换成2进制后通过移动小数点,来获得1.xxxxxxx *2的n次方或者0.xxxxxxx *2的n次方,此时阶码等于n+偏移量,偏移量=2的阶码-1次方-1,尾数就写小数点后面的,最后写成16进制形式,按照小端模式存储。其余运行结果都可按照类似得出。
相关文章推荐
- C语言学习总结 一 关于变量类型
- C语言学习关于数据类型的一些知识点(初学者)
- C语言学习4: 函数返回值与传入参数,关于函数值传递和类型隐性转换,变量不同的作用域,static变量,多文件编译例如两个C文件,显示函数调用语句跳转,递归,斐波那契数列,多文件编译相同变量的问题。
- 嵌入式学习10(C语言五大内存区间,变量的作用域和生存期,变量的存储类型)
- 【学习笔记】关于变量类型的一些知识
- C语言各种类型变量存储方式
- c语言学习第一课: 数据类型、变量、运算符
- C语言学习之变量存储
- C语言学习9: malloc动态内存存储,动态内存分配去空格字符增长版,动态内存分配去符号incr增长版,型参和返回值都是int型的函数的指针,main函数的地址也可以用指针指向,typedef定义函数指针,函数定义与嵌套的作用,返回函数指针类型,const作用
- C语言之变量类型和存储方式
- 关于c语言不同类型变量存放位置的个人理解
- 关于C语言学习单片机的一些心得
- C语言变量类型和存储分配
- Android中关于JNI 的学习(二)对于JNI方法名,数据类型和方法签名的一些认识
- 黑马程序员之ios学习总结——06 C语言的变量类型和结构体
- 黑马程序员——C语言学习笔记03 变量在内存中存储的细节、位运算
- C语言中变量的存储类型
- 关于引用类型变量存储的问题
- c语言中关于变量存储类别的心得
- C语言学习趣事_关于C语言中复杂类型定义