免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: zhangsuozhu
打印 上一主题 下一主题

求高手给个价,能写这样代码的程序员月薪应该给多少? [复制链接]

论坛徽章:
0
101 [报告]
发表于 2010-07-21 22:33 |只看该作者
表现一下时能写这个就可以了,给6K,再入门观察一阵子

论坛徽章:
0
102 [报告]
发表于 2010-07-21 22:39 |只看该作者
老实说,我水平比他低,他写的全然看不懂

目前6k

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
103 [报告]
发表于 2010-07-21 23:26 |只看该作者
回复 100# pandaiam

1. 这东西叫什么名字我忘了…… 有点像转义

  1. int a = '\x12';
  2. int b = 0x12;
  3. assert( a==b );
复制代码

  1. char const* a = "\x12\x12";
  2. char const b[] = { 0x12, 0x12, 0x0 };
  3. assert( strlen(a)==strlen(b) );
  4. assert( strlen(b)+1==sizeof b );
  5. assert( memcmp(a, b, sizeof b) == 0 );
复制代码
2. 类型的表示

假设int是4字节, 且用二进制补码表示。

  1. int a = 0x120326;
  2. // a是由4个字节组成, 从高权到低权依次是0x00, 0x12, 0x03, 0x26。
  3. // 如果是大端, 内存中的布局是高权在低地址

  4. unsigned char b[] = {0x00, 0x12, 0x03, 0x26 };
  5. assert( memcmp(&a, b, sizeof a) == 0 );

  6. // 如果是小端, 内存中的布局是低权在低地址

  7. unsigned char b[] = {0x26, 0x03, 0x12, 0x00};
  8. assert( memcmp(&a, b, sizeof a) == 0 );
复制代码
3. 数组与指针

数组与指针的区别可以说一大堆。
但最容易理解的, 恰好是它们在结构中的不同行为。

  1. typedef struct
  2. {
  3.       int  i;
  4.       char c[8];
  5. } A;
  6. typedef struct
  7. {
  8.       int   i;
  9.       char* c;
  10. } B;
复制代码
还是设int是4字节, A的布局是:

  1. ?? ?? ?? ?? ?? ?? ?? ?? ... ???
  2. <-   i   -> <-  8字节 c      ->
  3. <             A              ->
复制代码
再设指针也是4字节, 且对齐需求与int相同, 那B的布局是:

  1. ?? ?? ?? ?? ?? ?? ?? ??
  2. <-   i   -> <-  c    ->
  3. <          B         ->
复制代码
这样, 下面的代码应该就好理解了:

  1. char layout[sizeof(A)] = { 0x26, 0x03, 0x12, 0x00, 'h' , 'e' , 'l', 'l', 'o', ' ', 'c', 0 };
  2. A a;
  3. memcpy(&a, layout, sizeof a);
复制代码
前4个字节是i, 所以复制完毕后, a.i就是0x00120326(小端, 其他假设同上)。
a.c就是余下的内容, 一个c-style-string "hello c"

将中间的layout步骤省去:

  1. A a;
  2. memcpy(&a, "\x26\x03\x12\x00hello c\x00" , sizeof a);
复制代码
就差不多是那个样子了。
最后一个\x00是多余的, "literal" 本来末尾就有一个0。


4. flexible array member

  1. A a;
  2. assert( a.c == (char*)&a + offsetof(A, c) );
复制代码
即a.c的地址, 是a的地址加上c在A中的偏移。

  1. B b;
  2. char* p = *(char**)( (char*)&b + offsetof(B, c) );
  3. assert( b.c == p );
复制代码
将c在B中的偏移处的内容, 理解为一个指针, 该指针的值就是b.c的地址。

故A可以存放一个整数与一个长度不超过7的c-style-string。
而B可以存放一个整数与一个指针, 指针由可以存放另一块内存的地址。

上面的a的布局是:

  1. 0x26 0x03 0x12 0x00 "hello c"
  2. <-        i      -> <-  c  ->
  3. <          a         ->
