Главная страница
Навигация по странице:

  • 1.9 Указатели и функции

  • День до сдачи работы мы справимся, и ты получишь Отлично по своему предмету! Только представь ты занимаешься своим любимым делом, пока твои лохиодногруппники теряют свои нервные клетки Проникнись Это бесценное ощущение Курсовая,


    Скачать 389.95 Kb.
    НазваниеДень до сдачи работы мы справимся, и ты получишь Отлично по своему предмету! Только представь ты занимаешься своим любимым делом, пока твои лохиодногруппники теряют свои нервные клетки Проникнись Это бесценное ощущение Курсовая,
    Дата04.07.2021
    Размер389.95 Kb.
    Формат файлаdocx
    Имя файлаUchebnoe_posobie_Osnovy_C.docx
    ТипРешение
    #223314
    страница4 из 9
    1   2   3   4   5   6   7   8   9
    1.8. Указатели


    Указатель - это переменная, содержащая адрес данных, а не их значение. Указатель используется:

    1.Для связи независимых структур друг с другом.

    2.Для динамического распределения памяти.

    3.Для доступа к различным элементам структуры.

    Рассмотрим следующую программу:

    #include

    main()

    {

    int Z,*Y;

    Y =&Z;

    Z = 100;

    printf("Прямое значение Z: %d\n", Z);

    printf("Значение Z, полученное через указатель: %d\n",*Y);

    printf(" Адрес Z через получение адреса: %p\n",&Z);

    printf("Адрес Z через указатель: %p\n", Y);

    }

    В данном примере Y указатель на целую переменную и содержит ее адрес. В свою очередь & позволяет получить адрес по которому размещено значение переменной Z. В этой программе:

    - адрес переменной Z присваивается Y;

    - целое значение 100 присваивается Z;

    - оператор &, позволяет получить адрес,

    по которому размещено значение Z.

    Результат работы программы:

    Прямое значение Z: 100

    Значение Z, полученное через указатель: 100

    Адрес Z через получение адреса: 85B3:0FDC

    Адрес Z через указатель: 85B3:0FDC

    Указатели также используются для оптимального распределения памяти.

    Рассмотрим пример указателя на число типа char.

    #include

    #include

    #include

    #include

    #include


    int main(void)

    {

    char *str; /* указатель на символьную переменную */

    str = (char *)malloc(10);

    strcpy(str, "Hello");

    printf("String is %s\n", str);

    free(str);

    return(0);

    }

    Вначале по команде char *str; создан тип str, который является указателем на переменную типа char(* обозначает "указатель"). По команде str = (char *)malloc(10); выделяем 10 байт памяти под переменную str(типа строка). По команде strcpy(str, "Hello"); осуществляется - "записать в область памяти, на которую указывает str, строку символов "Hello". По команде printf("String is %s\n", str); осуществляется "напечатать на экране то, на что указывает str. Команда free(str); освобождает память, на которую указывает str.

    Рассмотрим более сложный пример получения доступа к записи, используя указатель.

    #include

    #include

    #include

    #include


    struct Student { /* запись Student */

    char Fio[30]; /* поле записи Fio */

    int Gruppa; /* поле записи Gruppa */

    }; /* конец записи */

    struct Student *A;

    main()

    {

    if ((A =(Student *) malloc(sizeof(Student))) == NULL)

    {

    printf("Нет памяти\n");

    exit(1);

    }

    strcpy(A[1].Fio, "Ivanov");

    A[1].Gruppa=385;

    printf("Fio1 %s\n Gruppa %d\n", A[1].Fio, A[1].Gruppa);

    strcpy(A[2].Fio, "Petrow");

    A[2].Gruppa=386;

    printf("Fio2 %s\n Gruppa %d\n", A[2].Fio, A[2].Gruppa);

    free(A);

    }

    Указатель также может использоваться для получения косвенного указателя на структуру.

    Пусть poit является указателем на структуру и что elem элемент, определенный структурным шаблоном. Тогда point->elem определяет элемент, на который выполняется ссылка. Рассмотрим предыдущий пример.

    struct Student { /* запись Student */

    char Fio[30]; /* поле записи Fio */

    int Gruppa; /* поле записи Gruppa */

    }; /* конец записи */

    Student *poin;

    Сейчас к полям структуры мы можем обращаться несколькими способами. Эквивалентные обращения:

    Student.Gruppa=236;

    poin->Gruppa=236;

    Отметим одну важную особенность указателей в Си. Транслятор автоматически учитывает тип указателя в арифметических действиях над ним. Например если i есть указатель на целую (т.е. двухбайтную) переменную, то действие типа i++ означает, что указатель получает приращение не один, а два байта, т.е. будет указывать на следующую переменную или элемент массива. По этой причине указатель можно использовать вместо индексов массива. Например если A - указатель на массив целого типа, то вместо A[i] можно писать *(A+i). Более того, использование указателей вместо индексов позволяет компилятору создавать более компактный и быстрый код.
    1.9 Указатели и функции
    Указатели также можно использовать в качестве формальных параметров функции. Рассмотрим пример.

    Функция swap (обмен) объявляет два формальных параметра x и y, как указатели на данные типа int. Это означает, что функция swap работает с адресами целых переменных (а не с их значениями). Поэтому будут обработаны данные, адреса которых переданы функции во время обращения к ней. Функция main(), вызывает swap.

    #include

    swap(int *x, int *y)

    {

    int wr;

    wr = *x; *x = *y; *y =wr;

    }

    main()

    {

    int i,j;

    i = 100;

    j = 200;

    printf("Было: i=%d, j=%d\n",i,j);

    swap(&i,&j);

    printf("Стало: i =%d, j=%d\n",i,j);

    }

    После выполнения программы значения i и j поменяются местами. Необходимо отметить, что хотя указатели и экономят память, но они используют время процессора горазда больше.

    Таким образом, рассмотрены основные элементы языка Си.
    1   2   3   4   5   6   7   8   9


    написать администратору сайта