小蒙 发表于 2017-11-1 10:37:19

三种方式打印数组疑问

本帖最后由 小蒙 于 2017-11-1 10:37 编辑

        #include <stdio.h>
#include <ctype.h>

void pp(double *p, int num);

void copy_arr(double target[], double source[], int num);

void copy_ptr(double *target, double *source, int num);

void copy_ptrs(double *target, double *start, double *end);

int main(void) {
    double source = {1.1, 2.2, 3.3, 4.4, 5.5};
    double target2;
    double target3;
    double target4;
//    for (int i = 0; i < 5; ++i) {
//      printf("%p\n", &target4);
//    }

    copy_arr(target2, source, 5);
    copy_ptr(target3, source, 5);
    copy_ptrs(target4, source, source + 5);
    printf("target2:");
    pp(target2, 5);
    printf("target3:");
    pp(target3, 5);
    printf("target4:");
    pp(target4, 5);
    return 0;
}

void copy_arr(double target[], double source[], int num) {
    for (int i = 0; i < num; ++i) {
      target = source;
    }
}

void copy_ptr(double *target, double *source, int num) {
    for (int i = 0; i < num; ++i) {
      *target++ = *(source + i);
    }
}

void copy_ptrs(double *target, double *start, double *end) {
    for (; target < end;) {
      *target++ = *start++;
    }
}

void pp(double *p, int num) {
    for (int i = 0; i < num; ++i) {
      printf("%.1f ", *p++);
    }
    putchar('\n');
}

如图打印结果是

如果注释掉其他两条函数调用只打印任意一个函数,结果就是对的。

BngThea 发表于 2017-11-1 11:00:03

*target++ = *start++;
这一句改变原数组的指向,所以前面两个target的内容也被更换了,
请用一个临时指针进行操作,或者在循环结束后加一句 start -= count;//count 是循环计数值

另外,printf("%.1f ", *p++);
也会改变原来的数组指向,在循环后要加上 p -= num

橙C 发表于 2017-11-1 11:17:56

使用VS2008运行该函数

void copy_ptrs(double *target, double *start, double *end) {
    for (; target < end;) {
      *target++ = *start++;
    }
}
=========================================
double source = {1.1, 2.2, 3.3, 4.4, 5.5};假设地址: 0x2afa70
    double target2;   假设地址: 0x2afa40
    double target3;    假设地址: 0x2afa10
    double target4;   假设地址: 0x2af9e0
========================================
该函数会赋值
0x2af9e0 到 0x2afa98 的内存块....
也就是就说 source, target2, target3, target4数组所有值都改变了..
还改变了其他的内存块..source之前的40个字节内存..
我比较好奇的是..竟然没有崩溃~{:10_269:}

小蒙 发表于 2017-11-1 11:46:14

BngThea 发表于 2017-11-1 11:00
*target++ = *start++;
这一句改变原数组的指向,所以前面两个target的内容也被更换了,
请用一个临时指 ...

不理解,我全程操作的是指向数组的指针,指针给数组元素赋值,指针是改变了,但是数组本身的地址(即数组首元素的地址)是常数,函数怎么还能改变数组的指向呢?

BngThea 发表于 2017-11-1 11:49:37

小蒙 发表于 2017-11-1 11:46
不理解,我全程操作的是指向数组的指针,指针给数组元素赋值,指针是改变了,但是数组本身的地址(即数组 ...

你将一个数组名作为指针传递到函数中,然后对这个指针进行了自增运算,你说它变了没有?

你若不信的话,可以写个小程序查看一下地址是否有变化

小蒙 发表于 2017-11-1 12:04:44

本帖最后由 小蒙 于 2017-11-1 12:06 编辑

BngThea 发表于 2017-11-1 11:49
你将一个数组名作为指针传递到函数中,然后对这个指针进行了自增运算,你说它变了没有?

你若不信的话 ...

    double source = {1.1, 2.2, 3.3, 4.4, 5.5};
    printf("before:");
    printf("%p\n", source);
    change(source);
    printf("after: ");
    printf("%p\n", source);
    return 0;
}

void change(double *source) {
    source++;
}

但是代码中提示:

BngThea 发表于 2017-11-1 12:21:31

小蒙 发表于 2017-11-1 12:04
但是代码中提示:

你随便操作一下
double a = *source++;
printf("%lf",&a);

小蒙 发表于 2017-11-1 12:23:01

橙C 发表于 2017-11-1 11:17
使用VS2008运行该函数

void copy_ptrs(double *target, double *start, double *end) {


我刚才打印看了,source确实被改变了,不懂……

橙C 发表于 2017-11-1 12:30:15

本帖最后由 橙C 于 2017-11-1 12:31 编辑

小蒙 发表于 2017-11-1 12:23
我刚才打印看了,source确实被改变了,不懂……

改成这样..就符合你的要求..

void copy_ptrs(double *target, double *start, double *end) {
    for (; start< end;) {
      *target++ = *start++;
    }
}

小蒙 发表于 2017-11-1 13:00:23

BngThea 发表于 2017-11-1 12:21
你随便操作一下

https://i.loli.net/2017/11/01/59f954d7a6b0d.png

小蒙 发表于 2017-11-1 13:07:03

橙C 发表于 2017-11-1 12:30
改成这样..就符合你的要求..

void copy_ptrs(double *target, double *start, double *end) {


我怎么感觉跟我的代码一样呢{:10_243:}

橙C 发表于 2017-11-1 13:07:50

小蒙 发表于 2017-11-1 13:07
我怎么感觉跟我的代码一样呢

写程序..不认真的话..什么都是错的..在仔细看看...{:10_243:}

小蒙 发表于 2017-11-1 13:31:34

橙C 发表于 2017-11-1 13:07
写程序..不认真的话..什么都是错的..在仔细看看...

target和end根本就是两个东西,多谢多谢!
页: [1]
查看完整版本: 三种方式打印数组疑问