Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4151914
  • 博文数量: 447
  • 博客积分: 1241
  • 博客等级: 中尉
  • 技术积分: 5786
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-27 06:48
个人简介

读好书,交益友

文章分类

全部博文(447)

文章存档

2023年(6)

2022年(29)

2021年(49)

2020年(16)

2019年(15)

2018年(23)

2017年(67)

2016年(42)

2015年(51)

2014年(57)

2013年(52)

2012年(35)

2011年(5)

分类: C/C++

2012-01-27 11:08:00

在大学里断断续续学过谭浩强的那本c语言,当时用的计算机是VAX,性能很不错,大家还用16位dos的时候 ,我已经用上了32位的小型机。以后跟着老婆又学了一遍c语言,谭浩强的那本c语言我都翻烂了。以后用了2年c语言后,广泛使用c++,接着转向了java。
我自认为我的c语言还不错,但是遇到这个问题,发现我的c语言的很多基础知识还是不很清楚。
用空格拆分字符串
char *message = "savvd ssfsf vdvdv";
char *ptr,*a=message;
while(ptr=strchr(a,' '))
{
*ptr='\0';
printf("%s\n",a);
a=ptr+1;
}
printf("%s\n",a);
运行就崩溃了,改为这样
char message[] = "savvd ssfsf vdvdv";

char *ptr,*a=message;
while(ptr=strchr(a,' '))
{
*ptr='\0';
printf("%s\n",a);
a=ptr+1;
}
printf("%s\n",a);

搬家的时候,谭浩强的那本c语言被卖了,找了本c primer plus看,明白了字符串常量string constant,又称为 string literal,是双引号内的字符,编译器自动加上后面的'\0'。被引用的字符串存放在可执行文件的数据段部分,被称为静态存储区。数组初始化是从静态存取区把一个字符串复制给数组,指针初始化只是复制字符串的地址,这段文字我肯定看过,因为我一直使用char *message ,就是为了提高效率,但是静态存储区是不运行修改的,所以*ptr='\0';肯定会出问题。
和光明兄聊了一下,看看汇编就知道了,我只有windows 通过vc反汇编
void a()
{
00401000  sub         esp,10h
00401003  mov         eax,dword ptr [___security_cookie (403000h)]
00401008  xor         eax,esp
0040100A  mov         dword ptr [esp+0Ch],eax
 
  char message[] = "123 456 789";
这个字符串是入栈的,0ch是9个字符加2个空格,然后对齐,是12
 char *message = "123 456 789";
反汇编是 0040100A  mov         edi,offset string "123 456 789" (4020E4h)
感觉gcc编译的比较怪异
set dis intel 设置汇编格式为intel
 disas
结果
0x00401318 : push   ebp
0x00401319 : mov    ebp,esp
0x0040131b : sub    esp,0x28
0x0040131e : mov    DWORD PTR [ebp-0x14],0x403024
0x00401325 : mov    eax,DWORD PTR [ebp-0x14]
0x00401328 : mov    DWORD PTR [ebp-0xc],eax
0x0040132b : jmp    0x401348
0x0040132d : mov    eax,DWORD PTR [ebp-0x10]
0x00401330 : mov    BYTE PTR [eax],0x0
0x00401333 : inc    DWORD PTR [ebp-0x10]
0x00401336 : mov    eax,DWORD PTR [ebp-0xc]
0x00401339 : mov    DWORD PTR [esp],eax
0x0040133c : call   0x4019c4
0x00401341 : mov    eax,DWORD PTR [ebp-0x10]
0x00401344 : inc    eax
0x00401345 : mov    DWORD PTR [ebp-0xc],eax
0x00401348 : mov    DWORD PTR [esp+0x4],0x20
0x00401350 : mov    eax,DWORD PTR [ebp-0xc]
0x00401353 : mov    DWORD PTR [esp],eax
0x00401356 : call   0x4019bc
0x0040135b : mov    DWORD PTR [ebp-0x10],eax
0x0040135e : cmp    DWORD PTR [ebp-0x10],0x0
0x00401362 : jne    0x40132d
0x00401364 : mov    eax,DWORD PTR [ebp-0xc]
0x00401367 : mov    DWORD PTR [esp],eax
0x0040136a : call   0x4019c4
0x0040136f : leave 
0x00401370 : ret   
看了一下strtok函数 也是如此    

If string is not NULL, the function scans string for the first occurrence of any character included in delimiters. If it is found, the function overwrites the delimiter in string by a null-character and returns a pointer to the token, i.e. the part of the scanned string previous to the delimiter. 字符串常量是不能overwirte的!!!,所以得用char buf[]。



阅读(4206) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~