#include<stdio.h>
#include<string.h>
int main(){
long long int a = 2<<30;
char string[] = "Hello China1!";
char string2[] = "Hello China2!";
if(0==strcmp(string,string2))
{
printf(string);
printf("\n");
}
else
{
printf("Not match!\n");
}
printf("a = %u\n",a);
printf("a = %d\n",a);
char c[] = {'I',' ','a','m',' ','l','i','u','k','u','n'};
printf(c);
return 0;
}

  

 
 
C语言字符串不加结束符,打印出的结果不好预测。这应该跟操作系统的内存模型有关,理由如下:
Windows GCC编译打印结果是:
Not match!
a = 2147483648
a = -2147483648
I am liukunHello China2!
 
Linux GCC编译打印结果是:

Not match!
a = 2147483648
a = -2147483648
I am liukunliukun

我也不知道为什么 Hello China2 内存上跟 I am liukun 连在一起的。
反汇编出来的代码好乱也不好读。
 
ASCII 码表:
ASCII 码 字符   ASCII 码 字符   ASCII 码 字符   ASCII 码 字符
十进位 十六进位   十进位 十六进位   十进位 十六进位   十进位 十六进位
032 20     056 38 8   080 50 P   104 68 h
033 21 !   057 39 9   081 51 Q   105 69 i
034 22 "   058 3A :   082 52 R   106 6A j
035 23 #   059 3B ;   083 53 S   107 6B k
036 24 $   060 3C <   084 54 T   108 6C l
037 25 %   061 3D =   085 55 U   109 6D m
038 26 &   062 3E >   086 56 V   110 6E n
039 27 '   063 3F ?   087 57 W   111 6F o
040 28 (   064 40 @   088 58 X   112 70 p
041 29 )   065 41 A   089 59 Y   113 71 q
042 2A *   066 42 B   090 5A Z   114 72 r
043 2B +   067 43 C   091 5B [   115 73 s
044 2C ,   068 44 D   092 5C \   116 74 t
045 2D -   069 45 E   093 5D ]   117 75 u
046 2E .   070 46 F   094 5E ^   118 76 v
047 2F /   071 47 G   095 5F _   119 77 w
048 30 0   072 48 H   096 60 `   120 78 x
049 31 1   073 49 I   097 61 a   121 79 y
050 32 2   074 4A J   098 62 b   122 7A z
051 33 3   075 4B K   099 63 c   123 7B {
052 34 4   076 4C L   100 64 d   124 7C |
053 35 5   077 4D M   101 65 e   125 7D }
054 36 6   078 4E N   102 66 f   126 7E ~
055 37 7   079 4F O   103 67 g   127 7F DEL
 
 
【注】小端模式
所谓的小端模式(Little-endian),是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
例子:
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000
0000440: b484 6c4e 004e ed00 0000 0000 0100 0000
在小端模式下,前32位应该这样读: 4e 6c 84 e6( 假设int占4个字节)
记忆方法: 地址的增长顺序与值的增长顺序相同
 
> objdump -d datatype.exe > output.txt
 
反汇编代码节选:
;I am liukun 的地址安排
4014e2: c6 44 24 11 49 movb $0x49,0x11(%esp)
4014e7: c6 44 24 12 20 movb $0x20,0x12(%esp)
4014ec: c6 44 24 13 61 movb $0x61,0x13(%esp)
4014f1: c6 44 24 14 6d movb $0x6d,0x14(%esp)
4014f6: c6 44 24 15 20 movb $0x20,0x15(%esp)
4014fb: c6 44 24 16 6c movb $0x6c,0x16(%esp)
401500: c6 44 24 17 69 movb $0x69,0x17(%esp)
401505: c6 44 24 18 75 movb $0x75,0x18(%esp)
40150a: c6 44 24 19 6b movb $0x6b,0x19(%esp)
40150f: c6 44 24 1a 75 movb $0x75,0x1a(%esp)
401514: c6 44 24 1b 6e movb $0x6e,0x1b(%esp)
.......
40144d: c7 44 24 1c 48 65 6c movl $0x6c6c6548,0x1c(%esp)
 
End
总之,使用C编程时还是要多注意,操纵内存虽然爽,但是一不小心就会埋下Bug。
话说两个没有使用到的局部变量字串应该可以被编译器优化的,如果是这样的话栈里面就不会为其分配内存啦,不知道Linux下面的GCC是不是这样做的。
 

C语言与内存模型初探的更多相关文章

  1. 有 va_arg宏 中数组下标-1 引发的思考 - C 语言中内存模型

    va_arg宏,是头文件 stdarg.h 中定义的,获取可变参数的当前参数. #define va_arg(list, mode) ((mode*)(list+=sizeof(mode)))[-1] ...

  2. C语言复习:内存模型1

    数据类型本质分析 数据类型概念 "类型"是对数据的抽象; 类型相同的数据有相同的表现形式/存储格式以及相关的操作; 程序中使用的所有数据都必定属于某一种数据类型; 数据类型本质思考 ...

  3. Java 线程 — JMM Java内存模型

    JMM Java Memory Model,Java内存模型,属于语言级的内存模型 并发编程中存在的问题: 如何通信:用于线程之间交换信息.两种方式:共享内存,消息传递 如何同步:用于控制不同线程间操 ...

  4. (第三章)Java内存模型(下)

    一.happens-before happens-before是JMM最核心的概念.对于Java程序员来说,理解happens-before是理解JMM的关键. 1.1 JMM的设计 从JMM设计者的 ...

  5. 求你了,再问你Java内存模型的时候别再给我讲堆栈方法区了…

    GitHub 4.1k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 4.1k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 4.1k Star 的 ...

  6. 一个试图了解JVM内存模型的两年经验的初级程序员,透彻!

    所有的编程语言中都有内存模型这个概念,区别于微架构的内存模型,高级语言的内存模型包括了编译器和微架构两部分.我试图了解了Java.C#和Go语言的内存模型,发现内容基本大同小异,只是这些语言在具体实现 ...

  7. JVM初探 -JVM内存模型

    JVM初探 -JVM内存模型 标签 : JVM JVM是每个Java开发每天都会接触到的东西, 其相关知识也应该是每个人都要深入了解的. 但接触了很多人发现: 或了解片面或知识体系陈旧. 因此最近抽时 ...

  8. C语言 二级指针内存模型①

    //二级指针第一种内存模型 #include<stdio.h> #include<stdlib.h> //说明:①:类似于int a[5]={0},数组名a是一维数组a中首元素 ...

  9. c语言内存模型

    文章一.C语言的内存分配模型 1.程序代码区:存放函数体的二进制代码. 2.全局区数据区:全局数据区划分为三个区域.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化 ...

随机推荐

  1. position: fixed用在iframe里面失效了

    iframe真是各种坑啊,,,可是找不到别的代替 $(parent.window).scroll(function(){ $('固定元素').css({ top : $(parent.window). ...

  2. atitit.农历的公式与原理以及农历日期运算

    atitit.农历的公式与原理以及农历日期运算 1. 农历的概述1 2. 如何在电脑程序里面计算农历??1 3. 农历的公式2 4. 获取当日农历日历3 5. 历史日期公式加查表才能得到精确日期3 6 ...

  3. Android中的AlertDialog使用示例一(警告对话框)

    在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框,AlertDialog实现方法为建造者模式. ...

  4. Android中通过线程实现更新ProgressDialog(对话进度条)

    作为开发者我们需要经常站在用户角度考虑问题,比如在应用商城下载软件时,当用户点击下载按钮,则会有下载进度提示页面出现,现在我们通过线程休眠的方式模拟下载进度更新的演示,如图(这里为了截图方便设置对话进 ...

  5. [转]Design Pattern Interview Questions - Part 2

    Interpeter , Iterator , Mediator , Memento and Observer design patterns. (I) what is Interpreter pat ...

  6. Android编码规范01

    目标: 掌握Java & Android命名规范 在研究Android源代码的基础上改进命名规范 考核内容 说出四种常用的命名法 比较java和C#的命名规范的不同点 总结: 读不同程序员写的 ...

  7. Xcode 创建.a和framework静态库(转载)

    库介绍 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. iOS中的静态库有 .a 和 .framework两种形式:动态库有.dylib 和 .framew ...

  8. C#中 ??、 ?、 ?: 、?.、?[ ]

    1. 可空类型修饰符(?)引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空. 例如:string str=null; 是正确的,int i=null; 编译器就会报错. 为了使值类型 ...

  9. ORACLE opatch命令学习实践

      opatch 是ORACLE开发的用来安装,卸载,检测patch冲突.管理ORACLE所有已经安装的补丁的工具,当然这是一个命令工具.opatch命令工具一般位于$ORACLE_HOME/OPat ...

  10. fdisk添加分区引起的Linux Error: 22: Invalid argument

    在Linux服务器(虚拟机)上使用fdisk添加分区.格式化分区后,遇到了Linux Error: 22: Invalid argument错误,操作步骤如下所示 [root@oracle-serve ...