Раздел «Язык Си».ClassPointer:

Адрес объектов и переменных, указтели и ссылки.

Как переменные расположены в памяти.

Вся память в компьютере состоит из ячеек - байтов. Все байты расположены один за другим. Каждый байт имеет свой номер: первый, второй, третий и т.д. Никакой байт не может иметь номер 0.

Разные переменные или объекты дложны поместиться в память. Объект может занять один байт или больше. Например, переменная типа int может занять 4 байта.

Объекты могут занимать больше или меньше места в памяти. Но адрес каждого объекта - это номер первого байта (ячейки) в памяти с которой он размещается. Если объект поместили в память, то на это место никакие другие объекты или переменные уже не размещают.

Для того, работы с адресами нужны специальные переменные: указатели или ссылки. Каждая из таких переменных "знает" свой тип переменной или класс объекта, на которы будет указывать. Указатель "знает" номер байта и размер переменной или объекта.

На каждую переменную или объект могут "смотреть" несколько указателей. Если наша переменная или объект изменилась, ВСЕ указатели сразу об этом "узнают".

Например.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int main(){
   int a = 3; // переменная с именем a, где-то лежит в памяти
   int *point_to_a; // это указатель на переменны типа int. Получит адрес а, и будет "указывать" на a
   int *point2; // это второй указатель на переменные типа int;

// Получим АДРЕС(номер ячейки) переменной a. & -  вычисляет адрес
   point_to_a = &a;
// И для другой переменной тоже получим ЭТОТ адрес:.
  point2 = point_to_a;

// Теперь ОБА указателя "смотрят" на a
// Посмотрим ЗНАЧЕНИЕ a по указателю point_to_a. * перед именем указателя получает ЗНАЧЕНИЕ:
   printf("point to a : %d\n",*point_to_a);

   
// Теперь по указателю point2:
  printf("point to a : %d\n",*point2);
  
// Изменим значение a. Указатели мы не трогаем при этом.

  a = 123;

// Посмотрим ЗНАЧЕНИЕ по указателям point_to_a и point2

    printf("point to a : %d\n",*point_to_a);
    printf("point to a : %d\n",*point2);
// Напечаталось одно и тоже.

//Попробуем изменить переменную через указатель:
   *point2 = 255;

// Напечатаем значение a и point_to_a
    printf("point to a : %d\n",*point_to_a);
    printf("a : %d\n",a);    


//Печатается одно и тоже
   
   
}

Получим 10 чисел с клавиатуры. Для этого нужен scanf(). В scanf() даем переменную с & - оператор, который вычисляет адрес. Значит в scanf() можно сразу передать АДРЕС переменной.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(){
  int k;// переменная для числа
  int *pk; //УКАЗАТЕЛЬ - переменная для адреса (номера ячейки)
  int sum = 0; //  для суммы
  int i; // счетчик
// положили в УКАЗАТЕЛЬ pk АДРЕС (номер ячейки) k
  pk = &k; 

  for (i = 0; i< 10; i++){

// для scanf  нужен АДРЕС переменной
// даем адрес переменной k 
// этот адрес лежит в pk
    scanf("%d",pk);
// значение из scanf попало по адресу pk
//  в переменную k

// сложим это число
    sum += k;
// напечатаем
    printf("k = %d sum = %d\n",k,sum);
  }

}

Можно работать и с буквами

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(){
  char c; // здесь будут лежать буквы
  char *pc; // указатель (АДРЕС) на переменную с буквой
  int i; // счетчик
// положили АДРЕС (номер ячейки) переменной c  в указатель pc
  pc = &c;

  for (i = 0; i< 10; i++){
    scanf("%c",pc);
    if (c == 'A'){
       printf("%c\n",c);
    }
  }

}

Теперь мы можем использовать указатели и ссылки в функциях:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// В эту функцию параметры передаются как "обычно". В этом случает в функцию попадают КОПИИИ переменных
// А сам переменные в функции не используются

void swap1(int a, int b){
    int c;
    c = a;
    a = b;
    b = c; 
};

// В эту функцию параметры передаются "по ссылке". В этом случает в функцию попадают САМИ переменные
// Они будут изменены во время работы функции int& a - тоже адрес переменной, но чтобы получить 
// значение, не нужно  писать * перед именем

void swap(int* a, int* b){
    int c;
    c = *a;
    *a = *b;
    *b = c; 
};

int main(){
   int a = 5,b = 7;
   swap1(a,b);
// Ничего не изменилось
   printf("a = %d b = %d\n",a,b);
  
// Переменные поменялись местами
  swap(&a,&b);
    printf("a = %d b = %d\n",a,b);
}

REFACTOR Задача 1

Даны два числа а и b. Написать функцию void min(int * a, int * b), которая находит минимальное число из a и b и кладет в а это минимальное число, а в b другое число.

REFACTOR Задача 2

Даны два числа а и b. Написать функцию void plus_minus(int* a, int *b), которая кладет в а сумму этих чисел (*a + *b), а в b - разность (*a - *b).

Массивы .

Известно, что в С можно составлять массивы из "обычных" переменных. Каждый элемент массива имеет номер. По номеру массива мы знаем что там находится. Массивы можно составлять и из объектов классов. Каждый массив располагает свои элементы в памяти последовательно. Имя массива - это АДРЕС его первого элемента.

Задача про точки Допустим у нас есть прямая, на которой отмечены 5 точек. Необходимо

  1. получить значения всех точек
  2. печатать все эти значения
  3. вычислять растояния можду точками
  4. искать две точки с наименьшим расстоянием

REFACTOR Задача 3

Напечатать расстояние от точки с номером 0 до точки с номером N.

REFACTOR Задача 4

Напечатать расстояние от точки с номером K до точки с номером N.

REFACTOR Задача 5

Напечатать самую правую точку (max)

REFACTOR Задача 6

Напечатать самую левую точку (min)

REFACTOR Задача 7

1. Напечатать все расстояния от точки с номером 0.
2. Вычислить среднее расстояние от точки m[0] до всех остальных точек (Сложить все расстояния и разделить на 5)

REFACTOR Задача 8

Напечатать минимальное расстояние от точки с номером 0 и напечатать номер такой точки (кроме 0).

REFACTOR Задача 9

Напечатать минимальное расстояние от точки с номером 0 и сколько точек лежат на этом расстоянии (кроме 0).

REFACTOR Задача 10

Напечатать минимальное расстояние от точки с номером 0 и напечатать номера точек, которые лежат на этом расстоянии (кроме 0).

REFACTOR Задача 11

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

-- TatyanaOvsyannikova2011 - 30 Oct 2015

Attachment sortdown Action Size Date Who Comment
points1.png manage 110.6 K 30 Oct 2015 - 17:45 TatyanaOvsyannikova2011  
points_mass.png manage 160.5 K 30 Oct 2015 - 18:59 TatyanaOvsyannikova2011