简单的一道题目

whillcoxdennis 2010-09-11 01:34:32


#include <stdio.h>

void f(char * str1, char ** r1)
{
*r1 = str1;
printf("%s",*r1);
}

void main()
{
char str1[10] = "abcdadfsd";
char ** r1 =(char**)&str1;
f(str1, r1);
printf("%s", *r1);
}


谁能给我详细解释下r1 str1在main函数 和 在子函数中的内容以及指向的内容呢?
又有点糊涂!
...全文
201 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
haogeai123 2010-09-11
  • 打赏
  • 举报
回复
#include <stdio.h>

void f(char * str1, char ** r1)
{
*r1 = str1;
printf("%s",*r1);
}

void main()
{
char str1[10] = "abcdadfsd";
char ** r1 =(char**)&str1;
f(str1, r1);//str1指向str1[0]的地址,r1指向str1[0]的元素的地址
printf("%s", *r1);
}

saishow 2010-09-11
  • 打赏
  • 举报
回复
学习了 。。。
whillcoxdennis 2010-09-11
  • 打赏
  • 举报
回复
谢谢楼上的各位i
下面是我对这个程序的理解:

1,字符串指针与字符数组名不同:
首先,很明显是关于结束符;
char * pstr = "abcdef";
char sarray[]={'a','b','c','d','e','f'};
2,字符串存储位置不同,指针是存储在常量区,应用子函数是不能改变内容的;后者则是存储在栈上,可以在子函数中修改内容;
3,pstr这个指针的地址是存储在相邻的栈上的,而sarray只是字符串首地址,没有存储位置。
指向指针的指针
char **p_st = &pstr; 是可以的
但是
char **p_st =reinterpret_cast<char**> &sarray; 只是将sarray的首地址给了p_st;
王大军9527 2010-09-11
  • 打赏
  • 举报
回复
10楼是正解...

r1指向的是char*类型的指针,占四个字节大小的空间。
*r1的值是一个四字节的char*类型的值。

题目中 r1 = (char **)&str1;
让r1的值等于数组的首地址(&str1 与 str1的值是一样的,但意义不一样,如12楼所说)。
就是让r1指向了str1字符串的首地址,即*r1的值就是str1字符串的前四位,
*r1 == 0x64636261(在小端字节序机器中的值,如x86,大端字节序值0x61626364, 0x61是'a'的ASCII码值)。

在函数f()里改变r1指向的内容*r1的值,也就是字符串的前四位。
而f()里让r1指向的 *r1 = str1,是把字符串的首地址给了*r1,即是把字符串的首地址放进了字符串的前四位了,所以字符串里的前四个字节里存储的是自己的地址,按字符格式输出的话就是乱码。

可以把这些值打印出来比较一下:


#include <stdio.h>

void f(char *str1, char **r1)
{
*r1 = str1;

printf("%s\n", *r1);
}

int main()
{
char str1[100] = "abcdadsd";
char **r1 = (char **)&str1;


printf("str1's address : %p\n", str1); //打印str1的首地址
printf(" r1 : %p\n\n", r1); //r1里的值,存储的即是str1的首地址

printf(" *r1 : %p\n", *r1 ); //r1指向的地址里的值,
//*r1,即是str1里的前四个字节
printf(" str1 : 0x%x%x%x%x\n\n", str1[3], str1[2], str1[1], str1[0]); //打印str1里的前四个字节

f(str1, r1);

printf("str1's address : %p\n", str1); //str1的首地址
printf(" *r1 : %p\n", *r1); //*r1里的值,现在存放的也就是str1的首地址
char **p = (char **)str1; //结合下面一句打印字符串里的前四个字节
printf(" str1 : %p\n\n", (char *)*p); //与str1的首地址的值是一样的了

printf("%s\n", *r1);

return 0;
}

renzhewh 2010-09-11
  • 打赏
  • 举报
回复
我觉得这个程序可以作为一个陷阱 :-)
第一感觉没什么问题(本人较菜,纯粹个人体会),细看发现数据被改了
pengzhixi 2010-09-11
  • 打赏
  • 举报
回复
&str1的类型是char(*)[10];不是转成2级指针就OK得。
danfeiwll 2010-09-11
  • 打赏
  • 举报
回复
**r1是双重指针,在子函数里*r1指向数组"abcdadfsd"的首地址,即str
renzhewh 2010-09-11
  • 打赏
  • 举报
回复
具体说下(参考我机器上的数据)

一开始str1 的值是 0x0012ff54,指向'a',r1的值同 str1,也指向'a'

执行函数f
r1 ,因其指向abcd...,类型为char*,大小为4个字节,因此是将abcd作为*r1的值
即*r1值是0x64636261,即abcd的逆序(不同处理器可能不同)
很明显这个一个错误的指针, 此时执行 printf("%s",*r1); 肯定出错

但是下面这句
*r1 = str1 将其值 替换为 0x54 0xff 0x12 0x00
也就是说str1的前4个字节被改掉了
这时*r1的值为0x0012ff54,变成了合法的指针,可以打印

但是这时输出的结果就不再是 abcdadfsd了
不过如果输出 str1 + 4 倒是可以,后面的没有被改
周靖峰 2010-09-11
  • 打赏
  • 举报
回复
r1是str1的地址
str1是"abcdadfsd"的首地址

*r1就是str1
*str1就是'a'
zxk860611 2010-09-11
  • 打赏
  • 举报
回复
char ** r1 =(char**)&str1;

不可以这样强制转换……
renzhewh 2010-09-11
  • 打赏
  • 举报
回复
哦,错了 不应那么说
应该是 修改*r1,其实就是修改str1
renzhewh 2010-09-11
  • 打赏
  • 举报
回复
[code = c/c++]
str1指向'a',r1也是指向'a'
但是
void f(char * str1, char ** r1)
执行中
将*r1的值换了,成了一个可以认为是随机的值
自然str1的值也变了
[/code]

向立天 2010-09-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 whillcoxdennis 的回复:]

引用 3 楼 pengzhixi 的回复:
C/C++ code

void f(char * str1, char ** r1)
{
*r1 = str1;
printf("%s",*r1);
}

int main()
{
char str1[10] = "abcdadfsd";
char*p =str1;
char**r1=&amp;p;
f(str1,……
[/Quote]
不是什么都可以强制转换的
whillcoxdennis 2010-09-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pengzhixi 的回复:]
C/C++ code

void f(char * str1, char ** r1)
{
*r1 = str1;
printf("%s",*r1);
}

int main()
{
char str1[10] = "abcdadfsd";
char*p =str1;
char**r1=&p;
f(str1, r1)……
[/Quote]


为什么强制转换不行呢。强制转换输出的内容不对呢?
pengzhixi 2010-09-11
  • 打赏
  • 举报
回复

void f(char * str1, char ** r1)
{
*r1 = str1;
printf("%s",*r1);
}

int main()
{
char str1[10] = "abcdadfsd";
char*p =str1;
char**r1=&p;
f(str1, r1);
printf("%s", *r1);
}
冻结 2010-09-11
  • 打赏
  • 举报
回复
我认为这是一段没事瞎折腾的代码。
难道有什么高深的东西,
等楼下高手。
justkk 2010-09-11
  • 打赏
  • 举报
回复
r1是指针,可以使用%p打印看看

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