【问题标题】:funny characters output for a sum function (Φw ÅΩw) [duplicate]求和函数的有趣字符输出(Φw ÅΩw)[重复]
【发布时间】:2020-04-10 14:54:36
【问题描述】:

我有一个带有有趣字符的疯狂输出 (Φw    ÅΩw) 我可以知道代码中有什么问题吗? 可能 int main 是错误的 我必须使用 int sumArray (int * a, int len , int * sum )格式

#include <stdio.h>
#include <stdlib.h>

int sumArray(int *a, int len, int *sum) {
  int sum1 = 0;
  if (a == NULL || sum == NULL)
    return -1;
  int i;
  (*sum) = 0;
  for (i = 0; i < len; i++) {
    (*sum) += a[i];
  }

  return 0;
}

int main() {
  int *a = {1, 2, 3, 4};
  int *b;

  sumArray(&a, 4, &b);
  printf(b);
  return 0;
}

【问题讨论】:

  • sumArray() 函数中,为什么要声明sum1 变量? (我看到你没有使用它)
  • printf 需要一个char* 格式字符串。

标签: c arrays pointers


【解决方案1】:

你能试试这些改变吗?

#include <stdio.h>
#include <stdlib.h>

int sumArray(int *a, int len, int *sum) {
  // int sum1 = 0;  // i removed this variable because you are not using it
  if (a == NULL || sum == NULL)
    return -1;
  int i;
  (*sum) = 0;
  for (i = 0; i < len; i++) {
    (*sum) += a[i];
  }

  return 0;
}

int main() {
  // int *a = {1, 2, 3, 4};
  int a[] = {1, 2, 3, 4};
  int b;
  // i rather declare an integer instead of a pointer to an integer
  // when you declared int * b , this was a pointer, and your printf(b) was
  // printing an address, not the value calculated by sumArray that is why you
  // were printing funny characters

  sumArray(a, 4, &b);
  // a is already a pointer

  printf("%d", b);
  return 0;
}

【讨论】:

  • 没有给出输出
  • 是的,我发错了,printf()用错了,我会改正的
  • @alexos 你现在可以试试吗?
  • 以我想要的方式工作,谢谢!
【解决方案2】:

您正在使用未初始化的指针。创建指针时,您不知道指针指向的位置。它要么指向一些垃圾数据,要么在更糟糕的情况下,指向一个内存区域,该区域已经被您计算机中的其他程序或操作系统本身使用。

如果你真的想使用这样的指针,你应该为它们动态分配内存。

int* a = malloc( 4 * sizeof(int) );
int* b = malloc( sizeof(int) );

这确保您可以将四个整数分配给a 指向的内存区域。还有一个给b

然后您可以使用循环在该内存中漫游以分配、读取或写入数据。

for ( int i=0; i < 4; i++ )
{
    *(a + i) = i + 1;
}

这里我们有一个 for 循环,它将运行 4 次。每次我们在内存中移动一个块并将我们想要的数字放在那里。

记住,a 是一个指针,它指向一个 4 int 大小的内存区域的开始。所以为了进入下一个区块,我们用i 来偏移我们的范围。每次循环运行时,a + i 指向“数组的ith 元素”。我们正在取消引用该区域并在那里分配我们想要的值。

for ( int i=0; i < 4; i++ )
{
    printf("%d\n", *(a + i) );
}

在这里,我们使用相同的逻辑,但读取我们刚刚写入的数据。

请记住,您需要使用带有printf 函数的格式说明符才能使其正常工作。 printf() 只是读取你碰巧给它的任何数据,格式说明符帮助解释给定格式的数据。

如果您在printf 中使用%d 格式说明符时有一个类似int c = 65; 的变量,您将读取数字65。如果您在printf 中有%c 说明符,您将读取字母A,其ASCII 码恰好是 65。数据是一样的,但是你用格式说明符解释它的方式不同。

现在,您的函数 int sumArray(int *a, int len, int *sum) 接受 int 指针作为第一个参数。在主函数中,您确实有一个名为 a 的 int 指针。但是您正在传递a 的地址,这会导致双重间接,您正在传递一个指针的地址,该指针包含一个int 数组的地址。这不是你想要的,所以函数调用中的&amp; 运算符是多余的。与b 相同。

调用sumArray 应该是这样的

sumArray( a, 4, b );

最后,我们也应该修复printf。记住我所说的格式说明符。

记住b不是int,它是int*,所以如果你想得到b指向的值,你需要取消引用它。

最后,调用printf 应该是这样的

printf( "%d", *b );

此外,您应该记住释放您使用 malloc 动态分配的内存。当您使用常规数组或变量时,您的编译器会自行处理这些内容。但是,如果您动态分配内存,则必须在使用完这些指针后使用 free 释放该内存。

您可以在调用sumArrayb 之后释放a,然后终止main 函数,如

free(a);free(b);

在这类小型项目中,释放内存可能不会导致任何不良结果,但这是关于指针的一个非常重要的主题,应该正确实施,以便更好地理解指针和更好的编程实践。

在这种形式下,您的代码应该可以按预期工作。

但是...这是一个很大的但是

如您所见,为了完成如此简单的任务,我们付出的努力远比优化的多。除非您的目标是学习指针,否则这里没有理由使用指针和动态分配。你可以像上面@Hayfa 演示的那样使用常规数组,让自己免于很多麻烦。

使用指针和动态内存是一个强大的工具,但它也带来了危险。您正在使用计算机的实际物理内存。现在的编译器不会让你在尝试将两个数字相加时搞砸你的操作系统,但它仍然会导致难以检测到崩溃,尤其是在复杂程序中。

(对不起,如果阅读困难,我对Stack Overflow的文本编辑器不一定有信心。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-08
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 2020-04-01
    • 2022-11-06
    相关资源
    最近更新 更多