In my program there is an input of elements of structural type and input of 2 numbers. After actually entering the menu at the top, I’m showing the status, whether the data is entered (YES, NO) checking if there is no NULL in the pointer (if there is no NULL, then the memory is allocated, and if the memory is allocated, then the data was recorded.) After writing the data, the status "NO" does not go to "YES", I can not understand what's the matter, maybe we have made some pointers ...

#include "stdafx.h" #include "stdio.h" #include "locale.h" #include "stdlib.h" //Глобально задаем структуру struct base { int first; int second; int third; } *list = NULL; //Функции //Проверка выделения памяти void CheckMem(void *list); //Ввод диапазона void Range(int *n, int *N); //Меню ввода данных через консоль void ConsoleRecord(struct base *list, int *len,int *n,int *N); //Запись элементов стр. типа через консоль void ConsoleScan(struct base *list, int *len); //Чистим мусор после ввода void CleanStdin(); int main(void) { setlocale(LC_ALL, ""); //Диапазон int *n; n = NULL; int *N; N = NULL; //Длина массива стр. элементов int *len; len = NULL; char number; printf("Добро пожаловать."); do { printf("Выберите необходимый пункт:\n"); printf("1) Запись данных с помощью консоли\n"); printf("2) Запись данных с помощью текстового файла\n"); printf("3) Выход\n"); number = getchar(); CleanStdin(); switch(number){ case '1': system("cls"); ConsoleRecord(list, len, n, N); break; case '2': system("cls"); printf("Еще не готово :(\n"); break; case '3': break; default: system("cls"); printf("Вы ничего не выбрали.\n"); break; } } while(number != '3'); //Освобождение памяти free(list); free(len); free(n); free(N); return 0; } void CheckMem(void *p) { if (p == NULL) printf("Память не выделена. Аварийное завершение программы.\n"), system("pause"), exit(1); } void Range(int *n, int *N) { if (n == NULL) { n = (int*)malloc(sizeof(int)), CheckMem(n); N = (int*)malloc(sizeof(int)), CheckMem(N); } printf("Введите диапазон ОТ:\n"); scanf_s("%d", n); CleanStdin(); printf("Введите диапазон ДО:\n"); scanf_s("%d", N); CleanStdin(); printf("Ваш диапазон: %d-%d\n", *n, *N); system("pause"); CleanStdin(); system("cls"); } void ConsoleRecord(struct base *list,int *len, int *n,int *N) { char number; printf("Вы выбрали запись данных с помощью консоли."); printf("\n------------------------------------------\n"); do { printf("Диапазон: "); if (n == NULL) { printf("НЕТ"); } else { printf("ДА"); } printf(". Элементы структурного типа: "); if (len == NULL) { printf("НЕТ"); } else { printf("ДА"); } printf(".\n------------------------------------------\n"); printf("Выберите необходимый пункт:\n"); printf("1) Ввести элементы структурного типа\n"); printf("2) Ввести диапазон\n"); printf("3) Обработка структуры\n"); printf("4) Выход в основное меню\n"); number = getchar(); CleanStdin(); switch (number) { case '1': system("cls"); ConsoleScan(list,len); break; case '2': system("cls"); Range(n,N); break; case '3': system("cls"); printf("Еще не готово.\n"); break; case '4': system("cls"); break; default: system("cls"); printf("Вы ничего не выбрали.\n"); break; } } while (number != '4'); } void CleanStdin() { int c; do { c = getchar(); } while (c != '\n' && c != EOF); } void ConsoleScan(struct base *list, int *len) { if (len == NULL) { len = (int*)malloc(sizeof(int)), CheckMem(len); } else { printf("Идет перезапись элементов массива структурного типа.\n"); free(list); return; } printf("Введите кол-во элементов структурного типа:\n"); scanf_s("%d", len); CleanStdin(); list = (struct base*)malloc((*len) * sizeof(struct base)), CheckMem(list); int i; for (i = 0; i < *len; i++) { printf("Введите поля %d-ого элемента массива структурного типа: ", i + 1); scanf_s("%d", &(list->first)); scanf_s("%d", &(list->second)); scanf_s("%d", &(list->third)); } CleanStdin(); system("pause"); system("cls"); } 

    1 answer 1

    Function parameters are their local variables. Functions deal with copies of the arguments passed to them.

    For example, if you have a program like this

     #include <stdio.h> #include <stdlib.h> void f( int *ptr ) { ptr = malloc( sizeof( int ) ); printf( "Inside f ptr = %p\n", ( void * )ptr ); } int main( void ) { int *p = NULL; printf( "Before f( p ) p = %p\n", ( void * )p ); f( p ); printf( "After f( p ) p = %p\n", ( void * )p ); return 0; } 

    then its console output will look like

     Before f( p ) p = (nil) Inside f ptr = 0x2ae3fe1af020 After f( p ) p = (nil) 

    That is, as can be seen from the output, the variable p declared in main did not change after the function f called, since the function dealt with a copy of the value of this variable. You can represent a function and its call as follows.

     int *p = NULL; f( p ); // ... void f( /* int *ptr */ ) { int *ptr = p; ptr = malloc( sizeof( int ) ); printf( "Inside f ptr = %p\n", ( void * )ptr ); } 

    The function has changed the value of its ptr parameter, which was initialized by the value of the argument p . The value of the argument p itself has not changed.

    Or an even simpler example. In the program below, no function is called, but, formally, a nested block of code can be viewed as the body of some supposed function. The declared variable y in the body of the code block can be considered as a parameter of the function. And the variable x declared before entering the code block can be considered as an argument of the function.

    In the code block, the variable y initialized with the value of the variable x , and then rewritten with the new value 25 . After exiting the code block, the variable Y ceases to exist. As for the variable x , its eigenvalue has not been changed.

     #include <stdio.h> int main( void ) { int x = 10; printf( "x = %d\n", x ); // Рассматривайте этот блок кода, как тело вызванной функции // имеющей параметр `y`, и которой передается аргумент `x` { int y = x; y = 25; printf( "y = %d\n", y ); } printf( "x = %d\n", x ); return 0; } 

    Output of the program to the console

     x = 10 y = 25 x = 10 

    If you want to change the value of the argument, then it must be passed by reference. For example,

     #include <stdio.h> #include <stdlib.h> void f( int **ptr ) { *ptr = malloc( sizeof( int ) ); printf( "Inside f ptr = %p\n", ( void * )*ptr ); } int main( void ) { int *p = NULL; printf( "Before f( p ) p = %p\n", ( void * )p ); f( &p ); printf( "After f( p ) p = %p\n", ( void * )p ); free( p ); return 0; } 

    Output of the program to the console

     Before f( p ) p = (nil) Inside f ptr = 0x2b3135483020 After f( p ) p = 0x2b3135483020 

    Since in the function the parameter is now declared as a pointer to a pointer, the value of the original pointer changes in the function.

    It is also better to use the scanf function instead of the getchar function in the following form:

     scanf( " %c", &number ); ^^^^ 

    Otherwise, the getchar function will also read space characters, which may not lead to the result you expect.

    • Yes thanks a lot. I apologize for not taking the answer for a long time as true, I forgot a bit about him. - ReCursia