复制代码
而B的布局:

  1. B b;
  2. b.i = 0x120326;
  3. void* p = malloc( sizeof("hello c") );
  4. b.c = p;
  5. memcpy(p, "hello c", sizeof("hello c") );

  6. 0x26 0x03 0x12 0x00 pp pp pp pp
  7. <-        i      -> <- 值是p ->
  8. <-                 b         ->

  9. p :
  10. "hello c"
复制代码
a中, 0x120326和 "hello c"的地址是连续的
b中, 它们可能是分离的。


而以前的一些"聪明"的C程序员这样来实现一个变长且连续的整数、字符串pair:

  1. A* pa = malloc( offsetof(A, c) + 12 );
复制代码
那么*pa的布局就是:

  1. pa:
  2. ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
  3. <-   i   -> <-     c             -> <- rest  ->
复制代码
理论上, pa->c只有8字节。
但pa->c是这8字节的首地址。
再根据指针运算, pa->c[8]就是rest的首地址。
所以, 通过pa->c, 其实可以操纵rest部分。
pa就可以存放一个整数与一个长度不超过11的c-style-string。

理论上, pa->c确实是一个8字节的数组, 但被当成了12字节的数组。
虽然大部分情况下不会出问题, 但这毕竟是一个类型漏洞, 说不通。
比如, C89没有规定C实现一定不能添加数组长度检查。
如果真有C编译器去实现了, 代码就要挂。


所以, C99把这个行为标准化, 称为flexible array member。
语法是不指定维度:

  1. typedef struct
  2. {
  3.       int i;
  4.       char c[];
  5. } A99;
复制代码
这样, 编译器必须让这种"末尾是一个不定长成员"的做法合法。

C要求数组的维度>=1, 0长数组是gcc的方言。

论坛徽章:
3
巳蛇
日期:2013-10-03 10:41:48申猴
日期:2014-07-29 16:12:04天蝎座
日期:2014-08-21 09:24:52
104 [报告]
发表于 2010-07-21 23:40 |只看该作者
哇塞。
谢谢,谢谢。
俺要仔细理解一下。{:3_200:}

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
105 [报告]
发表于 2010-07-22 00:08 |只看该作者
#include <stdio.h>

int main(void)
{
    printf("Hello World!\n");
    return 0;
}
这段代码肯定比楼主的更值钱.

论坛徽章:
0
106 [报告]
发表于 2010-07-22 00:26 |只看该作者
回复 97# zhangsuozhu


    用零长数组与直接用字符指针有什么区别? 这里如果用字符指针替换,有什么不同?

论坛徽章:
1
天蝎座
日期:2014-02-28 16:08:53
107 [报告]
发表于 2010-07-22 09:22 |只看该作者
回复 108# nine8


    指针会占内存,

论坛徽章:
0
108 [报告]
发表于 2010-07-22 09:22 |只看该作者
暂不说大小端。
莫名其妙的void*转换……
莫名其妙的一个追加0:"\x01\x00\x00\x00Hello World!\n\x0" … ...
OwnWaterloo 发表于 2010-07-21 22:11



    memcpy(拷贝内存内容)
相关函数         bcopy,memccpy,memcpy,memmove,strcpy,strncpy
表头文件         #include<string.h>
定义函数         void * memcpy (void * dest ,const void *src, size_t n);
函数说明         memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'\0'而结束。

论坛徽章:
0
109 [报告]
发表于 2010-07-22 09:39 |只看该作者
我在 读 你们的 心理
ssuclinux 发表于 2010-07-21 17:05



    小心被怡笑大方了!

论坛徽章:
0
110 [报告]
发表于 2010-07-22 10:05 |只看该作者
回复  pandaiam

1. 这东西叫什么名字我忘了…… 有点像转义2. 类型的表示

假设int是4字节, 且用二进 ...
OwnWaterloo 发表于 2010-07-21 23:26



    学习~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP