Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КУРС Программирование на Си.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
606.21 Кб
Скачать

Указатели

Указатель - это переменная, содержащая адрес другой пе­ременной. указатели очень широко используются в языке "C". Это происходит отчасти потому, что иногда они дают единст­венную возможность выразить нужное действие, а отчасти пото­му, что они обычно ведут к более компактным и эффективным программам, чем те, которые могут быть получены другими спо­собами.

Указатели и адреса

Так как указатель содержит адрес объекта, это дает воз­можность "косвенного" доступа к этому объекту через указа­тель. Предположим, что х - переменная, например, типа INT, а рх - указатель, созданный неким еще не указанным способом. Унарная операция & выдает адрес объекта, так что оператор

рх = &х; присваивает адрес х переменной рх; говорят, что рх "ука­зывает" на х. Операция & применима только к переменным и элементам массива, конструкции вида &(х-1) и &3 являются не­законными. Нельзя также получить адрес регистровой перемен­ной.

Унарная операция * рассматривает свой операнд как адрес конечной цели и обращается по этому адресу, чтобы извлечь содержимое. Следовательно, если Y тоже имеет тип INT, то

Y = *рх; присваивает Y содержимое того, на что указывает рх. Так пос­ледовательность

рх = &х;

Y = *рх;

присваивает Y то же самое значение, что и оператор

Y = X;

Переменные, участвующие во всем этом необходимо описать:

INT X, Y;

INT *PX;

Описание указателя

INT *PX;

говорит, что комбинация *PX имеет тип INT. Это означает, что если PX появляется в контексте *PX, то это эквивалентно переменной типа INT. Фактически синтаксис описания перемен­ной имитирует синтаксис выражений, в которых эта переменная может появляться. Это замечание полезно во всех случаях, связанных со сложными описаниями. Например,

DOUBLE ATOF(), *DP;

говорит, что ATOF() и *DP имеют в выражениях значения типа DOUBLE.

указатель может указывать только на определенный вид объектов.

Указатели могут входить в выражения. Например, если PX указывает на целое X, то *PX может появляться в любом кон­тексте, где может встретиться X. Так оператор

Y = *PX + 1

присваивает Y значение, на 1 большее значения X;

PRINTF("%D\N", *PX)

печатает текущее значение X;

D = SQRT((DOUBLE) *PX)

получает в D квадратный корень из X, причем до передачи фун­кции SQRT значение X преобразуется к типу DOUBLE. В выражениях вида

Y = *PX + 1

унарные операции * и & связаны со своим операндом более крепко, чем арифметические операции, так что такое выражение берет то значение, на которое указывает PX, прибавляет 1 и присваивает результат переменной Y.

Ссылки на указатели могут появляться и в левой части присваиваний. Если PX указывает на X, то

*PX = 0

полагает X равным нулю, а

*PX += 1

увеличивает его на единицу, как и выражение

(*PX)++

Круглые скобки в последнем примере необходимы; если их опус­тить, то поскольку унарные операции, подобные * и ++, выпол­няются справа налево, это выражение увеличит PX, а не ту пе­ременную, на которую он указывает.

И наконец, так как указатели являются переменными, то с ними можно обращаться, как и с остальными переменными. Если PY - другой указатель на переменную типа INT, то PY = PX копирует содержимое PX в PY, в результате чего PY указывает на то же, что и PX.

. Указатели и аргументы функций

Так как в си передача аргументов функциям осуществляет­ся "по значению", вызванная процедура не имеет непосредст­венной возможности изменить переменную из вызывающей прог­раммы. Что же делать, если вам действительно надо изменить аргумент? например, программа сортировки захотела бы поме­нять два нарушающих порядок элемента с помощью функции с именем SWAP. Для этого недостаточно написать

SWAP(A, B);

определив функцию SWAP при этом следующим образом:

SWAP(X, Y) /* WRONG */

INT X, Y;

INT TEMP;

TEMP = X;

X = Y;

Y = TEMP; из-за вызова по значению SWAP не может воздействовать на аргументы A и B в вызывающей функции.

К счастью, все же имеется возможность получить желаемый эффект. Вызывающая программа передает указатели подлежащих изменению значений: SWAP(&A, &B); так как операция & выдает адрес переменной, то &A является указателем на A. В самой SWAP аргументы описываются как ука­затели и доступ к фактическим операндам осуществляется через них.

