Приведение числовых типов в C - PullRequest
0 голосов
/ 26 декабря 2009

Я пытаюсь выяснить ответ на этот вопрос с помощью следующего кода, но, оказывается, значение указателя (адрес задачи 3 оказался настолько далеко от параметра и локальных переменных функции ) где, черт возьми, x = problem3; указывает на ...

void problem3(int a) {
    int overflowme[16];
    int x = problem3; 
    overflowme[15] = 102;
    printf(" the address of  x is %x\n the addres of the first local is %x\n the addres of the first para is %x\n ", x, &overflowme[15], &a);
}

int main(void) {
    problem3(101);
}

OUTPUT
 the address of  x is 42b613
 the addres of the first local is 12fed8
 the addres of the first para is 12fee4
 Press any key to continue . . .

Ответы [ 6 ]

4 голосов
/ 26 декабря 2009

problem3 - указатель на функцию. В C, если вы используете приведение типа (int), компилятор в основном отключает все проверки типов и предполагает, что вы знаете, что делаете (даже если, как в этом случае, это не имеет смысла) - в этом случае преобразование указателя в целое число.

Итог - не используйте приведения, если только вам это действительно не нужно.

2 голосов
/ 26 декабря 2009

Можете ли вы объяснить, почему мы можем назначить x = (int) problem3 в приведенном выше коде

Поскольку problem3 - это указатель на функцию (то есть адрес памяти функции), и все указатели могут быть преобразованы в целые числа.

Разве мы не присваиваем "привет мир" х?

Нет. Однако вы можете сделать это, если захотите (выполнив x = (int) "hello world";), потому что «hello world» также является указателем (точнее указателем на char), так что вышеизложенное применимо.

1 голос
/ 26 декабря 2009

Кастинг (то, что вы делаете, когда ставите (int) перед чем-то), магический в этом смысле. Он возьмет любую вещь и превратит ее в любую другую вещь (в данном случае * 1002), независимо от того, имеет ли это смысл. Вам следует избегать использования кастинга, если вы абсолютно не уверены, что должны, и другого пути нет.

Код вашей программы существует в памяти, как и переменные. Здесь происходит то, что приведение поворачивает число, представляющее, где в памяти находится код, в целое число. Это целое число может быть больше или меньше в зависимости от того, где в памяти компилятор и компоновщик решили разместить код для функции.

Ваш оператор printf вообще не присваивает. %x - это просто заполнитель, говорящий «Возьмите один из параметров, переданных в printf, и распечатайте его здесь». Тот факт, что это 'x', не имеет ничего общего с именем переменной в вашей программе. «X» говорит: «Напечатайте это целое число в базе 16 (шестнадцатеричное) вместо обычной базы 10». Если вы введете %u или %d, он все равно будет работать, и вы получите число, представленное как целое число без знака на основе 10 или целое число со знаком в базе 10.

0 голосов
/ 26 декабря 2009

Вы печатаете адреса функций («problem3» и «main»). Эти адреса полностью зависят от компилятора и реализации, поэтому разница между 6 и 7 цифрами, с которой вы сталкиваетесь.

0 голосов
/ 26 декабря 2009

В первом примере вы назначаете адрес вашей функции problem3 для x, а затем печатаете значение этого адреса.

Приведение его к int, как правило, совершенно бесполезно. Вам редко нужно знать фактический адрес памяти функции.

Единственный раз, когда вы захотите получить адрес функции, это когда вы захотите передать его некоторым другим частям вашего кода, который вызовет функцию (выполнит ее). Проверьте эту статью для получения дополнительной информации об использовании указателей функций.

0 голосов
/ 26 декабря 2009

Во-первых, вам не хватает круглых скобок в problem3;, чтобы фактически выполнить вызов функции. Во-вторых, присвоение x = (int)problem3 назначает адрес функции problem3 для x, приведенного к int. Это совершенно законно в C, хотя я не уверен, чего вы пытаетесь достичь.

Если вы печатаете адрес функции, приведенной к типу int, и форматируете ее как шестнадцатеричное число, вы, вероятно, напечатаете адрес функции как шестнадцатеричное число. Я не уверен, почему вы удивляетесь, что число состоит из 7 цифр.

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