Нұсқауыштар және адрестерге жасалатын операциялар Си тілінде кезкелген типтегі нысанды операнд ретінде қолдану үшін оның аты немесе нұсқауышы (жанама адрестеу) қолданылады.
Нұсқауыш- әлдебір нысанның, мысалы өзге айнымалының компьютер жадындағы адресін сақтайтын айнымалы. Айнымалыға арнаулы тағайындалған нұсқауыштың көмегімен жедел жадының кезкелген жерінде орналасқан айнымалының мәнін пайдалануға болады.
Нұсқауыш былай жарияланады:
тип *идентификатор;
Мысалы: int *a, *d;
float *f;
Мұнда бүтін айнымалылардың адрестерімен инициалдауға болатын a, d нұсқауыштары және нақты айнымалылардың адрестерімен инициалдауға арналған f нұсқауышы жарияланған.
Нұсқауыштарға екі унарлық & және * операциялары қолданылады. & операциясы операндының «адресін алуды» (яғни нұсқауыштың операндыға тағайындалғандығын) білдіреді. Бұл операция тек айнымалыларға ғана жарамды . * операциясы «нұсқалған адресте орналасқан мән» деген ұғымды білдіреді және қызметін былай атқарады:
- Нұсқауыш типті айнымалының жедел жадыдағы орны анықталады.
- Жадының осы бөлігінен мәлімет алынып, ол нұсқауыштың жариялануында көрсетілген адрес ретінде қабылданады.
- Жадының осы адреспен белгіленген бөлігіне операция жасау мақсатында қатынас жасалады.
1-мысал:
int x, /* int типті айнымалы */
*y; /* int типті мәлімет элементіне арналған нұсқауыш */
y=&x; /* y – x айнымалысының адресі */
*y=1; /* x өрісінің жанама адрестелуі
/* “ нұсқалған адреске 1 жазу, яғни x=1 */
2-мысал : int i, j=8, k=5, *y;
y=&i;
*y=2; /* i=2 */
y=&j; /* нұсқауышты j айнымалысына қайтара тағайындау */
*y+=i; /* j+=i , т.е. j=j+1 -> j=j+2=10 */
y=&k; /* нұсқауышты k айнымалысына қайтара тағайындау */
k+=*y; /* k+=k, k=k+k = 10 */
(*y)++; /* k++, k=k+1 = 10+1 = 11 */
Нұсқауышты пайдаланғанда адрестелетін нысанға атау қоюдың қажеттілігі болмайды.
Нысанға атау қоюды қабыл алмай, нұсқауышты пайдалану Си тілінің «нысан - жады» кескінделуінің икемділігін ассемблер тіліне жақындатады.
Нысанның адресін есептеу кезінде массивтің идентификаторы мен функция нұсқауыш типті константаны атайтынын ескеру керек. Мұндай константаны нұсқауыш типті айнымалыға меншіктеуге болады, бірақ оны түрлендіруге болмайды:
int x[100], *y;
y=x; // константаны айнымалыға меншіктеу ...
x=y; // Қате: сол жақта - нұсқауыш -константа
Нұсқауыш-айнымалыға басқа нұсқауыштың мәнін немесе нұсқауыш типті өрнекті қолдануға болады
int i, *x;
char *y;
x=&i; /* x -> поле объекта int */
y=(char *)x; /* y -> поле объекта char */
y=(char *)&i; /* y -> поле объекта char */
Программаның фрагментін қарастырайық:
int a=5, *p, *p1, *p2;
p=&a; p2=p1=p;
++p1; p2+=2;
printf(“a=%d, p=%d, p=%p, p1=%p, p2=%p.\n”,a,p,p,p1,p2);
Орындалу нәтижесі:
a=5, *p=5, p=FFC8, p1=FFCC, p2=FFD0.
Адрестердің нақты мәндері компьютердің архитектурасы, жедел жадының түрі мен сиымдылығы сияқты себептерге тәуелді.
Тапсырма. Шешуі:
#include #include #include #define n 10
main()
{ int i,l,a[n],c;
int *pa,max;
clrscr();
printf("элементтер : ");
for (i=0; iscanf(“%d\n”,&a[i]);
max=*pa; l=0;
for (i=1; iif(*(pa+i) > max)
{max = *(pa+i); l=i;}
for (i=l; ifor (j=i+1; jif(*(pa+i) < *(pa+j))
{ c=*(pa+i);
(pa+i)=(pa+j);
*(pa+j)=c;
}
for (i=0; iprintf("%d\n", *(pa+i));
}