Пятница, 17.05.2024, 22:03
Приветствую Вас, Гость

БИЛЕТ 27.

1) Проверка вида символов и преобразования

Некоторые макросы выполняют проверку символов и преобразования:

isalpha(c) не 0, если "c" алфавитный символ, 0 - если нет.

isupper(c) не 0, если "c" буква верхнего регистра, 0 - если нет.

islower(c) не 0, если "c" буква нижнего регистра, 0 - если нет.

isdigit(c) не 0, если "c" цифра, 0 - если нет.

isspacl(c) не 0, если "c" пробел, табуляция или новая строка, 0 - если нет.

toupper(c) преобразует "c" в букву верхнего регистра.

tolower(c) преобразует "c" в букву нижнего регистра.

 

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

В языке "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.

Если PA указывает на некоторый определенный элемент массива  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].

Эти замечания справедливы независимо от типа переменных в массиве A. Суть определения "добавления 1 к указателю", а также его распространения на всю арифметику указателей, состоит в том, что приращение масштабируется размером памяти, занимаемой объектом, на который указывает указатель. Таким образом, I в PA+I перед прибавлением умножается на размер

объектов, на которые указывает PA.

Очевидно существует очень тесное соответствие между индексацией и арифметикой указателей. в действительности компилятор преобразует ссылку на массив в указатель на начало массива. В результате этого имя массива является указательным выражением. Отсюда вытекает несколько весьма полезных следствий. Так как имя массива является синонимом местоположения его нулевого элемента, то присваивание PA=&A[0] можно записать как PA = A

 Еще более удивительным, по крайней мере на первый взгляд, кажется тот факт, что ссылку на A[I] можно записать в виде *(A+I). При анализировании выражения A[I] в языке "C" оно немедленно преобразуется к виду *(A+I); эти две формы совершенно эквивалентны. Если применить операцию & к обеим частям такого соотношения эквивалентности, то мы получим, что &A[I] и A+I тоже идентичны: A+I - адрес I-го элемента от начала A. С другой стороны, если PA является указателем, то в выражениях его можно использовать с индексом: PA[I] идентично *(PA+I). Короче, любое выражение, включающее массивы и индексы, может быть записано через указатели и смещения и

наоборот, причем даже в одном и том же утверждении.

Имеется одно различие между именем массива и указателем,

которое необходимо иметь в виду. указатель является перемен-

ной, так что операции PA=A и PA++ имеют смысл. Но имя массива является константой, а не переменной: конструкции типа A=PA или A++,или P=&A будут незаконными.

Когда имя массива передается функции, то на самом деле ей передается местоположение начала этого массива. Внутри вызванной функции такой аргумент является точно такой же переменной, как и любая другая, так что имя массива в качестве аргумента действительно является указателем, т.е. Переменной, содержащей адрес. мы можем использовать это обстоятельство для написания нового варианта функции STRLEN, вычисляющей длину строки.

 STRLEN(S)       /* RETURN LENGTH OF STRING S */

 CHAR *S;

 {  INT N;

    FOR (N = 0; *S != '\0'; S++)

            N++;

    RETURN(N);

 }

    Операция увеличения S совершенно законна, поскольку эта переменная является указателем; S++ никак не влияет на символьную строку в обратившейся к STRLEN функции, а только увеличивает локальную для функции STRLEN копию адреса. Описания формальных параметров в определении функции в виде

CHAR S[];

CHAR *S;

совершенно эквивалентны; какой вид описания следует предпочесть, определяется в значительной степени тем, какие выражения будут использованы при написании функции. Если функции передается имя массива, то в зависимости от того, что удобнее, можно полагать, что функция оперирует либо с массивом, либо с указателем, и действовать далее соответвующим образом. Можно даже использовать оба вида операций, если это кажется уместным и ясным.

Можно передать функции часть массива, если задать в качестве аргумента указатель начала подмассива. Например, если A - массив, то как

F(&A[2]) как и F(A+2) передают  функции F адрес элемента A[2], потому что и &A[2], и A+2 являются указательными  выражениями,  ссылающимися  на третий элемент A. внутри функции F описания аргументов могут присутствовать в виде:

F(ARR)

INT ARR[];

{   ...

}

или

F(ARR)

INT *ARR;

{ ...

}

Что касается функции F, то тот факт, что ее аргумент в действительности ссылается к части большего массива, не имеет для нее никаких последствий.


*************************************27 - 3

Напишите функцию сравнения двух строк.


//sravnenie 2 strok

            int strcmp(char *s1, char *s2)

{

            int i=0;

            while (s1[i] == s2[i] && s1[i] && s2[i])

                        i++;

            if (s1[i]>s2[i])

                        return 1;

            else if(s1[i]<s2[i])

                        return -1;

  else

    return 0;

}


*************************************27 - 4

Из заданного натурального числа n удалить все четные цифры.


#include<stdio.h>

#include<conio.h>

#include<math.h>

 int  n=10;

 int k;

 int ost,i;

 

 void main()

 {

 clrscr();

 printf("%d\n",n);

    k=0;i=0;

    while(n!=0)

      {

       ost=n%10;

       n=(n-n%10)/10;

       if(ost%2==1)

             {

              k=k+ost*pow(10,i);

              i++;

             }

      }

 printf("%d",k);

 getch();

 }