@pixik

Для чего в Си ввели синтаксис указателя на массив?

Добрый день!
В каких случаях нужно использовать указатель на массив?
Взято из СИ-ТЕСТ раздел 5 - объявление данных.
  • Вопрос задан
  • 338 просмотров
Пригласить эксперта
Ответы на вопрос 5
@Wexter
Например чтобы не передавать весь массив в функцию, а только указатель на него, тем самым избежав создания копии массива, сократив потребление памяти и времени вызова функции
Ответ написан
CityCat4
@CityCat4 Куратор тега C
//COPY01 EXEC PGM=IEBGENER
Потому что это удобно :) Есть сложные типы данных - структуры, обьединения, в которых полно указателей на другие указатели и пр. Очень часто обьекты данных такого типа агрегируются в массивы и адресуются указателями - получил один указатель и можешь перебирать огромный массив.
Си - системный язык и получить в качестве значения указатель, который адресует массив, содержащий указатели на элементы, каждый из которых указатель на что-нибудь с чем наконец-то можно и поработать - запросто :D
Ответ написан
Комментировать
x67
@x67
например, для передачи по ссылке, а не по значению. Это нужно:
а. когда массив во время выполнения функции может и должен меняться;
б. когда в массиве 100 000 000 000 000 000 000 (10^20) значений. Передача таких массивов в функции по значению несколько замедляет работу программы;
в. свой вариант (напишите в комментариях).
Ответ написан
@rPman
Для начала вопрос зачем в язык ввели понятие массив, а не остались с указателями - потому что типизация это добро. Т.е. на этапе компиляции можно будет понять, првильные ли переменные были переданы в функцию/метод, а так же можно узнать какой именно метод нужно использовать (методы с одинаковыми именами и разными типами параметров, плюс сюда в копилку темплейты С++)

Соответственно чтобы не передавать весь массив в качестве копии в методы, завели понятие ссылка (она не только к массивам определена, но и к любым объектам)
Ответ написан
@abcd0x00
Представь, например, что у тебя есть точка, которая описывается массивом её координат:
typedef int Point2D[2];
И дальше ты делаешь массив таких точек:
Point2D array[5];
А потом ты выводишь их по очереди:
Point2D *p, *q;

for (p = array, q = p + 5; p < q; p++) {
    print_point(*p);
}


А вот немного по-другому записано - и у тебя уже прямая получается:
typedef struct {
    Point2D *pt1;
    Point2D *pt2;
} Line2D;

Почему здесь указатели? Да потому что они жрут меньше памяти, чем массивы чисел. Так одна прямая жрёт 8 байт, а без указателей она жрала бы 16 байт. А была бы прямая в трёхмерном пространстве, то это так же занимало бы 8 байт, а без указателей - 24 байта.

Дальше код пошёл:
код
#include <stdio.h>

typedef int Point2D[2];

typedef struct {
    Point2D *pt1;
    Point2D *pt2;
} Line2D;

void print_point(Point2D p)
{
    printf("(%d,%d)\n", p[0], p[1]);
}

void print_line(Line2D l)
{
    printf("Line[\n");
    print_point(*l.pt1);
    print_point(*l.pt2);
    printf("Line]\n");
}

int main(void)
{
    Point2D array[5] = {{1, 2}, {3, 4}, {5, 6}};
    Point2D *p, *q;
    Line2D l;

    for (p = array, q = p + 5; p < q; p++) {
        print_point(*p);
    }

    l.pt1 = array;
    l.pt2 = array + 2;
    print_line(l);

    return 0;
}


Вывод
[guest@localhost c]$ .ansi t.c -o t
[guest@localhost c]$ ./t
(1,2)
(3,4)
(5,6)
(0,0)
(0,0)
Line[
(1,2)
(5,6)
Line]
[guest@localhost c]$



Как видишь, без этой возможности язык был бы гораздо ограниченней и сдох бы ещё в 80-е годы.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы