Вторник, 21.05.2024, 03:49
Приветствую Вас, Гость

1)Указатели. Использование указателей при работе с массивами, при передаче параметров функциям.

Указатели - это переменные, показывающие место или адрес памяти, где расположены другие объекты (переменные, функции и др.). Так как указатель содержит адрес некоторого объекта, то через него можно обращаться к этому объекту.

   Унарная операция & дает адрес объекта, поэтому оператор у = &х;  присваивает адрес переменной х переменной у. Операцию & нельзя применять к константам и выражениям; конструкции вида &(х+7) или &28 недопустимы.

   Унарная операция * воспринимает свой операнд как адрес некоторого объекта и использует этот адрес для выборки содержимого, поэтому оператор  z = *y;  присваивает z значение переменной, записанной по адресу у. Если

     y = &x;;

     z = *у;

     то z = x.

   Объекты, состоящие из знака * и адреса (например, *а), необходимо определить. Делается это, например, так:

     int *а, *b, *с;

     char *d;

    Определение вида char *d говорит о том, что значение, записанное по адресу d, имеет тип char.

    Указатели могут встречаться и в выражениях. Если у - указатель на целое, т.е. имело место объявление int *у, то *у может появиться там же, где и любая другая переменная, не являющаяся указателем. Таким образом, следующие выражения вполне допустимы:

*у = 7; заносит число 7 в ячейку памяти по адресу у

*x *=5; увеличивает значение по адресу х в пять раз

(*z)++; добавляет единицу к содержимому ячейки памяти с адресом z

 Указатели можно использовать как операнды в арифметических операциях. Если у - указатель, то унарная операция y++ увеличивает его значение; теперь оно является адресом следующего элемента. Указатели и целые числа можно складывать. Конструкция у + n (у - указатель, n - целое число) задает адрес no объекта, на который указывает у. Это справедливо для любых объектов (int, char, float и др.); транслятор будет масштабировать приращение адреса в соответствии с типом, указанным в определении объекта.

     Любой адрес можно проверить на равенство (= =) или неравенство (!=) со специальным значением NULL, которое позволяет определить ничего не адресующий указатель.

 

Указатели и массивы

В языке "C" существует сильная взаимосвязь между указателями и массивами, настолько сильная, что указатели и массивы действительно следует рассматривать одновременно. Любую операцию, которую можно выполнить с помощью индексов массива, можно сделать и с помощью указателей. Вариант с указателями обычно оказывается более быстрым, но и несколько более трудным для непосредственного понимания, по крайней мере, для начинающего. Описание int a[10] определяет массив размера 10, т.е. набор из 10 последовательных объектов, называемых a[0], a[1], ..., a[9]. Запись a[i] соответствует элементу массива через i позиций от начала. Если pa – указатель целого, описанный как int *pa, то присваивание pa = &a[0] приводит к тому, что pa указывает на нулевой элемент массива a; это означает, что pa содержит адрес элемента a[0]. Теперь присваивание  x = *pa будет копировать содержимое a[0] в x.

Если ра указывает на некоторый определенный элемент массива a, то по определению pa+1 указывает на следующий элемент, и вообще pa-i указывает на элемент, стоящий на i позиций до элемента, указываемого pa,а pa+i на элемент, стоящий на i позиций после. Таким образом, если pa указывает на a[0], то *(pa+1) ссылается на содержимое a[1], pa+i - адрес a[i], а *(pa+i) – содержимое a[i].

 

2) Оператор goto. Рекомендации по его использованию и примеры.

Действие передачи управления оператору указано меткой. Метки образуются по правилам, что и идентификаторы и отделяются от оператора «:».

Рекомендации: пользуйтесь goto как можно реже, он затрудняет компилятору оптимизацию кода, а также усложняет чтение и сопровождение программы.

Ограничения по использованию goto:

1) Избегайте входа внутрь блока из вне. Язык это разрешает, но если выше точки входа находились объявления переменных с инициализацией, то значения этих переменных будут мусором.

goto inblock;

{ int a=1;

 int b=2;

 inblock: …

}

2) Не входить внутрь оператора if-else и switch из вне (язык это запрещает).

3) Не входить внутрь циклов из вне.

Пригождение goto:

1) При выходе из глубокой вложенности цикла

В двумерном массиве найти первый отрицательный элемент:

for (i=0; i<m; i++)

        for (j=0; j<n; j++)

                if (a[i][j]<0)

                {index i=-i;

                index j=-j;

                goto label;

                }

label; …

2) Уменьшение вложенности

If (усл)

{код

}

3) Если ошибки могут возникать в нескольких местах, а ветвь обработки ошибок значительна.

4) Полезно также использовать goto при переводе программы с неструктурированных языков (basic и др.)


3.  Напишите функцию поиска самой длинной цепочки из подряд идущих одинаковых элементов  в массиве.

 

# include <stdio.h>

# include <stdlib.h>

 

  const n=10;

  int s[n];

  int x[n],maxk=1,j;

 

void poisk(int a[])

{

 for (int i=0;i<n;i++)

    {

      int k=1;

      if (a[i]==a[i+1])

            { j=i;

              while (a[j]==a[j+1]) { j++; k++;}

            }

      if (k>maxk)

            { maxk=k;

              for (k=0;i<=j;i++,k++)

                 x[k]=a[i];

            }

     }

}

 

 

 и мой собственный вариант=Ю

 

 

#include<stdio.h>

#include<conio.h>

 

int arr[]={'1','2','4','4','4','4','w','w','32','s','2','3','2','1','2'};

int i,j,k,m,record,recordabs,end;

int n=sizeof(arr)/sizeof(int);

 

int main()

{

 clrscr();

 m=0;

 recordabs = 0;

 for (i=0, j=i+1; j < n; )

     {

      if (arr[i] == arr[j])

             {

              record = j-i+1;

              if (recordabs < record) {recordabs = record; k = i;}

              j++;

             }

      else {i++;j=i+1;}

     }

 end = recordabs + k;

  printf ("Position = %d; Lenth = %d;\n The string: ",k,recordabs);

 for (i=k;i<end;i++)

      printf(" %c ",arr[i]);

 getch();

}


4.   Напишите функцию, выдающую на экран битовое представление заданного вещественного числа.

 

 

#include<conio.h>

#include<stdio.h>

 

 

void preds(unsigned char*b)

{

for(int i=7;i>=0;i--)

    printf("%d",(*b >> i) & 1);

    printf(" ");

}

void main()

{

int i;

float ch=-123.5123421;

 

unsigned char*b;

 

clrscr();

 

b = (unsigned char*) & ch;

for(i=0; i<sizeof(float); i++)

    preds(b++);

 

getch();

}