0

我只是好奇——为什么当一个函数需要一个指针时,C 允许你传递取消引用的指针。这是一个例子:

typedef struct {
char message[255];
} Bla;  

// so he's the function that's expecting the pointer
void cool_function(Bla *_bla) {

}

Bla *woot = (Bla *)malloc(2 * sizeof(Bla));

woot[0] = (Bla) {
    .message = "bla bla bla"
};

// woot itself is a pointer, but it's getting dereferenced when I am adding [0]
cool_function(woot[0]);

现在编译得很好,但是当我实际使用_bla(即_bla->what)时,BAM,运行时错误。

所以这让我很困惑——如果它按值传递给这个显然需要一个指针的函数,它会发生什么?为什么它甚至可以编译?

我对C相当陌生,所以请不要跳过我。:/

* 更新 *

抱歉之前没有提到,但这是 Pebble Watch 的应用程序,它使用特殊版本的 gcc 用于特定的 arm 处理器 (arm-cs-tools)。

* 更新 2 *

我想我发现了它为什么这样做。函数“cool_function”实际上是在一个单独的文件中,当我在头文件中声明该函数时,它只是用 -forgot void cool_function()to include声明的Bla *_bla。但定义是void cool_function(Bla *_bla)。混淆编译器都是我的错。

4

4 回答 4

4

你应该得到编译器错误:

error: passing 'Bla' to parameter of incompatible type 'Bla *'; take the address with &
    cool_function(woot[0]);

如果您使用 gcc 或 clang,请尝试使用 -WError 和 -Wall 选项编译您的程序。

于 2014-02-16T02:30:21.630 回答
1

C 不会给出编译错误,因为它缺少类型检查。woot[]在您的示例中,如果从系统的角度来看这些值是正确的,它甚至可能不会给出任何运行时错误

于 2014-02-16T02:33:51.707 回答
1

你需要做:

cool_function(&woot[0]);

在这种情况下 & 运算符创建一个引用。所以你传递了对 woot[0] 的引用

请注意,这意味着cool_function() 现在可以改变woot[0] 的内容。如果这是不希望的,您可能想要执行某种复制操作。

例如,您可以有一个函数,该函数采用 Bla* 将其复制到 Bla* 的新实例中——这有效地实现了按值传递。诀窍是你必须做一个副本。

或者,您可以使函数采用 const Bla* - 从技术上讲,它也不应该能够改变这些值。

于 2014-02-16T02:36:03.313 回答
1

我已经获取了您的代码并从中制作了一个完整的主文件:

#include <pebble.h>

typedef struct {
  char message[255];
} Bla;

// so he's the function that's expecting the pointer
void cool_function(Bla *_bla) {

}

int main() {
  Bla *woot = (Bla *)malloc(2 * sizeof(Bla));

  woot[0] = (Bla) {
      .message = "bla bla bla"
  };

  // woot itself is a pointer, but it's getting dereferenced when I am adding [0]
  cool_function(woot[0]);
}

这是我尝试使用 Pebble SDK 2.0.0 编译它时得到的结果:

./src/test.c: In function 'main':
../src/test.c:20:3: error: incompatible type for argument 1 of 'cool_function'
../src/test.c:8:6: note: expected 'struct Bla *' but argument is of type 'Bla'

所以看起来对你的问题的评论都是正确的。您使用的是什么版本的 SDK?

于 2014-02-17T03:12:43.033 回答