SWAP(PX, PY) /* INTERCHANGE *PX AND *PY */

INT *PX, *PY;

INT TEMP;

TEMP = *PX;

*PX = *PY;

*PY = TEMP;

Указатели в качестве аргументов обычно используются в функциях, которые должны возвращать более одного значения. (Можно сказать, что SWAP вOзвращает два значения, новые зна­чения ее аргументов). В качестве примера рассмотрим функцию GETINT, которая осуществляет преобразование поступающих в своболном формате данных, разделяя поток символов на целые значения, по одному целому за одно обращение. Функция GETINT должна возвращать либо найденное значение, либо признак кон­ца файла, если входные данные полностью исчерпаны. Эти зна­чения должны возвращаться как отдельные объекты, какое бы значение ни использовалось для EOF, даже если это значение вводимого целого.

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с адержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с задержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с адержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с адержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с адержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с адержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с задержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с адержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с задержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

Практическое задание :

Ввести строки s1 и s2

  1. сравнить строки и вывести ссответствующие ссообщения о результате сравнения

  2. вывести строку s1 по буквам в столбик разным цветом

  3. вывести строку s2 по буквам в стиле "телеграф" ( с адержкой вывода и звуком)

  4. вывести строку s2 по буквам, не используя strlen

  5. определить количество слов в s1

  6. определить количество букв в s2

  7. определить количество букв О в строке s1

  8. определить количество заглавных букв в s2

  9. определить количество четырехбуквенных слов в s1

  10. вывести строку s2 по словам. Каждое слово разным цветом

#include <stdlib.h>

#include <stdio.h>

char *delet(char *s,int pos,int n)

{

char *p1,*p2;

p1=s+pos-1;

p2=p1+n;

while(*p2) *p1++=*p2++;

*p1 = 0;

return(s);

}

void main()

{

char txt[]="Карл у Клары";

printf("\n%s\n",delet(txt,5,3));

}распечатки по теме 1

//буквы в слове

#include <stdio.h>

#include <conio.h>

#include <string.h>

void main()

{

int i,bukwy[256];

char stroka[80],stroka1[80],firstword[30],*p;

clrscr();

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

bukwy[i]=0;

//strcpy(stroka,"карл у клары украл кораллы а клара у карла украла кларнет");

strcpy(stroka,"qwerty werty erty rty ty y");

strcpy(stroka1,stroka);

strcpy(firstword,strtok(stroka1," "));

i=0;

while(firstword[i])

{

for(p=stroka;*p;p++)

{

// printf("%s\n",p);

if (firstword[i] == *p) bukwy[firstword[i]]++;

}

i++;

}

i=0;

while(firstword[i])

{

printf("Буква %c встpечается %d раз\n",firstword[i],bukwy[firstword[i]]);

i++;

}

getch();

}

//количество слов

#include <stdio.h>

#include <conio.h>

#include <string.h>

void main()

{

int count;

char stroka[80],*p;

clrscr();

count=1;

strcpy(stroka,"qwerty werty erty rty ty y");

for(p=stroka;*p;p++)

if(*p==' ')count++;

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

getch();

}

strtok

последовательность вызовов strtok (s1,s2) разбивает строку s1 на лексемы - логические куски, разделенные символами. содержащимися в строке s2. Первый вызов содержит в качестве первого аргумента s1, а последующие вызовы для продолжения обработки той же строки, содержат в качестве первого аргумента NULL. Прикаждом вызове возвращается указатель на текущую лексему. Если при вызове лексем больше нет, возвращается NULL

Пример:

p=strtok(s1," ");

while (p=strtok(NULL," ")) printf("%s\n", p);

Практическая работа : работа со строками (функции,аналоги в pas)

# include<stdio.h>

#include <string.h>

int length (char s1[10])

{ char s3[20];

int n;

n=strlen(s1);

return(n);

}

main()

{char s1[10], s2[10];

int pos;

char b;

gets(s1);

printf("%d",length(s1));

}

# include<stdio.h>

#include <string.h>

int pos (char s1[10], char b)

{ char s3[20];

char *p; int n;

p=strchr(s1,b);

n=p-s1+1;

return(n);

}

main()

{char s1[10], s2[10];

char b;

gets(s1);

scanf("%c",&b);

printf("%d",pos(s1,b));

}

