| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1026 人关注过本帖
标题:关于指针,函数,数组的程序
只看楼主 加入收藏
晴天一阵
Rank: 2
等 级:论坛游民
帖 子:40
专家分:24
注 册:2011-5-21
收藏
得分:0 
路过。。
2011-09-08 21:39
xd1103121524
Rank: 2
等 级:论坛游民
帖 子:27
专家分:49
注 册:2011-8-29
收藏
得分:2 
楼主,那个指针已经移动了位置,这个输出是不可预测的。。。。。
2011-09-08 21:53
xd1103121524
Rank: 2
等 级:论坛游民
帖 子:27
专家分:49
注 册:2011-8-29
收藏
得分:0 
#include <stdio.h>

void copy_ptr(double *,double *,int);
int main(void)
{
    double source[8]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8};
    double target[3] = { 0.0, 0.0, 0.0};
    //int i;
        copy_ptr(&source[2],target,3);
    return 0;
}


void copy_ptr(double *source,double * target,int n)
{
    int i;

    double *p;
     p=target;
   
    for(i=0;i<n;i++)
         *target++ = *source++;
   
    for(i=0;i<3;i++)
         printf("%.2lf ",*target++);
    putchar('\n');
   
   
    target=p;
    for(i =0; i< 3; i++)
         printf("%.2lf ", target[i]);
    puts("");
   
        
}
2011-09-08 21:56
scott_dw
Rank: 2
等 级:论坛游民
帖 子:35
专家分:52
注 册:2011-8-30
收藏
得分:0 
回复 楼主 hanxiaokun
靠,这是我的帖子!怪不得那么眼熟呢。
问题就是出在++运算符,越界了。
2011-09-08 22:25
hanxiaokun
Rank: 2
等 级:论坛游民
帖 子:44
专家分:56
注 册:2011-8-31
收藏
得分:0 
回复 7楼 A13433758072
其实我以前恢复那位原始发布这个程序的人的时候已经知道输出越界,关键是在这种越界的情况下为什么输出会从souce数组的开头输出呢,这点我不太明白
2011-09-09 07:59
hanxiaokun
Rank: 2
等 级:论坛游民
帖 子:44
专家分:56
注 册:2011-8-31
收藏
得分:0 
回复 14楼 scott_dw
朋友,我以前恢复你的时候早就说明原因了,只不过我不知道在这种越界的情况下输出为什么会从souce数组的开头开始输出
2011-09-09 08:02
hanxiaokun
Rank: 2
等 级:论坛游民
帖 子:44
专家分:56
注 册:2011-8-31
收藏
得分:0 
各位兄弟,我不理解的是在这种越界的情况下为什么会转从souce数组的开头开始输出
2011-09-09 08:27
hanxiaokun
Rank: 2
等 级:论坛游民
帖 子:44
专家分:56
注 册:2011-8-31
收藏
得分:0 
各位兄弟,在这种越界的情况下程序为什么会转从souce数组的开头输出,这个是我不明白的啊
2011-09-09 08:35
tisyang
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:132
专家分:737
注 册:2011-5-7
收藏
得分:10 
你可以每次操作打印source和target 的地址的,因为地址的排布问题,这种情况是这样的
程序代码:
#include <stdio.h>

void copy_ptr(double *,double *,int);
int main(void)
{
  double source[8]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8};
  double target[3];
  //int i;
  copy_ptr(&source[2],target,3);
  return 0;
}


void copy_ptr(double *source,double * target,int n)
{
  int i;
  puts("\n==== Before the copy operation =====");
  printf("*source* is AT: %p, *target* is AT: %p\n", source, target);

  for(i=0;i<n;i++)
    *target++ = *source++;

  puts("\n==== Middle in the operation =====");
  printf("*source* is AT: %p, *target* is AT: %p\n", source, target);

  for(i=0;i<3;i++)
    printf("%.2lf ",*target++);
  putchar('\n');

  puts("\n==== End of the operation =====");
  printf("*source* is AT: %p, *target* is AT: %p\n", source, target);
  
        
}


如果是普通编译的话 输出:
程序代码:
$ gcc -o test_double_cp double_cp.c

$ ./test_double_cp.exe

==== Before the copy operation =====
*source* is AT: 0022FF20, *target* is AT: 0022FEF8

==== Middle in the operation =====
*source* is AT: 0022FF38, *target* is AT: 0022FF10
1.10 2.20 3.30

==== End of the operation =====
*source* is AT: 0022FF38, *target* is AT: 0022FF28



如果开启 gcc 的优化选项 O2 输出是:
程序代码:
$ gcc -O2 -o test_double_cp double_cp.c

$ ./test_double_cp.exe

==== Before the copy operation =====
*source* is AT: 0022FF08, *target* is AT: 0022FF38

==== Middle in the operation =====
*source* is AT: 0022FF20, *target* is AT: 0022FF50
0.00 0.00 0.00

==== End of the operation =====
*source* is AT: 0022FF20, *target* is AT: 0022FF68


如果开始 gcc 的优化选项 O3 输出是:
程序代码:
zhd@TISYANG ~/source/temp_cpp
$ gcc -O3 -o test_double_cp double_cp.c

zhd@TISYANG ~/source/temp_cpp
$ ./test_double_cp.exe

==== Before the copy operation =====
*source* is AT: 0022FEF8, *target* is AT: 0022FF28

==== Middle in the operation =====
*source* is AT: 0022FF10, *target* is AT: 0022FF40
0.00 1.#R 0.00

==== End of the operation =====
*source* is AT: 0022FF10, *target* is AT: 0022FF58


你可以看下 内存地址的变化情况,在普通情况下,开始的时候 source 比 target 大 40 个字节
在开启了 O2 优化的时候 source 比 target 要小 32 个字节。
收到的鲜花
  • hanxiaokun2011-09-09 10:33 送鲜花  3朵   附言:好文章

C++ 用无参数构造函数生成对象时候请勿在构造函数后添加无用的那一对括号,否则有可能会被当成函数声明而忽略,嗯,栈上构建的时候就是这样。
2011-09-09 08:52
tisyang
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:132
专家分:737
注 册:2011-5-7
收藏
得分:0 
可以分析下普通编译时候的情况
==== Before the copy operation =====
*source* is AT: 0022FF20, *target* is AT: 0022FEF8

==== Middle in the operation =====
*source* is AT: 0022FF38, *target* is AT: 0022FF10
1.10 2.20 3.30

==== End of the operation =====
*source* is AT: 0022FF38, *target* is AT: 0022FF28

复制前,source 比 target 大 0x28 也就是 40个字节, 复制过程中, source 和 target 都向后移动了 3*sizeof(double) 也就是24个字节(32位编译器上)
此时 target 变成了 0x0022FF10,也就是比 原本 source 0x0022FF20 要小 16 个字节 也就是 2个 double 变量的位移。
那么 首先需要注意的是,这里所有的地址都是 copy_ptr 函数中,与主函数中的数组地址没有必然的关联性。
这里的 source 应该是 主函数中 source[] 数组的 第3个元素的 的位置(因为传递的参数是 source[2])
那么比 source[2] 要小两个double 位移的地址就是 source[0] 的地址。
也就是说 这个赋值操作完成后, target 指针指向的就是 source[0] 的位置。
这下能明白了吗

C++ 用无参数构造函数生成对象时候请勿在构造函数后添加无用的那一对括号,否则有可能会被当成函数声明而忽略,嗯,栈上构建的时候就是这样。
2011-09-09 09:08
快速回复:关于指针,函数,数组的程序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025167 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved