2013-04-13 2 views
0

Я действительно в недоумении об этой программе. Я хочу, чтобы он возвращал адрес целочисленного массива из 5 элементов. Но это просто не работает. Как заставить функцию C вернуть адрес массива вместо адреса его первого элемента (базового адреса)? Я знаю, что оба они одинаковы, но их типы разные, поэтому я спрашиваю.В C, как мне заставить эту программу возвращать адрес массива, а не адрес первого элемента?

Кроме того, чтобы указать, как объявить прототип таких функций? Я понимаю, как объявить часть аргумента прототипа (используя абстрактные деклараторы), но просто не знаю, как объявить тип возврата, если мы чтобы возвращать адреса массивов или функций. Я знаю только, что если мы помещаем '*' перед именем функции в объявлении, это означает, что функция возвращает указатель на соответствующий первичный тип данных, такой как int, char или float.

#include<stdio.h> 

    int (*)[5]fun(int (*)[5]); 

    int main(void) 
    { 

    int arr[5]; 

    printf("%u",fun(&arr)); 

    } 

    int (*)[5]fun(int (*arr_add)[5]) 
    { 
    return arr_add; 
    } 

HELLO !!DANIEL FISCHER Спасибо за ваш ответ. Вы ответили на него точно и кратко. Но я выбираю ответ H2CO3, поскольку этот блестящий венгерский ребенок взял на себя труд, чтобы подробно объяснить это мне через чат. трудно выбрать лучший ответ, когда так много ярких людей отвечают. Спасибо всем!

+0

Я уверен, что (*) [5] перед именем функции в объявлении абсолютно абсурд. Я могу чувствовать запах. Но как мы это делаем, если хотим упомянуть, что функция будет возвращать вещи, отличные от простых указателей на int, char или float? Как мы обозначаем, что он должен возвращать адрес массива или адрес функции? –

+0

Не являются ли типы «& array_name» и «array_name» разными по типу? Поскольку «& array_name + 1» и «array_name + 1», безусловно, отличаются друг от друга, как и предыдущие приращения по размеру массива, а последние увеличиваются по размеру одного элемента. –

+0

Да, они разные. Один из них - 'int [5]', который может распасться на 'int *', другой - 'int (*) [5]'. – 2013-04-13 08:27:40

ответ

1

Здесь вы:

int (*fun(int (*arr)[5]))[5] 
{ 
    return arr; 
} 

Если вы хотите, чтобы вернуть адрес первого элемента (в отличие от адреса самого массива), это другой тип:

int *fun(int (*arr)[5]) 
{ 
    return &(*arr)[0]; 
} 
+0

Но вы возвращаете адрес указателя в «return & (* arr) [0] !! –

+0

@SheerFish №' arr' - указатель на массив из 5 'int'. Итак,' * arr' - это массив из 5 'int'. Таким образом,' (* arr) [0] 'является первым элементом массива из 5' int'. И '& (* arr) [0]' является адресом этого элемента, который, при возврате из функции, распадается на 'int *'. Пожалуйста, не научите меня C. – 2013-04-13 08:38:41

+0

Я плохой! Я полностью пропустил этот момент. Но сэр, чтобы выразить это окончательно, нельзя явным образом объявить в объявлении функции что функция возвращает адрес самого массива (типа int (*) []), а не адрес первого элемента массива (типа int *)? –

1

Это неправильно:

printf("%u",fun(&arr)); 

Это должно быть действительно:

printf("%p", (void*)fun(&arr)); 

В адрес массива, он будет таким же, как адрес его первого элемента.

Теперь, объявление и определение действительно должны выглядеть следующим образом:

int (*fun(int(*)[5]))[5]; 

Fixed код:

#include<stdio.h> 

int (*fun(int (*)[5]))[5]; 

int main(void) 
{ 
    int arr[5]; 

    printf("%p\n", (void*)fun(&arr)); 
} 

int (*fun(int (*arr_add)[5]))[5] 
{ 
    return arr_add; 
} 

ideone

+0

Но разве «& arr» и «arr» разные, поскольку у них разные типы? +1 и & arr + 1 наверняка означают разные вещи.Один увеличивает размер одного элемента, а другой увеличивает размер массива. –

+0

@SheerFish Да, точно. Типы разные, значения одинаковые. – 2013-04-13 08:26:55

+0

Я обновил/исправил ответ. Типы '& arr' и' arr' различны, но значения указателя совпадают. –

3

Возможно объяснить, как это работает, некоторые используют.

Идея синтаксиса объявления C заключается в том, что «имитация объявления использует».Итак, вы хотите

  • функция

    fun() 
    
  • принимает указатель на массив из пяти int

    fun(int (*arr)[5]) // or without argument name fun(int(*)[5]) 
    
  • и возвращает указатель

    (*fun(int (*arr)[5])) 
    
  • на массив из пяти

    (*fun(int (*arr)[5]))[5] 
    
  • int

    int (*fun(int (*arr)[5]))[5]; 
    

Или, вы можете также перейти от результата, который должен быть указателем на массив из пяти int,

int (*result)[5]; 

и заменить result на th е вызова (result = fun(arr))

int (*fur(arr))[5]; 

, а затем добавить тип аргумента/заменить аргумент с типом:

int (*fun(int(*)[5]))[5]; 
+1

+1, хорошо объяснено. – 2013-04-13 09:34:02

Смежные вопросы