Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
NOOBasi4
1 / 1 / 0
Регистрация: 05.05.2014
Сообщений: 38
1

Определение функции в функции допустимо?

16.06.2014, 16:11. Просмотров 1127. Ответов 14
Метки нет (Все метки)

из документации gcc

Кликните здесь для просмотра всего текста
A "nested function" is a function defined inside another function.
Nested functions are supported as an extension in GNU C, but are not
supported by GNU C++.

The nested function's name is local to the block where it is defined.
For example, here we define a nested function named 'square', and call
it twice:

C
1
2
3
4
5
6
foo (double a, double b)
{
double square (double z) { return z * z; }
 
return square (a) + square (b);
}


Но работаю я в MSVS 2012.
И там такое не прокатывает... такие приколы могу быть только в GNU С или как-то надо VS2012 настраивать для этого???
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.06.2014, 16:11
Ответы с готовыми решениями:

Табулирование заданной функции и определение максимального и минимального значения функции
Ребята, пожалуйста, помогите сделать задачи новичку, пожалуйста кто-то откликнитесь( 3....

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

Табулирование заданной функции и определение максимального и минимального значения функции в таблице
Разработать консольное приложение, производящее табулирование заданной функции и определение...

Определение экстремумов функции методом золотого сечения (переписать программу через функции)
program lab12 real,dimension(5):: p(5)=(/0,1,0,0,0/) integer::ii(3)=(/1,2,3/) real pi,...

14
Вованя
153 / 148 / 66
Регистрация: 20.02.2014
Сообщений: 555
Завершенные тесты: 1
16.06.2014, 16:21 2
NOOBasi4, такие приколы только в gnu
0
NOOBasi4
1 / 1 / 0
Регистрация: 05.05.2014
Сообщений: 38
16.06.2014, 16:36  [ТС] 3
Цитата Сообщение от Вованя Посмотреть сообщение
такие приколы только в gnu
оки.
Но у меня остаётся тогда вопрос такой... почему это компилится? как это можно использовать?

C
1
2
3
4
void foo (double a, double b)
{
    double square (int b, int c);
}
Если нельзя, исключая GNU C, писать определение в определении, но прототип в определении как видимо можно, какой смысл в этой конструкции???
0
uglyPinokkio
326 / 229 / 55
Регистрация: 30.05.2014
Сообщений: 682
16.06.2014, 16:48 4
Цитата Сообщение от NOOBasi4 Посмотреть сообщение
Если нельзя, исключая GNU C, писать определение в определении, но прототип в определении как видимо можно, какой смысл в этой конструкции???
forward declaration. Объявлен прототип функции, объявление видно только внутри блока в котором находится.
0
NOOBasi4
1 / 1 / 0
Регистрация: 05.05.2014
Сообщений: 38
16.06.2014, 17:10  [ТС] 5
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
forward declaration. Объявлен прототип функции, объявление видно только внутри блока в котором находится.
К сожалению мне не снизошло озарение... Какой смысл в это конструкции, на фиг оно нужно, что дальше с ней можно делать.
То, что прототип только в теле этой ф-ии виден я и так понимаю.

в поисках по "forward declaration", я ни чего не нашёл
0
uglyPinokkio
326 / 229 / 55
Регистрация: 30.05.2014
Сообщений: 682
16.06.2014, 17:20 6
Цитата Сообщение от NOOBasi4 Посмотреть сообщение
К сожалению мне не снизошло озарение... Какой смысл в это конструкции, на фиг оно нужно, что дальше с ней можно делать.
То, что прототип только в теле этой ф-ии виден я и так понимаю.
Смысл все тот-же объявление функции, реализованной где-то в другом месте (единице трансляции). При этом видима она только в этом блоке. Дальше ее можно вызвать, если она реализована. Необходимости применения вне пределов GCC лично я не вижу.
0
easybudda
Модератор
Эксперт JavaЭксперт CЭксперт С++
10749 / 6477 / 1601
Регистрация: 25.07.2009
Сообщений: 12,225
18.06.2014, 01:20 7
Цитата Сообщение от NOOBasi4 Посмотреть сообщение
что дальше с ней можно делать
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int func(int n) {
    int sqr(int a) { return a * a; }
    int cube(int a) { return a * a * a; }
    int f(int a, int (*fptr)(int)) { return fptr(a); }
    
    return f(n, ( n & 1 ) ? cube : sqr);
}
 
int main(void) {
    printf("%d %d\n", func(2), func(3));
    
    return 0;
}
забавно по-своему...
1
NOOBasi4
1 / 1 / 0
Регистрация: 05.05.2014
Сообщений: 38
18.06.2014, 02:35  [ТС] 8
Цитата Сообщение от easybudda Посмотреть сообщение
забавно по-своему...
Однако вы переиначели последовательность. Такой способ и мне ясен. Вопрос было о другом. Такое использование и мне ясно. Но оно только в GNU C... зачем тогда мне оно? Незачем, верно.
0
easybudda
Модератор
Эксперт JavaЭксперт CЭксперт С++
10749 / 6477 / 1601
Регистрация: 25.07.2009
Сообщений: 12,225
18.06.2014, 03:33 9
Цитата Сообщение от NOOBasi4 Посмотреть сообщение
Но оно только в GNU C... зачем тогда мне оно?
Ну за то у вас _tmain() есть...
1
NOOBasi4
1 / 1 / 0
Регистрация: 05.05.2014
Сообщений: 38
18.06.2014, 16:51  [ТС] 10
Цитата Сообщение от easybudda Посмотреть сообщение
Ну за то у вас _tmain() есть...
Звучит как претензия =)

Однако спасибо за такую инфу. Нашёл тему по такой штуке много нового прочёл = узнал и запомнил. А то пока где-то не мелькнёт... в книгах фиг напишут =(

З.Ы. я же жёсткий новичок в этой области знаний

Добавлено через 12 часов 55 минут
Походу книгу я читал первый раз крайне не внимательно... вчитавшись всё таки я увидел то, о чём спрашивал

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
 
#define SIZE 10
 
void bubble(int work[], const int size, int (*pFunction)(int a,int b));
int ascending (int a, int b);
int descending (int a, int b);
 
int main(void)
{   int sort, i, a[SIZE] = {2, 6, 4, 8, 10, 12, 89, 68, 45, 37};
    
    setlocale(LC_ALL,"");
    printf_s("%s", "Введите 1 для восходящей сортировки или\nвведите 2 для нисходящей сортировки: ");
    scanf_s("%d", &sort);
 
    puts("\nДанные исходного массива");
 
    for (i = 0; i < SIZE; i++)  printf_s("%5d", a[i]);
 
    if (sort == 1)
    {   bubble(a, SIZE, ascending);     puts("\n\nСортировка данных восходящим методом");
    } else 
    {   bubble(a, SIZE, descending);    puts("\n\nСортировка данных нисходящим методом");  }
 
    for (i = 0; i < SIZE; i++)  printf_s("%5d", a[i]);
 
    printf_s("%s","\n\n");
 
    swap(&a[3], &a[4]);
    printf_s("Поменяли 4 и 5 элементы: 4 = %d, 5 = %d\n\n", a[3], a[4]);
 
    system("pause");
    return 0;
}
 
void bubble(int work[], const int size, int (*pFunction)(int a, int b))
{   int pass, count;
 
    void swap(int *element1p, int *element2p);
 
    for (pass = 1; pass < size; pass++)
        for (count = 0; count < size - 1; count++)
            if ((*pFunction)(work[count], work[count + 1])) swap(&work[count], &work[count + 1]);
}
 
void swap(int *element1p, int *element2p)
{
    int hold;
 
    hold = *element1p;
    *element1p = *element2p;
    *element2p = hold;
}
 
int ascending(int a, int b)     { return b < a; }
 
int descending(int a, int b)    { return b > a; }
И теперь повторно вопрос...
В bubble() объявлен прототип swap()... ок... но для чего??? смысл такой темы??? реализация swap() всё равно глобально доступна... я понимаю если бы она юзалась бы только из bubble(), там есть куда такие приколы пристроит я думаю, если надо.
Или просто это так в MSVS 2012?
0
Хедин
74 / 69 / 55
Регистрация: 17.05.2014
Сообщений: 301
18.06.2014, 19:17 11
Лучший ответ Сообщение было отмечено NOOBasi4 как решение

Решение

NOOBasi4, для удобства кода, для создания каких то узконаправленных функций, которые в иных местах работать не будут. Смотрит программист, видит функцию внутри функции и понимает, что написана она конкретно для этой подпрограммы
1
NOOBasi4
1 / 1 / 0
Регистрация: 05.05.2014
Сообщений: 38
18.06.2014, 19:29  [ТС] 12
Цитата Сообщение от Хедин Посмотреть сообщение
Смотрит программист, видит функцию внутри функции и понимает, что написана она конкретно для этой подпрограммы

А вот это конкретный ответ =)
Вопросов больше не имею, по данной теме
0
castorsky
1975 / 1078 / 87
Регистрация: 29.11.2013
Сообщений: 3,354
18.06.2014, 20:26 13
Сам по себе гццшный екстенд неплох: ограничение области видимости читай секьюрность, решение конфликта имен. Декларация в теле функции -- не более чем явный намек читателю исходного кода программы, ибо единственное требование к декларации -- она должна быть раньше чем определение функции.
0
NOOBasi4
1 / 1 / 0
Регистрация: 05.05.2014
Сообщений: 38
03.07.2014, 16:08  [ТС] 14
Я тут нашёл для себя, мб кому тоже полезно будет, смысл прототипов. Для тех кто совмещает прототип с определением, код тоже покажу, это не грозит.

