Функция C всегда возвращает ноль в Objective C - PullRequest
1 голос
/ 01 ноября 2009

У меня есть проект Objective C, включающий файл C с некоторыми вспомогательными функциями. У меня серьезная и очень раздражающая проблема при попытке вернуть float s из файла C.

C файл:

float returnFloat() {
    return 10.0;
}

Между тем в методе экземпляра Objective C:

float x;
x = returnFloat();

х всегда 0,000000. Есть идеи, что я делаю не так?

Редактировать

Хорошо, я понял, что у меня есть куча предупреждений о «неявном объявлении» в файле Objective C, касающихся использования функций, которые есть в файле C.

Назначения с использованием функций, которые возвращают int с, работают нормально. Если присваивание выполняется из функции, возвращающей float, отладчик говорит «переменная оптимизирована компилятором».

Вполне вероятно, что я не использую "правильный" способ включения файла C, содержащего вспомогательные функции, в проект Objective C? Я (тупо?) Просто позволил Xcode связать его автоматически. Даже если это так, почему эта проблема должна проявляться только тогда, когда функция возвращает float?

Ответы [ 5 ]

12 голосов
/ 01 ноября 2009

Вы должны использовать файл .h, как и файлы .m, чтобы объявить, что вы делаете в другом файле. Итак, вам нужно что-то вроде этого для этого сценария (они неполные):

returnfloat.c

float returnFloat() {
    return 10.0;
}

returnfloat.h

float returnFloat(void);

usefloat.m

#import "returnfloat.h"

- (void) someMethod {
    float ten = returnFloat();
}

Проблема (выдаваемая вашими предупреждениями о "неявном объявлении") заключается в том, что компилятор предполагает, что вы вызываете что-то, что возвращает int или id, а не float. Когда вы работаете с C, вещи должны быть прототипированы (GCC будет обрабатывать файл .c как C, и все правила C применяются, даже если вы находитесь в проекте Objective-C).


Если вы хотите увидеть пример, вот что-то из одного из моих проектов - рабочий код (вы можете написать чистый C в файле, заканчивающемся на .m, и GCC будет обрабатывать его как Objective-C в некотором смысле ):

DebugF.m

#import "DebugF.h"

void __Debug(const char *file, int line, NSString *format, ...) {
#ifdef DEBUG
    /* Wraps NSLog() with printf() style semantics */
#endif
}

DebugF.h

#ifndef __DEBUGF_H_INCLUDED__
#define __DEBUGF_H_INCLUDED__

#ifdef DEBUG
#define DebugF(args...) __Debug(__FILE__, __LINE__, args)
#else
#define DebugF(...)
#endif /* DEBUG */

void __Debug(const char *file, int line, NSString *fmt, ...);

#endif /* __DEBUGF_H_INCLUDED */

SomeViewController.m

DebugF(@"Got these arguments: %u, %@, %@", 4, anObject, [anObject somethingElse]);
1 голос
/ 01 ноября 2009

Я не программист Objective-C, но в мире C компилятор принимает int тип возврата для любой необъявленной функции, которую использует текущий модуль. Мне кажется, что создание обычного заголовочного файла C, содержащего:


#ifndef _MY_IMPORTANT_HEADER_
#define _MY_IMPORTANT_HEADER_
extern float returnFloat();
#endif

и включение этого в ваш файл .m должно заставить все это работать:


#include "myheader.h"
0 голосов
/ 01 ноября 2009

Как вы объявили функцию returnFloat () в своей программе Objective-C? Есть ли у прототипа по объему? Если нет, то, вероятно, ваша проблема в том, что Objective-C рассматривает функцию как возвращающую int, а не как float, и это приводит к хаосу (или вы чувствуете, что ноль возвращается).

0 голосов
/ 01 ноября 2009

Как вы определяете, что x равно 0.0000? Распространенной ошибкой при отладке является использование неверной строки формата в NSLog().

Если вы используете NSLog(), убедитесь, что вы используете %f или какой-либо его вариант:

NSLog(@"x = %f", x);

(многие люди путаются и пытаются использовать %i вместо)

РЕДАКТИРОВАТЬ: Это с предположением, что ваш прототип функции C является правильным, а отсутствие скобок было здесь просто опечаткой. Если нет, ответ Бленка, вероятно, правильный.

0 голосов
/ 01 ноября 2009

Это потому что ты хочешь:

// the c way
float returnFloat() {
   return 10.0;
}

float result = returnFloat();

// the objective-c way
- (float) returnFloat {
   return 10.0;
}

float result = [self returnFloat]; // assuming this is an object

Не то, что у вас есть. Вы смешиваете прототипы функций C с Objective-C. Попробуйте способ C, упомянутый выше (должен быть в состоянии использовать его в коде Objective C).

Извините, если я неправильно понял ваш вопрос, я почти уверен, что мой код правильный:)

РЕДАКТИРОВАТЬ : Разъяснение для всех downvoters. В своей первой редакции поста он сделал это float returnFloat {} вместо float returnFloat () {}, что вызвало мой ответ.

РЕДАКТИРОВАТЬ 2 : Очевидно, это было недостаточно ясно. В своей первой редакции своего поста он смешивал способ написания прототипов функций на языке C и способ написания прототипов функций на Objective-C. Вы МОЖЕТЕ использовать функции C в Objective-C, но НЕ МОЖЕТЕ смешивать способ написания прототипов их функций, как я объяснил выше. Извините за путаницу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...