ссылки и указатели в c для чего нужны
Указатели в C++: зачем нужны, когда использовать и чем отличаются
Память компьютера — это длинный ряд ячеек. Размер каждой ячейки называется байтом. Байт — это пространство, занятое английским символом алфавита. Объект в обычном понимании — это последовательный набор байтов в памяти. Каждая ячейка имеет адрес, который представляет собой целое число, обычно записанное в шестнадцатеричной форме. Есть три способа доступа к объекту в памяти. Доступ к объекту можно получить с помощью так называемого указателя. Доступ к нему можно получить, используя так называемую ссылку. К нему по-прежнему можно получить доступ с помощью идентификатора. В этой статье основное внимание уделяется использованию указателей и ссылок. В C ++ есть заостренный объект и объект-указатель. У остроконечного предмета есть интересующий предмет. Объект-указатель имеет адрес указанного объекта.
Вам необходимо иметь базовые знания C ++, включая его идентификаторы, функции и массивы; чтобы понять эту статью.
У объекта-указателя и объекта-указателя есть свой идентификатор.
Оператор Address-Of, &
Это унарный оператор. Если за ним следует идентификатор, он возвращает адрес объекта идентификатора. Рассмотрим следующее объявление:
Ниже приведен код, следующее выражение, вернет адрес, идентифицированный ptdInt:
Вам не нужно знать точный адрес (номер) при кодировании.
Оператор косвенного обращения, *
Это унарный оператор в контексте указателей. Обычно он печатается перед идентификатором. Если используется в объявлении идентификатора, то идентификатор является объектом-указателем, который содержит только адрес указанного объекта. Если используется перед идентификатором объекта-указателя, чтобы что-то вернуть, то возвращаемое значение является значением указанного объекта.
Создание указателя
Взгляните на следующий фрагмент кода:
Сегмент начинается с объявления указанного объекта ptdFloat. ptdFloat — это идентификатор, который просто идентифицирует объект с плавающей запятой. Ему мог быть присвоен реальный объект (значение), но в этом случае ему ничего не было присвоено. Далее в сегменте идет объявление объекта-указателя. Оператор косвенного обращения перед этим идентификатором означает, что он должен содержать адрес указанного объекта. Тип объекта, плавающий в начале оператора, означает, что заостренный объект является плавающим. Объект-указатель всегда имеет тот же тип, что и заостренный объект. ptrFoat — это идентификатор, который просто идентифицирует объект-указатель.
В последнем операторе кода адрес указанного объекта присваивается объекту-указателю. Обратите внимание на использование оператора адресации &.
Последний оператор (строка) выше показывает, что после объявления объекта-указателя без инициализации вам не нужен оператор косвенного обращения, когда вам нужно его инициализировать. Фактически, использование оператора косвенного обращения в третьей (последней) строке является синтаксической ошибкой.
Объект-указатель может быть объявлен и инициализирован указанным объектом в одной инструкции, как показано ниже:
Первая строка предыдущего сегмента кода и эта совпадают. Здесь вторая и третья строки предыдущего сегмента кода объединены в один оператор.
Обратите внимание, что в приведенном выше коде при объявлении и инициализации объекта-указателя необходимо использовать оператор косвенного обращения. Однако он не используется, если инициализация должна быть выполнена позже. Объект-указатель инициализируется адресом указанного объекта.
В следующем сегменте кода оператор косвенного обращения используется для возврата содержимого указанного объекта.
В последнем предложении здесь оператор косвенного обращения использовался для возврата значения, на которое указывает идентификатор указателя. Таким образом, при использовании в объявлении идентификатор для оператора косвенного обращения будет содержать адрес указанного объекта. При использовании в выражении возврата в сочетании с идентификатором указателя оператор косвенного обращения возвращает значение указанного объекта.
Присвоение нуля указателю
Объект-указатель всегда должен иметь тип указанного объекта. При объявлении объекта-указателя должен использоваться тип данных указанного объекта. Однако значение десятичного нуля может быть присвоено указателю, как в следующем сегменте кода:
int ptdInt = 5 ;
int * ptrInt = ;
В любом случае указатель (идентификатор) называется нулевым указателем; это означает, что он указывает в никуда. То есть у него нет адреса какого-либо указанного объекта. Здесь 0 — это десятичный ноль, а не шестнадцатеричный ноль. Шестнадцатеричный ноль будет указывать на первый адрес памяти компьютера.
Не пытайтесь получить значение, на которое указывает нулевой указатель. Если вы попробуете это сделать, программа может скомпилироваться, но не запуститься.
Имя массива как постоянный указатель
Рассмотрим следующий массив:
Имя массива arr на самом деле является идентификатором, который имеет адрес первого элемента массива. Следующее выражение возвращает первое значение в массиве:
В случае с массивом оператор приращения ++ ведет себя иначе. Вместо добавления 1 он заменяет адрес указателя на адрес следующего элемента в массиве. Однако имя массива — это постоянный указатель; это означает, что его содержимое (адрес) не может быть изменено или увеличено. Итак, для увеличения начальный адрес массива должен быть назначен непостоянному указателю следующим образом:
Теперь ptr можно увеличивать, чтобы указывать на следующий элемент массива. ptr был объявлен здесь как объект-указатель. Без * здесь не было бы указателя; это будет идентификатор для хранения объекта типа int, а не для хранения адреса памяти.
Следующий сегмент кода, наконец, указывает на четвертый элемент:
Следующий код выводит четвертое значение массива:
Имя функции как идентификатор
Имя функции — это идентификатор функции. Рассмотрим следующее определение функции:
fn — идентификатор функции. Выражение,
возвращает адрес функции в памяти. fn похожа на заостренный объект. Следующее объявление объявляет указатель на функцию:
Идентификатор указанного объекта и идентификатор объекта-указателя различаются. func — это указатель на функцию. fn — идентификатор функции. Итак, func может указывать на fn следующим образом:
Значение (содержание) func — это адрес fn. Два идентификатора могли быть связаны с помощью оператора инициализации следующим образом:
Обратите внимание на различия и сходства в обработке указателей функций и скалярных указателей. func — указатель на функцию; это заостренный объект; он объявлен иначе, чем скалярный указатель.
Функцию можно вызвать с помощью,
Его нельзя вызвать с помощью * func ().
Когда функция имеет параметры, во вторых скобках указаны типы параметров, и для них не обязательно должны быть идентификаторы. Следующая программа иллюстрирует это:
#include
using namespace std ;
C++ Reference
Ссылка в C ++ — это просто способ создать синоним (другое имя) для идентификатора. Он использует оператор &, но не так, как & используется для указателей. Рассмотрим следующий фрагмент кода:
cout myInt ‘ \n ‘ ;
cout yourInt ‘ \n ‘ ;
Первый оператор инициализирует идентификатор myInt; т.е. myInt объявлен и содержит значение 8. Второй оператор создает новый идентификатор yourInt, синоним myInt. Для этого в объявлении между типом данных и новым идентификатором помещается оператор &. Операторы cout показывают, что два идентификатора являются синонимами. Чтобы вернуть значение в этом случае, вам не нужно ставить перед ним *. Просто используйте идентификатор.
Здесь myInt и yourInt — это не два разных объекта. Это два разных идентификатора, которые ссылаются (идентифицируют) одно и то же место в памяти, имеющее значение 8. Если значение myInt изменяется, значение yourInt также изменится автоматически. Если значение yourInt изменится, значение myInt также изменится автоматически.
Ссылка на функцию
Так же, как у вас может быть ссылка на скаляр, вы также можете иметь ссылку на функцию. Однако кодирование ссылки на функцию отличается от кодирования ссылки на скаляр. Следующая программа иллюстрирует это:
Обратите внимание на первый оператор в функции main, который делает func синонимом fn. Оба ссылаются на одну и ту же функцию. Обратите внимание на одноразовое использование и положение &. Таким образом, & является здесь ссылочным оператором, а не оператором адресации. Чтобы вызвать функцию, просто используйте любое имя.
Идентификатор ссылки — это не то же самое, что идентификатор указателя.
Функция, возвращающая указатель
В следующей программе функция возвращает указатель, который является адресом указанного объекта:
Первый оператор в функции fn () предназначен только для создания объекта-указателя. Обратите внимание на одноразовое использование и положение * в сигнатуре функции. Также обратите внимание, как указатель (адрес) был получен в функции main () другим объектом-указателем.
Функция, возвращающая ссылку
В следующей программе функция возвращает ссылку:
Первый оператор в функции fn () предназначен только для создания ссылки. Обратите внимание на одноразовое использование и положение & в сигнатуре функции. Также обратите внимание, как ссылка была получена в функции main () по другой ссылке.
Передача указателя на функцию
В следующей программе указатель, который на самом деле является адресом объекта с плавающей точкой, отправляется в качестве аргумента функции:
int main ( )
<
float v = 2.5 ;
Обратите внимание на использование и положение * для параметра с плавающей запятой в сигнатуре функции. Как только начинается вычисление функции fn (), делается следующий оператор:
Передача ссылки на функцию
В следующей программе ссылка отправляется в качестве аргумента функции:
int main ( )
<
float v = 2.5 ;
Обратите внимание на использование и положение & для параметра float в сигнатуре функции. Как только начинается вычисление функции fn (), делается следующий оператор:
Передача массива функции
Следующая программа показывает, как передать массив функции:
int fn ( int arra [ ] )
<
return arra [ 2 ] ;
>
В этой программе передается массив. Обратите внимание, что параметр сигнатуры функции имеет объявление пустого массива. Аргументом в вызове функции является только имя созданного массива.
Может ли функция C ++ вернуть массив?
Функция в C ++ может возвращать значение массива, но не может возвращать массив. Компиляция следующей программы приводит к сообщению об ошибке:
int fn ( int arra [ ] )
<
return arra ;
>
Указатель указателя
Указатель может указывать на другой указатель. То есть объект-указатель может иметь адрес другого объекта-указателя. Они по-прежнему должны быть одного типа. Следующий фрагмент кода иллюстрирует это:
В объявлении указателя на указатель используется двойной *. Чтобы вернуть значение последнего заостренного объекта, по-прежнему используется двойной *.
Массив указателей
Следующая программа показывает, как кодировать массив указателей:
Обратите внимание на использование и положение * в объявлении массива. Обратите внимание на использование * при возврате значения в массиве. С указателями указателей задействованы два *. В случае массива указателей об одном * уже позаботились, потому что идентификатор массива является указателем.
Массив строк переменной длины
Строковый литерал — это константа, возвращающая указатель. Массив строк переменной длины — это массив указателей. Каждое значение в массиве является указателем. Указатели — это адреса к ячейкам памяти, они имеют одинаковый размер. Строки разной длины находятся в другом месте памяти, а не в массиве. Следующая программа иллюстрирует использование:
На выходе получается «girl».
Объявление массива начинается с зарезервированного слова «const» для константы; за которым следует «char» для символа, затем звездочка *, чтобы указать, что каждый элемент является указателем. Чтобы вернуть строку из массива, * не используется из-за неявного характера указателя каждой строки. Если используется *, то будет возвращен первый элемент строки.
Указатель на функцию, возвращающую указатель
Следующая программа показывает, как кодируется указатель на функцию, возвращающую указатель:
int * fn ( )
<
int num = 4 ;
int * inter = & num ;
return inter ;
>
int * ( * func ) ( ) = & fn ;
int val = * func ( ) ;
Объявление указателя на функцию, возвращающую указатель, аналогично объявлению указателя на обычную функцию, но перед ним стоит звездочка. Первый оператор в функции main () иллюстрирует это. Чтобы вызвать функцию с помощью указателя, поставьте перед ней *.
Заключение
Чтобы создать указатель на скаляр, сделайте что-нибудь вроде:
* имеет два значения: в объявлении указывает указатель; чтобы что-то вернуть, это значение указанного объекта.
Имя массива — это постоянный указатель на первый элемент массива.
Чтобы создать указатель на функцию, вы можете:
где fn () — функция, определенная в другом месте, а func — указатель.
Чтобы создать ссылку на функцию, вы можете:
где fn () — функция, определенная в другом месте, а refFunc — ссылка.
Когда функция возвращает указатель, возвращаемое значение должно быть получено указателем. Когда функция возвращает ссылку, возвращаемое значение должно быть получено по ссылке.
При передаче указателя на функцию параметр является объявлением, а аргумент — адресом указанного объекта. При передаче ссылки на функцию параметр является объявлением, а аргумент — ссылкой.
При передаче массива функции параметр — это объявление, а аргумент — это имя массива без []. Функция C ++ не возвращает массив.
Для указателя на указатель требуется два * вместо одного, где это необходимо.
Ссылки и указатели в c для чего нужны
Указатели совместно с адресной арифметикой играют в Си особую роль. Можно сказать, что они определяют лицо языка. Благодаря им Си может считаться одновременно языком высокого и низкого уровня по отношению к памяти.
Если говорить о понятиях указатель, ссылка, объект, то они встречаются не только в языках программирования, но в широком смысле в информационных технологиях. Когда речь идет о доступе к информационным ресурсам, то существуют различные варианты доступа к ним:
В языках программирования термины объект (значение), указатель и ссылка имеют примерно аналогичный смысл, но касаются способов доступа и передачи значений переменных.
· при передаче формальных параметров при вызове процедур (функций) практически во всех языках программирования реализованы способы передачи по ссылке и по значению;
· в Паскале и Си определено понятие указатель как переменная особого вида, содержащая адрес размещения в памяти другой переменной. Использование указателей позволяется создавать динамические структуры данных, в которых элементы взаимно ссылаются друг на друга;
Указатель в Си
Передавать данные между программами, данные от одной части программы к другой (например, от вызывающей функции к вызываемой) можно двумя способами :
· создавать в каждой точке программы (например, на входе функции) копию тех данных, которые необходимо обрабатывать ;
Наряду с указателем в программировании также используется термин ссылка. Ссылка – содержанием ссылки также является адресная информация об объекте (переменной), но внешне она выглядит как переменная (синоним оригинала).
В языках программирования имя переменной ассоциируется с адресом области памяти, в которой транслятор размещает ее в процессе трансляции программы. Все операции над обычными переменными преобразуются в команды с прямой адресацией к соответствующим словам памяти.
· указатель, который содержит адрес переменной, ссылается на эту переменную или назначен на нее;
· переменная, адрес которой содержится в указателе, называется указуемой переменной.
рис. 52-2. Определение указателя и операции над ним
Последовательность действий при работе с указателем включает 3 шага:
1. Определение указуемых переменных и переменной-указателя. Для переменной-указателя это делается особым образом.
int a,x; // Обычные целые переменнные
2. Связывание указателя с указуемой переменной. Значением указателя является адрес другой переменной. Следующим шагом указатель должен быть настроен, или назначен на переменную, на которую он будет ссылаться.
p = &a; // Указатель содержит адрес переменной a
3. И наконец, в любом выражении косвенное обращение по указателю интерпретируется как переход от него к указуемой переменной с выполнением над ней всех далее перечисленных в выражении операций.
* p =100; // Эквивалентно a =100
x = x + *p; // Эквивалентно x = x + a
(* p )++; // Эквивалентно a ++
Замечание: при обращении через указатель имя указуемой переменной в выражении отсутствует. Поэтому можно считать, что обращение через указатель производится к «безымянной» переменной, а операцию « *» называются также операцией разыменования указателя.
Указатель дает « степень свободы» или универсальности любому алгоритму обра
ботки данных. Действительно, если некоторый фрагмент программы получает данные непосредственно в некоторой переменной, то он может обрабатывать ее и только ее. Если же данные он получает через указатель, то обработка данных (указуемых переменных) может производиться в любой области памяти компьютера (или программы). При этом сам фрагмент может и «не знать», какие данные он обрабатывает, если значение самого указателя передано программе извне.
Адресная арифметика и управление памятью
Способность указателя ссылаться на «отдельно стоящие» переменные не меняет качества языка, поскольку нельзя выйти за рамки множества указуемых переменных, определенных в программе. Такая же концепция указателя принята, например, в Паскале. Но в Си существует еще одна, расширенная интерпретация, позволяющая через указатель работать с массивами и с памятью компьютера ни низком (архитектурном) уровне без каких-либо ограничений со стороны транслятора. Это «свобода самовыражения» обеспечивается одной дополнительной операцией адресной арифметики. Но сначала определим свойства указателя в соответствии с расширенной интерпретацией.
Любой указатель в Си ссылается на неограниченную в обе стороны область памяти (массив), заполненную переменными указуемого типа с индексацией элементов относительно текущего положения указателя.
· любой указатель потенциально ссылается на неограниченную в обе стороны область памяти, заполненную переменными указуемого типа;
· результатом операции указатель+i является адрес i-ой переменной (значение указателя на i-ую переменную) в этой области относительно текущего положения указателя.
Значение указуемой переменной
Указатель на i-ю переменную после указуемой
Указатель на i-ю переменную перед указуемой
Значение i-й переменной после указуемой
Значение i-й переменной после указуемой
Переместить указатель на следующую переменную
Переместить указатель на предыдущую переменную
Переместить указатель на i переменных вперед
Переместить указатель на i переменных назад
Получить значение указуемой переменной и переместить указатель к следующей
Переместить указатель к переменной, предшествующей указуемой, и получить ее значение
Указатель на свободную память вслед за указуемой переменной
Если МАССИВ=ПАМЯТЬ+УКАЗАТЕЛЬ (начальный адрес), то УКАЗАТЕЛЬ=МАССИВ-ПАМЯТЬ, т.е. указатель это «массив без памяти», «свободно перемещающийся по памяти» массив.
Различия и сходства
Оба интерпретируются как указатели и оба имеют тип int *
Указатель требует настройки «на память»
Работа с областью памяти как с обычным массивом, так и через указатель полностью идентична вплоть до синтаксиса
Указатель может перемещаться по памяти относительно своего текущего положения
Идентификатор массива без скобок интерпретируется как адрес нулевого элемента нулевой строки, или указатель на базовый тип данных. В нашем примере идентификатору A будет соответствовать выражение &A[0][0] с типом char*.
Имя двумерного массива с единственным индексом интерпретируется как начальный адрес соответствующего внутреннего одномерного массива. A[i] понимается как &A[i][0], то есть начальный адрес i-го массива символов.
От такого многообразия возможностей работы с указателями нетрудно прийти в замешательство: как вообще с ними работать, кто за что отвечает? Действительно, при работе с указателями легко выйти «за рамки дозволенного», т.е. определенных самим же программистом структур данных. Поэтому попробуем еще раз обсудить принципиальные моменты адресной арифметики.
· наличие операции инкремента или индексации говорит о работе указателя с памятью (массивом) ;
· использование исключительно операции косвенного обращения по указателю свидетельствует о работе с отдельной переменной.
· неинициализированный указатель. После определения указатель ссылается «в никуда», тем не менее программист работает через него с переменной или массивом, записывая данные по случайным адресам;
· несколько указателей, ссылающихся на общий массив – это все-таки один массив, а не несколько. Если программа работает с несколькими массивами, то они должны либо создаваться динамически, либо браться из двумерного массива;
· выход указателя за границы памяти. Например, конец строки отмечается символов ‘\0’, начало же формально соответствует начальному положению указателя. Если в процессе работы со строкой требуется возвращение на ее начало, то начальный указатель необходимо запоминать, либо дополнительно отсчитывать символы.
Другие операции над указателями
В процессе определения указателей мы рассмотрели основные операции над ними:
· операция присваивания указателей одного типа. Назначение указателю адреса переменной p=&a есть одни из вариантов такой операции;
· операция косвенного обращения по указателю (разыменования указателя);
· операция адресной арифметики «указатель+целое» и все производные от нее.
Значение NULL может быть присвоено любому указателю. Если указатель по логике работы программы может иметь такое значение, то перед косвенным обращением по нему его нужно проверять на достоверность:
//— Симметричная перестановка символов строки
< char c; c=*p; *p=*q; *q=c; >// 3 стакана над переменными под указателями
extern int fread(void *, int, int, FILE *);
fread(A, sizeof(int), 20, fd);
extern void *malloc(int);
int *p = (int*)malloc(sizeof(int)*20); // Явное преобразование void* к int*
Указатель как формальный параметр и результат функции
Если же фактический параметр должен быть изменен, то формальный параметр можно определить как явный указатель. Тогда фактический параметр должны быть явно передан в виде указателя на ту переменную (с использованием операции &).
< (* pi )++; >// аналог вызова: pi = & a
inc (& a ); > // *( pi )++ эквивалентно a ++
int sum(int A[],int n) // Исходная программа
int sum(int *p, int n) // Эквивалент с указателем
< x = sum(B,10); >// аналог вызова : p = B, n = 10
В вызове фигурирует идентификатор массива, который интерпретируется как указатель на начало. Поэтому типы формального и фактического параметров совпадают. Совпадают также оба варианта функций вплоть до генерируемого кода.
· глобальные переменные программы;
· формальные параметры, если они являются массивами, указателями или ссылками, то есть «за ними стоят» другие переменные.
Функция не может возвратить указатель на локальную переменную или формальный параметр-значение, поскольку они разрушаются при выходе из функции. Это приводит к ошибке времени выполнения, не обнаруживаемой транслятором.
Пример: функция возвращает указатель на минимальный элемент массива. Массив передается как формальный параметр.
int *min(int A[], int n)<
int *pmin, i; // Рабочий указатель, содержащий результат
Ссылка как неявный указатель
Во многих языках программирования указатель присутствует, но в завуалированном виде в форме ссылки. Под ссылкой понимается переменная, которая не имеет самостоятельного значения, а отображается на другую переменную, т.е. является ее синонимом. Во всем остальном она не отличается от обычной переменной. В отличие от явного указателя обращение по ссылке к объекту-прототипу имеет тот же самый синтаксис, что и обращение к объекту-прототипу.
int a =5; // Переменная – прототип
b ++; // Операция над b есть операция над прототипом a
· при передаче по значению формальный параметр является копией фактического, он может быть изменен независимо от значения оригинала – фактического параметра. Такой параметр является исключительно входным;
· при передаче по ссылке формальный параметр отображается на фактический, и его изменение сопровождается изменением фактического параметра-прототипа. Такой параметр может быть как входным, так и выходным.
//—— Функция возвращает ссылку на минимальный элемент массива
int &ref_min(int A[], int n)<
//—— Функция возвращает указатель на минимальный элемент массива
int *ptr_min(int *p, int n)<
Строки, массивы символов и указатель char *
int n; // указателем на на строку char*
· создание массива символов с размерностью, достаточной для размещения строки;
· инициализацию (заполнение) массива символами строки, дополненной символом ‘\0’;
char * q = «ABCD»;; // Программа
char *q; // Эквивалент
В связи с этим в Си возможны довольно странные выражения с участием строковых констант:
char c2 = («12345» + 2)[1];
extern int strcmp(char *, char*);
Посмотрим, как все вышесказанное выглядит на практике.
//—- Поиск в строке заданного фрагмента
> // иначе продолжить поиск
Для обнаружения всех фрагментов достаточно передавать для каждого последующего вызова функции указатель на часть строки, непосредственно следующей за найденным фрагментом.
//—— Поиск всех вхождений фрагмента в строке
for (s=find(c,q); s!=NULL; s=find(s+strlen(q),q)) puts(s);
//—- Поиск слова максимальной длины посимвольная обработка
int n,lmax; char *pmax;
for (n=0,lmax=0,pmax=NULL; *s!=0;s++)<
n =0; // фиксация максимального значения
//—- Сортировка слов в строке в порядке убывания (выбором)
void sort(char *in, char *out)
* out ++= * q ; * q ++=’ ‘; // Переписать с затиранием
* out ++=’ ‘; // После слова добавить пробел
Лабораторный практикум
1. Функция находит минимальный элемент массива и возвращает указатель на него. С использованием этой функции реализовать сортировку выбором.
2. Шейкер-сортировка с использованием указателей на правую и левую границы отсортированного массива и сравнения указателей.
3. Функция находит в строке пары одинаковых фрагментов и возвращает указатель на первый. С помощью функции найти все пары одинаковых фрагментов.
4. Функция находит в строке пары инвертированных фрагментов (например «123apr» и «rpa321») и возвращает указатель на первый. С помощью функции найти все пары.
5. Функция производит двоичный поиск места размещения нового элемента в упорядоченном массиве и возвращает указатель на место включения нового элемента. С помощью функции реализовать сортировку вставками.
6. Функция находит в строке десятичные константы и заменяет их на шестнадцатеричные с тем же значением, например «aaaaa258xxx» на «aaaaa0x102xxx».
7. Функция находит в строке символьные константы и заменяет их на десятичные коды, например «aaa’6’xxx» на «aaa54xxx».
8. Функция находит в строке самое длинное слово и возвращает указатель на него. С ее помощью реализовать размещение слов в выходной строке в порядке убывания их длины.
9. Функция находит в строке самое первое (по алфавиту) слово. С ее помощью реализовать размещение слов в выходной строке в алфавитном порядке.
10. Функция находит в строке симметричный фрагмент вида » abcdcba » длиной 7 и более символов (не содержащий пробелов) и возвращает указатель на его начало и длину. С использованием функции «вычеркнуть» все симметричные фрагменты из строки.
11. «Быстрая» сортировка (разделением) с использованием указателей на правую и левую границы массива, текущих указателей на правый и левый элемент и операции сравнения указателей (см. 7.2).
Вопросы без ответов
Определите, используется ли указатель для доступа к отдельной переменной или к массиву. Напишите вызов функции с соответствующими фактическими параметрами – адресами переменных или именами массивов.
void F(int *p, int *q, int n)<
F(A,&x,5); printf(«x=%d\n»,x); > // Выведет 13