В MSVS 2012 этот код не корректен
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
 
//int bbb(float a, float b);без прототипа, компилятор не делает преобразования a, b
 
int main(void)
{
    int a = 111, b = 222;
    
    setlocale(LC_ALL," ");
    
    printf_s("%d\n", bbb(a,b));
 
    system("pause");
    return 0;
}
 
int bbb(float a, float b)
{
    return a + b;
}
Такого варианта это тема не касается - объединённое определение с прототипом ф-ии

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
 
int bbb(float a, float b) // прототип и определение совмещены воедино
{
    return a + b;
}
 
int main(void)
{
    int a = 111, b = 222;
 
    setlocale(LC_ALL," ");
 
    printf_s("%d\n", bbb(a,b));
 
    system("pause");
    return 0;
}
0
DrOffset
11867 / 6421 / 1545
Регистрация: 30.01.2014
Сообщений: 10,442
04.07.2014, 16:15 15
Цитата Сообщение от NOOBasi4 Посмотреть сообщение
Я тут нашёл для себя, мб кому тоже полезно будет, смысл прототипов.
Цитата Сообщение от NOOBasi4 Посмотреть сообщение
реализация swap() всё равно глобально доступна
Это только с точки зрения линкера она доступна. А с точки зрения компилятора - нет, чтобы произвести вызов, на уровне bubble должно быть видно прототип (или определение) swap. Например так.
C
1
2
3
4
5
6
7
8
9
void swap(int *element1p, int *element2p);
 
void bubble(int work[], const int size, int (*pFunction)(int a, int b))
{   int pass, count;
 
    for (pass = 1; pass < size; pass++)
        for (count = 0; count < size - 1; count++)
            if ((*pFunction)(work[count], work[count + 1])) swap(&work[count], &work[count + 1]);
}
Т.е. обязательно прототип или само определение должно быть доступно. Т.к. компилятор С - однопроходный (обычно), то существует зависимость от порядка объявления\определения и она есть в стандартах как С, так и С++.
0
04.07.2014, 16:15
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.07.2014, 16:15

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

определение функции в ЗАГОЛОВОЧНОМ файле. В основном предполагается переопределение ТЕЛА этой функции. Как это сделать, не правя хидер?
Сабж, а подробнее если в заголовочном файле hider.h описана функция, допустим так: void f ();...

Определение функции
Определите функцию ```shut_down```, которая на вход принимает некоторый аргумент. Так что, если на...

Определение функции
Здравствуйте. Никак не могу написать, как определяется функция, которая строит список (1 3 5 7 ......

Определение функции
Приветствую, уважаемые форумчане. Нужна ваша помощь в решении задачи. Нужно определить, какой...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.