Функция — это самостоятельная единица программы, которая спроектирована для реализации конкретной подзадачи.
Функция является подпрограммой, которая может содержаться в основной программе, а может быть создана отдельно (в библиотеке). Каждая функция выполняет в программе определенные действия.
Сигнатура функции определяет правила использования функции. Обычно сигнатура представляет собой описание функции, включающее имя функции, перечень формальных параметров с их типами и тип возвращаемого значения.
Семантика функции определяет способ реализации функции. Обычно представляет собой тело функции.
Определение функции
Каждая функция в языке Си должна быть определена, то есть должны быть указаны:
- тип возвращаемого значения;
- имя функции;
- информация о формальных аргументах;
- тело функции.
Определение функции имеет следующий синтаксис:
{
ТелоФункции;
…
return(ВозвращаемоеЗначение);
}
Пример: Функция сложения двух вещественных чисел
2
3
4
5
6
{
float y;
y=x+z;
return(y);
}
В указанном примере возвращаемое значение имеет тип float. В качестве возвращаемого значения в вызывающую функцию передается значение переменной y. Формальными аргументами являются значения переменных x и z.
Если функция не возвращает значения, то тип возвращаемого значения для нее указывается как void. При этом операция return может быть опущена. Такая функция называется процедурой.
Если функция не принимает аргументов, в круглых скобках также указывается void.
Различают системные (в составе систем программирования) и собственные функции.
Системные функции хранятся в стандартных библиотеках, и пользователю не нужно вдаваться в подробности их реализации. Достаточно знать лишь их сигнатуру. Примером системных функций, используемых ранее, являются функции printf() и scanf().
Собственные функции — это функции, написанные пользователем для решения конкретной подзадачи.
Разбиение программ на функции дает следующие преимущества:
- Функцию можно вызвать из различных мест программы, что позволяет избежать повторения программного кода.
- Одну и ту же функцию можно использовать в разных программах.
- Функции повышают уровень модульности программы и облегчают ее проектирование.
- Использование функций облегчает чтение и понимание программы и ускоряет поиск и исправление ошибок.
С точки зрения вызывающей программы функцию можно представить как некий «черный ящик», у которого есть несколько входов и один выход. С точки зрения вызывающей программы неважно, каким образом производится обработка информации внутри функции. Для корректного использования функции достаточно знать лишь ее сигнатуру.
Вызов функции
Общий вид вызова функции
Фактический аргумент — это величина, которая присваивается формальному аргументу при вызове функции. Таким образом, формальный аргумент — это переменная в вызываемой функции, а фактический аргумент — это конкретное значение, присвоенное этой переменной вызывающей функцией. Фактический аргумент может быть константой, переменной или выражением.
Если фактический аргумент представлен в виде выражения, то его значение сначала вычисляется, а затем передается в вызываемую функцию. Если в функцию требуется передать несколько значений, то они записываются через запятую. При этом формальные параметры заменяются значениями фактических параметров в порядке их следования в сигнатуре функции.
Возврат в вызывающую функцию
По окончании выполнения вызываемой функции осуществляется возврат значения в точку ее вызова. Это значение присваивается переменной, тип которой должен соответствовать типу возвращаемого значения функции.
Функция может передать в вызывающую программу только одно значение. Для передачи возвращаемого значения в вызывающую функцию используется оператор return в одной из форм:
Действие оператора следующее: значение выражения, заключенного в скобки, вычисляется и передается в вызывающую функцию. Возвращаемое значение может использоваться в вызывающей программе как часть некоторого выражения.
Оператор return также завершает выполнение функции и передает управление следующему оператору в вызывающей функции. Оператор return не обязательно должен находиться в конце тела функции.
Функции могут и не возвращать значения, а просто выполнять некоторые вычисления. В этом случае указывается пустой тип возвращаемого значения void, а оператор return может либо отсутствовать, либо не возвращать никакого значения:
Пример: Посчитать сумму двух чисел.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define _CRT_SECURE_NO_WARNINGS // для возможности использования scanf
#include <stdio.h>
// Функция вычисления суммы двух чисел
int sum(int x, int y) // в функцию передаются два целых числа
{
int k = x + y; // вычисляем сумму чисел и сохраняем в k
return k; // возвращаем значение k
}
int main()
{
int a, r; // описание двух целых переменных
printf("a= ");
scanf("%d", &a); // вводим a
r = sum(a, 5); // вызов функции: x=a, y=5
printf("%d + 5 = %d", a, r); // вывод: a + 5 = r
getchar(); getchar(); // мы использовали scanf(),
return 0; // поэтому getchar() вызываем дважды
}
Результат выполнения
В языке Си нельзя определять одну функцию внутри другой.
В языке Си нет требования, чтобы семантика функции обязательно предшествовало её вызову. Функции могут определяться как до вызывающей функции, так и после нее. Однако если семантика вызываемой функции описывается ниже ее вызова, необходимо до вызова функции определить прототип этой функции, содержащий:
- тип возвращаемого значения;
- имя функции;
- типы формальных аргументов в порядке их следования.
Прототип необходим для того, чтобы компилятор мог осуществить проверку соответствия типов передаваемых фактических аргументов типам формальных аргументов. Имена формальных аргументов в прототипе функции могут отсутствовать.
Если в примере выше тело функции сложения чисел разместить после тела функции main, то код будет выглядеть следующим образом:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define _CRT_SECURE_NO_WARNINGS // для возможности использования scanf
#include <stdio.h>
int sum(int, int); // сигнатура
int main()
{
int a, r;
printf("a= ");
scanf("%d", &a);
r = sum(a, 5); // вызов функции: x=a, y=5
printf("%d + 5 = %d", a, r);
getchar(); getchar();
return 0;
}
int sum(int x, int y) // семантика
{
int k;
k = x + y;
return(k);
}
Функция может вернуть только одно значение. В случае если требуется вернуть более одного значения, остальные переменные, значения которых должны быть возвращены, передаются как местодержатели — указатели или ссылки.
Пример: поменять местами два числа.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
void swap(int* a, int* b) // аргументы передаются через указатели
{
int temp = *a;
*a = *b;
*b = temp;
return;
}
int main()
{
int a = 3, b = 5;
printf("a=%d b=%d\n", a, b);
swap(&a, &b); // передаем в функцию адреса переменных a и b
printf("a=%d b=%d\n", a, b);
getchar(); getchar();
return 0;
}
Результат выполнения
Рекурсивные функции
Функция, которая вызывает сама себя, называется рекурсивной функцией.
Рекурсия — вызов функции из самой функции.
Пример рекурсивной функции — функция вычисления факториала.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define _CRT_SECURE_NO_WARNINGS // для возможности использования scanf
#include <stdio.h>
int fact(int num) // вычисление факториала числа num
{
if (num <= 1) return 1; // если число не больше 1, возвращаем 1
else return num*fact(num - 1); // рекурсивный вызов для числа на 1 меньше
}
// Главная функция
int main()
{
int a, r;
printf("a= ");
scanf("%d", &a);
r = fact(a); // вызов функции: num=a
printf("%d! = %d", a, r);
getchar(); getchar();
return 0;
}
Результат выполнения
Более подробно рекурсивные функции рассмотрены в этой статье.
Математические функции
Математические функции хранятся в стандартной библиотеке math.h. Аргументы большинства математических функций имеют тип double. Возвращаемое значение также имеет тип double. Углы в тригонометрических функциях задаются в радианах.
Основные математические функции стандартной библиотеки.
Функция | Описание |
int abs(int x) | Модуль целого числа x |
double acos(double x) | Арккосинус x |
double asin(double x) | Арксинус x |
double atan(double x) | Арктангенс x |
double cos(double x) | Косинус x |
double cosh(double x) | Косинус гиперболический x |
double exp(double x) | Экспонента x |
double fabs(double x) | Модуль вещественного числа |
double fmod(double x, double y) | Остаток от деления x/y |
double log(double x) | Натуральный логарифм x |
double log10(double x) | Десятичный логарифм x |
double pow(double x, double y) | x в степени y |
double sin(double x) | Синус x |
double sinh(double x) | Синус гиперболический x |
double sqrt(double x) | Квадратный корень x |
double tan(double x) | Тангенс x |
double tanh(double x) | Тангенс гиперболический x |
Особенности использования функций в языке C++ рассмотрены в этой статье.
Здравствуйте нужно этот код поместить в функцию помоги пожалуйста
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int tmpBirthDay;
int tmpBirthMonth;
int tmpBirthyear;
scanf("%d", &tmpBirthDay);
scanf("%d", &tmpBirthMonth);
scanf("%d", &tmpBirthyear);
if(tmpBirthDay > 0)
{
pStudent->birthDay.day = tmpBirthDay;
}
if(tmpBirthDay > 0)
{
pStudent->birthDay.month = tmpBirthMonth;
}
if(tmpBirthDay > 0)
{
pStudent->birthDay.year = tmpBirthyear;
}
printf("\n");
Здраствуйте, помогите, пожалуйста, найти недочёт в программе. Нужно осуществлять ввод переменных, дейсвия над ними и их вывод в разных функциях. С передачей данных через return между вводом(фун-я Input) и действиями(фун-я Actions) нет, но передача между действиями и выводом хромает, не могу понять в чём проблема. Вроде возвращаю значения max, min и вызываю их в функции вывода, но не выходит. Ругается на строку вызова функции Output_MaxMin в функции main, что тут использована неинициализированная локальная меременная max и min, хотя выше их инициализирую. Заранее спасибо за помощь!
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main()
{
srand(time(NULL));
int z[6][5];
int s;
int i, j;
int max, min;
input(z);
output(z);
actions(z);
Output_MaxMin(max, min);
getchar();
return 0;
}
int input(int z[6][5]) {
int* a = z;
int i, j;
for (i = 0; i < 6; i++) {
for (j = 0; j < 5; j++) {
*((a + i) + j) = rand() % (100 — 1 + 1) + 1;
}
}
return *a;
}
int output(int* a) {
int i, j;
printf("\n");
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 5; j++) {
printf("%4d", *((a + i) + j));
}
printf("\n");
}
}
int actions(int z) {
int summa[6];
int* a = z;
int* p = summa;
int max, min;
int i, j;
int s;
printf("Amount: \n");
for (int i = 0; i < 6; ++i) {
s = 0;
for (int j = 0; j < 5; ++j)
s += *((a + i) + j);
*(p + i) = s;
printf("%5d\n", *(p + i));
}
max = 0;
min = 10000;
for (int i = 0; i < 6; ++i)
{
if (*(p + i) > max)
{
max = *(p + i);
}
}
for (int i = 0; i < 6; ++i)
{
if (*(p + i) < min)
{
min = *(p + i);
}
}
printf("Maximum: %d\n", max);
printf("Minimum: %d\n", min);
return max, min;
}
int Output_MaxMin(int max, int min) {
printf("Maximum: %d\n", max);
printf("Minimum: %d\n", min);
}
Проблема с областями видимости переменных max, min. Те переменные, которые описаны в main, не видны в Actions. Чтобы это исправить, нужно описать переменные глобально, до всех функций. Тогда они станут видны во всем файле.
Добрый день.
А не подскажете как в рекурсивной функции вычисления чисел Фибоначчи, с указанием количества шагов, организовать вывод значений на экран в самой функции? Вроде должно быть простое решение, но уже всю голову сломал.
2
3
4
if (x<3) return 1;
return Phib(x-1)+Phib(x-2);
}
Поделитесь решением, когда найдете 🙂
Пока мне видится вывод только из внешней функции.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using namespace std;
int Phib(int x) {
if (x < 3)
{
return 1;
}
return Phib(x — 1) + Phib(x — 2);
}
int main()
{
for(int i=1; i<=5; i++)
cout << Phib(i) << " ";
cin.get();
return 0;
}
Ну вот как вариант нашел:
2
3
4
5
6
7
8
9
10
11
if (n > 0) {
// выводим числа Фибоначчи от 1 до n-1
fib(n — 1);
// выводим n-ое число Фибоначчи
cout << (n <= 2 ? 1 : fib(-(n — 1)) + fib(-(n — 2))) << endl;
} else {
n *= -1;
}
return n <= 2 ? 1 : fib(-(n — 1)) + fib(-(n — 2));
}
Но это на c++ и через потоки. Мне нужно на си и без них )
Здравствуйте, Елена. У меня возникла проблема в том, что заданная функция, не хочет работать и выдает ошибку, можете подсказать)) Вот условие:Дана строка. Найти в строке индексы первого и последнего символов, таких, что слева и справа от них стоят цифры.
Все строки (и только строки) должны быть размещены динамически с помощью оператора new.
Разделителем слов в предложении считать только пробел. Все остальные символы считать частью слов предложения.
Можно использовать функции для работы со строками.
Дано предложение. Сформировать массив слов из таких слов предложения,
которые имеют в своем составе латинскую букву 'a', обрамленную цифрами. */
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
#include <conio.h>
#include <windows.h>
#include <string.h>
int main ()
{
char *s=new char[100];
int p;
printf("Vvedite predlozhenie\n");
gets (s);
printf("\nVvedennoe predlozhenie\n");
puts (s);
printf("\n");
pos(s,p);
delete []s;
}
void pos(char *s, int p)
{
int i=0,k;
k= strlen(s);
if (k>=3)
{
while(i+2<k)
{
if((s[i]>='0' && s[i]<='9') && (s[i+2]>='0' && s[i+2]<='9'))
{
p=i+2;
printf("1:%d",p);
printf("\n");
break;
}
p=0;
i++;
}
i=k;
while(i+2>0)
{
if((s[i]>='0' && s[i]<='9') && (s[i-2]>='0' && s[i-2]<='9'))
{
p=i;
printf("2:%d",p);
printf("\n");
break;
}
i—;
}
if(p==0)
printf("Net takix simvolov\n");
}
}
1.В вызове pos(s,p) чему равно p? Такое впечатление, что хотели вернуть значение из функции. Лучше это сделать через return. Если возвращать через аргумент, то по крайней мере его нужно описать указателем или ссылкой.
2. Почему поиск ведется не от начала строки а от 2 символа?
3. Зачем условие (s>='0' && s<='9')?
Здравствуйте, Елена! Спасибо за статью. У меня простой вопрос. Если тип формального параметра указан в прототипе, то возможно при определении функции в качестве формального параметра указывать только имя переменной без его типа?
Нет
Здравствуйте, помогите пожалуйста. Я написала код (находит слово в тексте и выводит его кол-во). Код работает, но нужно через функцию.
Я не понимаю как его в функцию переделать.
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
#include <string.h>
int main(){
char poisk[65];
int kol = 0;
FILE *text;
if ((text = fopen("text.txt", "r")) == NULL){
printf("Текст не найден");
getchar();
return 0;
}
printf("Введите слово: ");
scanf("%s", poisk);
int ch;
int i = 0;
int len = strlen(poisk);
while((ch = fgetc(text)) != EOF){
if (poisk[i] == ch) {
++i;
} else {
i = 0;
}
if (i == len) {
++kol;
i = 0;
}
}
printf("Количество данного слова в тексте: %d", kol);
fclose(text);
getchar();
return 0;
}
2
3
4
5
6
{int kol=0;
printf("Введите слово");
…
return kol;
}
А в основной функции — вызов
И вывести kol
Здравствуйте, не могу найти ошибку, всегда выводит 0.
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
#include <string.h>
int func(FILE *text, char *poisk){
int kol = 0, i = 0, ch, len = strlen(poisk);
while((ch = fgetc(text)) != EOF){
if (poisk[i] == ch) {
++i;
} else {
i = 0;
}
if (i == len) {
++kol;
i = 0;
}
return kol;
}
}
int main(){
char poisk[65];
int kol = 0;
FILE *text;
if ((text = fopen("text.txt", "r")) == NULL){
printf("Текст не найден");
getchar();
return 0;
}
{
kol=func(text, poisk);
}
printf("Введите слово: ");
scanf("%s", poisk);
printf("Количество данного слова в тексте: %d", kol);
fclose(text);
getchar();
return 0;
}
Заранее спасибо.
Сначала нужно ввести искомое слово, а затем вызывать функцию поиска
Здравствуйте Елена. Пытаюсь разобрать функции с переменным количеством параметров. Помогите найти где лежат параметры вызова.()
long summa(int k, …)
{
int *pick = &k;
long total = 0;
for ( ; k; k—)
{
total += *(++pick);
}
return total;
}
void main()
{
printf("\n summa(2, 6, 4) = %d",summa(2,4,6));
printf("\n summa(6, 1, 2, 3, 4, 5, 6) = %d",summa(6,1,2,3,4,5,6));
}
на выходе получаю :
summa(2, 6, 4) = 0
summa(6, 1, 2, 3, 4, 5, 6) = -116778876
Пробовал добавить printf(" %p — %ld ", pick, *pick) и printf(" %p — %ld ", pick, *(pick+1)) в тело цикла.
0x7ffded1bcb9c — 2
0x7ffded1bcba0 — 0
0x7ffded1bcba4 — 0
summa(2, 6, 4) = 0
Как видите, сдвиг есть, но там пусто или какой-то мусор.
long summa(int n, int k, …) // первый параметр указывает количество параметров далее
{
int* pick = &k;
long total = 0;
for (; n; n—)
{
total += *(pick++);
}
return total;
}
void main()
{
printf("\n summa(2, 6, 4) = %d", summa(3, 2, 4, 6));
printf("\n summa(6, 1, 2, 3, 4, 5, 6) = %d", summa(6, 1, 2, 3, 4, 5, 6));
}
Спасибо что так быстро ответили!!
И извините за спам. Вобщем в результате продолжительного гугления удалось решить проблему, как оказалось это особенности компилятора. Кстати, в книге после еще нескольких примеров тоже всплыло что разные компиляторы по своему адресуют параметры функций и тут в дело вступают макрокоманды: va_start va_arg va_end. Сайт у вас замечательный, и никого не слушайте они просто завидуют.
PS. На правах автора выше размещенного кода, прошу убрать нумерацию строк =З
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <math.h>
double func1 (double x_min,double x_max,double dx,double a,double f , double c ,double b);
double fanc2 (double a ,double b , double c , int q);
int main()
{
int a;
printf("выберети функцию 1 или 2 ");
scanf("%d",&a);
switch (a) {
case 1:
{
double x_min, x_max, dx, a, f , c , b ;
do {
printf("\n Укажите интервал:\t");
scanf("%lf%lf", &x_min, &x_max);
}while(x_min>x_max);
printf("Введите значенaе a");
scanf("%lf" , &a );
printf("Введите значение b");
scanf("%lf" , &b );
printf("Введите значение c");
scanf("%lf" , &c );
do {
printf("\n Укажите шаг:\t");
scanf("%lf",&dx);
}
while (dx<0);
for (x_min; x_min<=x_max; x_min+=dx)
if (x_min<0 && b!=0)
{
f=-a*x_min*x_min*x_min-b;
printf ("—————————————-\n");
printf ("|x=%lf:|\tФункция равна: %f|\n", x_min , f);
printf ("—————————————-\n");
}
else{
if (x_min>0 && b==0)
{
f=(x_min-a)/(x_min-c);
printf ("—————————————-\n");
printf ("|x=%lf:|\tФункция равна: %f|\n", x_min , f);
printf ("—————————————-\n");
}
else
{
f=(x_min/c)+(c/x_min) ;
printf ("—————————————-\n");
printf ("|x=%lf:|\tФункция равна: %f|\n", x_min , f);
printf ("—————————————-\n");
}
}
return 0;
}
break;
case 2:
{
double a,b,c ;
printf ("введите а");
scanf ("%lf",&a);
printf ("введите b");
scanf ("%lf",&b);
c=a*a+b*b;
printf ("%lf" , c );
return 0;
}
break;
default:
printf( "Неизвестное значение" );
}
}
я не понимаю что надо сделать чтобы програма стала функциями
Насколько я понимаю, то, что сейчас записано в case 1 и case 2, нужно оформить в виде функций, чтоб там только вызов остался. Прототипы функций указаны сверху (до main). Осталось только тело функций туда перетащить и вызов добавить в case-ax.
Помогите найти ошибку
2
3
4
5
6
7
{
if (x>y
return x
else
return y
}
2
3
4
5
6
7
{
if (x>y)
return x;
else
return y;
}
Здравствуйте! Написала функции ввода и вывода массива, но не знаю, как к ним обратиться в теле программы. Подскажите, пожалуйста, как это сделать.
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
#include <stdio.h>
#include <locale.h>
#include <math.h>
#define k 8
int readM(double a[])
{
int i, n;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Введите а[%d]=", i);
scanf("%lf", &a[i]);
}
return n;
}
void displayM(double a[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%lf\t", a[i]);
printf("\n");
}
int main()
{
?
return 0;
}
2
3
4
5
6
7
8
{
double a[100];
int n;
n = readM(a);
displayM(a, n);
return 0;
}
Здравствуйте, мой преподаватель просит меня изменить программу вот так:
Нужно перенести логику определения в отдельную функцию, которая возвращает true или false.
2
3
4
5
6
7
8
9
10
11
12
{
cout << "true" << endl;
}
if ((x11 >= x21 && y11 <= y21) || (x12 <= x22 && y12 >= y22))
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
И я не понимаю, что именно мне нужно сделать.
Вот сама программа:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using namespace std;
int main()
{
double x11, y11, x12, y12, x21, y21, x22, y22;
cin >> x11 >> y11;
cin >> x12 >> y12;
cin >> x21 >> y21;
cin >> x22 >> y22;
if ((x11 <= x21 && y11 >= y21) || (x12 >= x22 && y12 <= y22))
{
cout << "true" << endl;
}
if ((x11 >= x21 && y11 <= y21) || (x12 <= x22 && y12 >= y22))
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
return 0;
}
Прошу, помогите!
В простейшем случае — что-то типа
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
using namespace std;
void func(double x11, double y11, double x12, double y12, double x21, double y21, double x22, double y22)
{
if ((x11 <= x21 && y11 >= y21) || (x12 >= x22 && y12 <= y22))
{
cout << "true" << endl;
}
if ((x11 >= x21 && y11 <= y21) || (x12 <= x22 && y12 >= y22))
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
}
int main()
{
double x11, y11, x12, y12, x21, y21, x22, y22;
cin >> x11 >> y11;
cin >> x12 >> y12;
cin >> x21 >> y21;
cin >> x22 >> y22;
func(x11, y11, x12, y12, x21, y21, x22, y22);
return 0;
}
Здравствуйте не понимаю почему все числа складываются которые кратны 4Найти и вывести сумму целых положительных чисел из интервала от a до b, кратных 4.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <cstdio>
using namespace std;
int main()
{
int sum, A, B, ch;
sum = 0;
cout << "Введите начало отрезка: ";
cin >> A;
cout << "Введите конец отрезка: ";
cin >> B;
for (ch = A; ch <= B; ch++)
{
if (ch%4) continue;
sum = sum + ch;
}
cout << sum;
return 0;
}
Поставьте проверку перед циклом:
Очень начинающий — это про меня. Решил попробовать из библиотеки на LCD "выкусить" часть в отдельный модуль для использования с другими подобными библиотеками.
Получилось это:
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
//Таблица перекодировки в русские символы.
static const unsigned char PROGMEM convert_HD44780[64] =
{
0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4,
0xA5,0xA6,0x4B,0xA7,0x4D,0x48,0x4F,0xA8,
0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB,
0xAC,0xE2,0xAD,0xAE,0xAD,0xAF,0xB0,0xB1,
0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7,
0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE,
0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0,
0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7
};
static uint8_t lcd_rus(uint8_t c)
{
if (c > 191)
{
c -=192;
c= pgm_read_byte(&convert_HD44780[c]);
}
return c;
}
При компиляции предупреждение типа "объявлено, но не используется" Соответственно не работает.
Строка static uint8_t lcd_rus(uint8_t); является вызовом функции?
Нет, это описание функции, а не вызов
Спасибо! По-моему нашел.
2
3
4
5
6
7
{
Busy_flag(); //Проверим сперва флаг занятости, а свободен ли дисплей?
CPORT|=(1<<RS); //RS=1 посылаем данные в LCD
Send_byte(lcd_rus(i));
CPORT&=~(1<<RS);//RS=0
}
Здравствуйте Елена! У меня вопрос, помогите найти ошибку!
Не получается сложить элементы массива в функции. Надо чтобы возвращалась сумма!
//Напишите функцию, которая принимает одномерный массив целых чисел и возвращает сумму всех чисел.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int sum = 0;
for (int i = 0; i < size; i++) {
cout << (sum + mas[i]) << " ";
}
}
int main() {
setlocale(LC_ALL, "rus");
const int size = 10;
int mas[size]{ 5,5,8,9,11,6,10,7,14,17 };
mnozhitel(mas, size);
cin.get(); cin.get();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int sum = 0;
for (int i = 0; i < size; i++) {
sum += mas[i];
}
return sum;
}
int main() {
setlocale(LC_ALL, "rus");
const int size = 10;
int mas[size]{ 5,5,8,9,11,6,10,7,14,17 };
int s = summa(mas, size);
cout << s;
cin.get(); cin.get();
}
Здравствуйте. Спасибо за Ваш труд. Хотелось бы узнать причину, если можно, ошибки программы, в которой при передаче указателя на динамический двумерный массив в функцию(для расширения массива на одну строку, например) при попытке обращения к любому элементу массива происходит крушения программы:
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
mass = (int**)malloc(kolvert * sizeof(int*));
for (int i = 0; i < kolvert; i++)
{
mass[i] = (int*)malloc(koledge * sizeof(int));
}
add(&kolvert,koledge,&mass);
return 0;
}
void add(int *kolvert, int koledge, int ***mass)
{
int now = *kolvert;
*kolvert = *kolvert + 1;
*mass = (int**)realloc(*mass, *kolvert * sizeof(int*));
*mass[now] =(int*)malloc(koledge * sizeof(int));
for (int i = now; i < *kolvert; i++)
for(int j = 0; j < koledge; j++)
*mass[i][j] = 0;
for (int i = 0; i < *kolvert; i++)
{
for(int j = 0; j < koledge; j++)
{
printf("%3i",*mass[i][j]);
if(j == koledge-1)
{
printf("\n");
}
}
}
}
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
using namespace std;
void add(int* kolvert, int koledge, int** mass)
{
int now = *kolvert;
*kolvert = *kolvert + 1;
mass = (int**)realloc(mass, *kolvert * sizeof(int*));
mass[now] = (int*)malloc(koledge * sizeof(int));
for (int i = now; i < *kolvert; i++)
for (int j = 0; j < koledge; j++)
mass[i][j] = 0;
for (int i = 0; i < *kolvert; i++)
{
for (int j = 0; j < koledge; j++)
{
printf("%3d", mass[i][j]);
if (j == koledge — 1)
{
printf("\n");
}
}
}
}
int main()
{
int** mass;
int kolvert = 1;
int koledge = 1;
mass = (int**)malloc(kolvert * sizeof(int*));
for (int i = 0; i < kolvert; i++)
{
mass[i] = (int*)malloc(koledge * sizeof(int));
for (int j = 0; j < koledge; j++)
mass[i][j] = 0;
}
add(&kolvert, koledge, mass);
getchar();
return 0;
}
По прежнему в функции main невозможно обратиться ни к какому элементу массива, программа рушится.
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
using namespace std;
int** add(int* kolvert, int koledge, int** mass)
{
int now = *kolvert;
*kolvert = *kolvert + 1;
mass = (int**)realloc(mass, *kolvert * sizeof(int*));
mass[now] = (int*)malloc(koledge * sizeof(int));
for (int i = now; i < *kolvert; i++)
for (int j = 0; j < koledge; j++)
mass[i][j] = 0;
for (int i = 0; i < *kolvert; i++)
{
for (int j = 0; j < koledge; j++)
{
printf("%3d", mass[i][j]);
if (j == koledge — 1)
{
printf("\n");
}
}
}
return mass;
}
int main()
{
int** mass;
int kolvert = 1;
int koledge = 1;
mass = (int**)malloc(kolvert * sizeof(int*));
for (int i = 0; i < kolvert; i++)
{
mass[i] = (int*)malloc(koledge * sizeof(int));
for (int j = 0; j < koledge; j++)
mass[i][j] = 0;
}
mass = add(&kolvert, koledge, mass);
for (int i = 0; i < kolvert; i++)
{
for (int j = 0; j < koledge; j++)
cout << mass[i][j] << " ";
}
getchar();
return 0;
}
Да, получается что через return функции все работает. Спасибо большое!
double x = 3.5, a = 1.8, b = 3.7;
double y, z;
y = sqrt(((x * 2) + 16) / (x + 2));
printf("|y = %8.4lf| \n", y);
z = y + sqrt(sin(a + 3 + b)) / (y * 2) + sqrt(sin(a + 3));
printf("| z = %8.4lf| \n", z);
мне z выводит — nan (ind) когда компилирую а Y нормально
Очень похоже, что синус отрицательный под корнем получился.
Здравствуйте, Елена!
При определении функции тип возвращаемого значения и тип формальных аргументов в функции обязательно должны быть одинаковыми?
Спасибо
Нет
Спасибо.
Здравствуйте, а подскажите пожалуйста как можно поменять два значения в функции и вернуть их обратно?
Нужно передать в функцию не сами значения, а ссылки на них.
Здраствуйте, у меня есть функция которая принимает два значения, могу ли я передать ей одно значение?
Зависит от конкретной реализации. Например, если второй аргумент задан по умолчанию, то можете.
Как написать функцию bool Even(int K) логического типа, возвращающую True, если целый параметр K является четным, и False в противном случае.
2
3
4
5
{
if (k % 2 == 0) return true;
return false;
}
2
3
4
{
return k&1;
}
Елена, а может ли функция вернуть два значения? Причем разного типа… допустим Int и Char… К примеру:
2
3
return(25, "Saratov");
}
Понятно что такая семантика не будет работать, но как сделать, что то похожее? если это возможно…
Функция, к сожалению, может возвращать только одно значение.
Но действительно, возникают ситуации, когда требуется передать несколько значений.
В этом случае значения (кроме одного), которые должны быть вычислены функцией, передаются в общем списке аргументов как местодержатели. Причем передача таких аргументов производится по ссылке: prog-cpp.ru/cpp-amp/.
Например, функция должна посчитать минимум и максимум:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using namespace std;
void minimax(int a, int b, int c, int &min, int &max)
{
min = a;
max = a;
if (b < min) min = b;
else max = b;
if (c < min) min = c;
if(c > max) max = c;
return;
}
int main()
{
int min, max;
minimax(3, 8, 4, min, max);
cout << "min = " << min << endl;
cout << "max = " << max << endl;
cin.get();
return 0;
}
Елена,у меня возник вопрос ,есть ли ограничение на количество формальных/фактических параметров функции? Просто написал программу , вычисляющую интеграл методом Симпсона , где содержится 3 функции(функция ввода данных,функция реализующая заданный алгоритм и функция вывода данных), отмечу , что в функции алгоритма использовал указатель на функцию , мол, препод отдельно требовал вычислить значения y ,чтобы функция вызывалась для этого отдельно. Это всё я то сделал , но вскоре захотелось чуть намудрить и сделать ,чтобы в функции вывода было не только значение интеграла , но и выводилась таблица , содержащая расчёты x,y, проблема в том , что добавляю дополнительный формальный параметр и все катится к чертям
Я не знаю ограничения на количество передаваемых аргументов. Скорее всего, это будет определяться свободной областью памяти в стеке.
Единственное ограничение — если Вы используете аргументы со значениями по умолчанию, то они обязательно должны находиться в конце в списке аргументов.
А так — зависит от кода.
Елена, добрый день.
Мне попался примерно такой программный текст на Си:
Основная программа:
2
…
Функция:
2
3
…
}
При этом программа работает.
Пожалуйста, поясните, в каких случаях формальным параметрам задают значения и что это значит. Большое спасибо.
Здравствуйте, Валерий!
Действительно, формальным аргументам функции могут быть присвоены значения по умолчанию. Эти значения будут использоваться в том случае если они не переданы в функцию при вызове.
Например, в Вашем случае можно вызвать функцию
func(0); // равносильно вызову func(0,1);
или
func(); // равносильно вызову func(1,1);
То есть если в функции есть значения по умолчанию, то значения фактических параметров для них могут не передаваться.
Но значения по умолчанию могут иметь только формальные параметры, находящиеся справа в перечне параметров. Иными словами, если для аргумента задано значение по умолчанию, то правее его аргумент без заданного значения по умолчанию стоять не может.
Также некорректным будет вызов функции
func(,0); // компилироваться не будет
Это свойство стало доступно в языке C++, но не было доступно в Си.
Подробнее смотрите здесь.
void main() и int main(void) дадут одинаковый результат? В обоих случаях не будет возвращаться результат?
То, что написано слева от имени функции — это тип возвращаемого значения. В первом случае функция не возвращает значения — void, во втором случае возвращает целочисленное значение — int.
То, что записано внутри круглых скобок — это перечень аргументов. В приведенном Вами примере оба случая — пустые круглые скобки или (void) не содержат аргументов.
Понял, Спасибо!
Добрый день!
Елена, подскажите плз, возможен ли вариант double main(), float main(), char main(), string main() и т.д.?
И в чём будет практическое отличие, например, int main() и int main(void)? Как это отобразиться на финальном результате программы?
Тип возвращаемого значения функции main() — это значение, возвращаемое ей операционной системе. Операционная система анализирует целочисленное значение, поэтому используется
int main() {…}
Возможен также вариант функции main() не возвращающей значение. При этом ее можно записать как
void main() {…}
В этом случае последняя команда return 0; в функции main() отсутствует.
Насчет аргументов, которые могут передаваться в функцию main() можно посмотреть здесь.
В языке СИ нет требования, чтобы определение функции обязательно предшествовало ее вызову. Определения используемых функций могут следовать за определением функции main, перед ним, или находится в другом файле.
Согласна отчасти. В языке Си нет требования, чтобы определение функции было до вызова. Но это требование среды разработки Visual Studio. Для того, чтобы в Visual Studio программа корректно откомпилировалась, до вызова функции должна быть описана хотя бы сигнатура функции. В противном случае при компиляции возникнет ошибка.
Если функция находится в другом файле, и этот файл добавляется в проект, то до вызова функции также должна быть описана сигнатура функции.
Способом не включать сигнатуру функции в файл является подключение заголовочного файла, внутри которого содержится описание функции, с помощью директивы #include. В этом случае всё содержимое заголовочного файла вставляется в начало файла кода на этапе компиляции.