当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 6 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 字符数组和字符指针在这段代码中的区别
帖子发表于 : 2010-10-14 13:10 

注册: 2010-04-01 17:23
帖子: 26
送出感谢: 0 次
接收感谢: 0 次
#include <stdio.h>
#include <string.h>

int main()
{
char s[] = "hello! let us study c.";
//char * s = "hello! let us study c.";
memset(s, 'G', 6);
printf("%s\n", s);

return 0;
}

如代码所示,若采用注释掉的那一句char * s,则运行的时候会出现 段错误。而采用char s[]则运行无误,请问这两者有什么区别呢?

memset的原型如下:
#include<string.h>
void * memset(void *s, int c, size_t n);

谢谢!


页首
 用户资料  
 
2 楼 
 文章标题 : Re: 字符数组和字符指针在这段代码中的区别
帖子发表于 : 2010-10-14 19:54 
头像

注册: 2009-07-07 19:52
帖子: 240
送出感谢: 0 次
接收感谢: 0 次
我的水平有限,尝试着解释一下这个问题,如果有错误,欢迎大家指正。

char * s = "hello! let us study c.";
这时,s 是一个指针,它指向的是一个静态数据。
一个可执行程序,它是包含数据段和代码段的。对于程序里用到的静态数据(如:char * s = "hello! let us study c.";),在编译后,会把数据存储在数据段里,而这个数据是不可更改的。

char s[] = "hello! let us study c.";
这时,s 是一个数组。程序在内存分配一个数组空间,并将数据存进去,这时,你可以把它当做一个数组来使用。所以用 memset 是不会崩溃的。


_________________
阿呆 : 天下第一呆!


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 字符数组和字符指针在这段代码中的区别
帖子发表于 : 2010-10-15 16:03 
头像

注册: 2008-12-24 12:02
帖子: 108
送出感谢: 1
接收感谢: 4
c 語言標準就是如此。通過聲明指針是初始化的數據和通過聲明數組初始化的數據是放在兩個不同屬性的段中的。通過聲明數組初始化的數據放入可寫段,而通過聲明指針的初始化數據放入不可寫的段。你去寫,cpu就異常,然後就報段保護錯誤。
另外,就數組和指針本身來說,本來就是兩回事麼。:-)


_________________
機器生命


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 字符数组和字符指针在这段代码中的区别
帖子发表于 : 2010-10-15 21:22 

注册: 2010-04-01 17:23
帖子: 26
送出感谢: 0 次
接收感谢: 0 次
Kandu 写道:
c 語言標準就是如此。通過聲明指針是初始化的數據和通過聲明數組初始化的數據是放在兩個不同屬性的段中的。通過聲明數組初始化的數據放入可寫段,而通過聲明指針的初始化數據放入不可寫的段。你去寫,cpu就異常,然後就報段保護錯誤。
另外,就數組和指針本身來說,本來就是兩回事麼。:-)



嗯,你说的有道理。不过不清楚具体是怎么分配内存的。


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 字符数组和字符指针在这段代码中的区别
帖子发表于 : 2010-10-16 12:32 
头像

注册: 2008-12-24 12:02
帖子: 108
送出感谢: 1
接收感谢: 4
分配方式如下,例如:
代码:
char *str_a="show";
char str_b[]="me";

int main(void)
{
  char *str_c= "the";
  char str_d[]= "money";
  return 0;
}

執行
gcc -S test.c
得到
代码:
    .file    "test.c"
.globl str_a
    .section    .rodata        /*使得下面的數據存入只讀數據段*/
.LC0:
    .string    "show"            /*於是 "show" 就被存入只讀段了*/
    .data                /*使得下面的數據存入普通數據段*/
    .align 4
    .type    str_a, @object
    .size    str_a, 4
str_a:
    .long    .LC0
.globl str_b
    .type    str_b, @object
    .size    str_b, 3
str_b:
    .string    "me"            /*於是 "me" 就被存入普通數據段了*/
    .section    .rodata        /*使得下面的數據存入只讀數據段*/
.LC1:
    .string    "the"            /*於是 "the" 就被存入只讀數據段*/
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    $.LC1, -4(%ebp)
    movl    $1701736301, -10(%ebp)    /* "money" 去哪裡了?“錢沒了呀”。因為它在函數內部聲明,所以被分配到棧,因為棧頂部的具體位置是在函數被調用後才能得知(通過 esp),所以需要通過指令來初始化這個數據。從上面的 movl %esp, %ebp 可知,此時 %ebp指向棧,所以直接通過 %ebp 向棧寫入 money 的數值。*/
    /*$1701736301 的值就是 "mone",去對照下 ascii 表*/
    movw    $121, -6(%ebp)        /*然後寫入 'y' 加上一個0,因為使用 movw,為雙字節,$121 的高字節部分就是0,所以字符串寫入完成。一個正常的操作系統在給棧段的屬性都是可寫的。*/
    movl    $0, %eax
    leave
    ret
    .size    main, .-main
    .ident    "GCC: (GNU) 4.5.1"
    .section    .note.GNU-stack,"",@progbits

/*另外的說明,為何 "the" 這個字符串不存入棧?它是通過聲明指針初始化的,所以得存入只讀數據段*/


_________________
機器生命


最后由 Kandu 编辑于 2011-11-06 10:04,总共编辑了 2 次

页首
 用户资料  
 
6 楼 
 文章标题 : Re: 字符数组和字符指针在这段代码中的区别
帖子发表于 : 2010-10-17 17:29 
头像

注册: 2007-09-23 17:06
帖子: 1051
送出感谢: 1
接收感谢: 8
好强悍,回来研究研究。。。。。。。。。。


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 6 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译