# include<stdio.h>

#include <string.h>

concat (char s1[10],char s2[10])

{ char s3[20];

strcpy(s3,"");

strcat(s3,s1);

strcat(s3,s2);

puts(s3);

return(0);

}

delete (char s1[10],char b)

main()

{char s1[10], s2[10];

char b; int n;

gets(s1);

gets(s2);

concat(s1,s2);

}

# include<stdio.h>

#include <string.h>

copy (char s1[10], int pos,int n)

{ char s3[20];

char *p;

strcpy(s3,"");

//strncpy(s3,s1,pos);

p=s1+pos;

strncat(s3,p,n);

printf("%s\n",s3);

return(0);

}

main()

{char s1[10], s2[10];

int pos,n;

gets(s1);

scanf("%d", &n);

scanf("%d", &pos);

copy(s1,pos,n);

}

# include<stdio.h>

#include <string.h>

insert (char s1[10], char s2[10],int pos)

{ char s3[20];

char *p;

strncpy(s3,s1,pos);

p=s1+pos-1;

strcat(s3,s2);

strcat(s3,p+1);

printf("%s\n",s3);

return(0);

}

main()

{char s1[10], s2[10];

int pos,n;

gets(s1);

gets(s2);

scanf("%d", &pos);

insert(s1,s2,pos);

}

# include<stdio.h>

#include <string.h>

val (int n)

{ char s3[20];

sprintf(s3,"%d",n);

puts(s3);

return(0);

}

main()

{char s1[10], s2[10];

int n;

scanf("%d", &n);

val(n);

}

# include<stdio.h>

# include <stdlib.h>

#include <string.h>

val (int n)

{ char s3[20];

itoa(n,s3,10);

puts(s3);

return(0);

}

main()

{char s1[10], s2[10];

int n;

scanf("%d", &n);

val(n);

}

# include<stdio.h>

# include <stdlib.h>

#include <string.h>

str (char s1[10] )

{

int n;

n=atoi(s1);

printf("%d",n);

return(0);

}

main()

{char s1[10], s2[10];

scanf("%s", s1);

str(s1);

}

Пример:

for (i=0;i<32;i++) printf("%o-%d \n", i,i);

# include <stdio.h>

# include <string.h>

# include <dos.h>

# include <conio.h>

main()

{

clrscr();

char s1[25],s2[25],sd[10],sk[10];

char *p;

int i,dl,dk,nd,nk;

char ch;

printf("введите строку\n");

//gets(s1);

strcpy(s1,"мама мыла раму васечка");

strcpy(s2,s1);

strcpy(sd,"");

strcpy(sk,"");

//вывод строки по буквам в стиле "телеграф"

for(i=0;i<strlen(s1);i++) {delay (100);printf("%c \a",s1[i]);}

//разрезание строки по словам

p=strtok(s1," ");

dl=dk=strlen(p);

nd=nk=0;

while (p=strtok(NULL," "))

{

if (strlen(p)>=dl) {dl=strlen(p);strcpy(sd,p);}

if (strlen(p)<=dk) {dk=strlen(p);strcpy(sk,p);}

printf("%s\n", p);

}

textcolor(5);

cprintf("длинное %d - %s\n", dl,sd);

//textcolor(1);

cprintf("короткое %d - %s\n", dk, sk);

//печать в разных форматах o-8ми ричн; x-6ричн;c-символы;

//for (i=64;i<92;i++) printf("%d-%c \n", i,i);

getchar();

}

Практичсекая работа

  1. Вывести десятичные числа от 1 до 64 в их восьмиричной и шестнадцатиричной записи.

  2. Вывести ASCII коды латинских и русских букв в виде таблицы

  3. Ввести строку и напечатеть е в стиле "телеграф" через знак "-" с задержкой и звуком

  4. Вывести введенную строку по словам разным уветом

  5. Найти самое длинное и самое маленькое слово в строке и вывести их разным цветом

  6. Поменять местами в исходной строке самое длинное и самое короткое слово

Контрольная работа

  1. написать функцию вычисления факториала числа

  2. Ввести 2 строки. Соединить слова обеих строк в третью поочередно

  3. Отсортировать массив а(10)

  4. В матрице найти сумму элементов главной диагонали. Вывести другим цветом

  5. Написать функцию, которая удаляет из строки все буквы а