Указатели и масиви - 1
Chapter 5 - Pointers and Arrays
5.1 Pointers and Addresses
5.2 Pointers and Function Arguments
5.3 Pointers and Arrays
5.4 Address Arithmetic
5.5 Character Pointers and Functions
5.6 Pointer Arrays; Pointers to Pointers
Указатели и адреси
Пример:
int x = 1, y = 2, z[10];
int *ip; /* ip is a pointer to int */
ip = &x; /* ip now points to x */
y = *ip; /* y is now 1 */
*ip = 0; /* x is now 0 */
ip = &z[0]; /* ip now points to
z[0] */
Указатели и аргументи на функции
Пример:
Размяна на стойности.
void swap(int x, int y) /* WRONG */
{
int temp;
temp = x;
x = y;
y = temp;
}
swap(a, b);
void swap(int *px, int *py) /* interchange *px
and *py */
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}
swap(&a, &b);
Указатели и масиви
Името на масив е константен
указател.
Пример:
int a[3] = {10, 20, 30};
int *pa = a;
/* отпечатва 3 пъти стойността на a[0] */
printf("%d %d %d \n", a[0], pa[0],
*pa);
/* отпечатва 4 пъти стойността на a[1] */
printf("%d %d %d %d \n", a[1],
pa[1], *(pa+1), (pa+1)[0]);
Адрес |
pa или a |
pa+1 или a+1 |
pa+2 или a+2 |
Стойност |
10 |
20 |
30 |
Индекс |
0 |
1 |
2 |
Достъп 1 |
a[0] |
a[1] |
a[2] |
Достъп 2 |
*pa |
*(pa+1) |
*(pa+2) |
Достъп 3 |
pa[0] |
(pa+1)[0] |
(pa+1)[1] |
Достъп 4 |
*a |
*(a+1) |
*(a+2) |
Пример:
Намиране дължината на низ
/* strlen: return length of string s */
int strlen(char *s)
{
int n;
for (n = 0; *s != '\0', s++)
n++;
return n;
}
strlen("hello, world"); /* string constant */
strlen(array);
/* char
array[100]; */
strlen(ptr);
/* char *ptr; */
Адресна аритметика
указател + int
указател - int
++указател, указател++, --указател, указател--
Сравняване на указатели в границите на масив
указател - указател (сойността на операцията е int)
/* strlen: return length of string s */
int strlen(char *s)
{
char *p = s;
while (*p != '\0')
p++;
return p - s;
}
Знакови указатели и функции
Разлика между масив и указател.
char amessage[] = "now is the time"; /* an array
*/
char *pmessage = "now is the time"; a pointer */
Пример:
Копиране на един низ в друг.
/* strcpy: copy t to s; array subscript version
*/
void strcpy(char *s, char *t)
{
int i;
i = 0;
while ((s[i] = t[i]) != '\0')
i++;
}
/* strcpy: copy t to s; pointer version */
void strcpy(char *s, char *t)
{
int i;
i = 0;
while ((*s = *t) != '\0') {
s++;
t++;
}
}
/* strcpy: copy t to s; pointer version 2 */
void strcpy(char *s, char *t)
{
while ((*s++ = *t++) != '\0')
;
}
/* strcpy: copy t to s; pointer version 3 */
void strcpy(char *s, char *t)
{
while (*s++ = *t++)
;
}
Масиви от указатели, указатели към указатели
Масив от указатели към низове.
Пример:
char *arr[100];
char a[] = "Hello!";
arr[0] = a;
printf("%s %c %c \n", a, *arr[0], **arr);
Указатели към тип указател.
Пример:
int
k = 1;
int *pk = &k;
int **pkk = &pk;
int ***pkkk = &pkk;
printf("%d %d \%d %d \n", k, *pk,
**pkk, ***pkkk);
Пример:
Прочитат се редове с текст, сортират се и се отпечатват (при направа
на речник).
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* max #lines to be sorted
*/
char *lineptr[MAXLINES]; /* pointers to text lines */
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort(char *lineptr[], int left, int
right);
/* sort input lines */
int main()
{
int nlines; /* number of input lines
read */
if ((nlines =
readlines(lineptr, MAXLINES)) >= 0) {
qsort(lineptr, 0,
nlines-1);
writelines(lineptr,
nlines);
return 0;
}
else {
printf("error:
input too big to sort\n");
return 1;
}
}
#define MAXLEN 1000 /* max length of any input
line */
int getline(char *, int);
char *alloc(int);
/* readlines: read input lines */
int readlines(char *lineptr[], int maxlines)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN))
> 0)
if (nlines >=
maxlines || p = alloc(len) == NULL)
return
-1;
else {
line[len-1] = '\0'; /* delete newline */
strcpy(p, line);
lineptr[nlines++] = p;
}
return nlines;
}
/* writelines: write output lines */
void writelines(char *lineptr[], int nlines)
{
int i;
for (i = 0; i < nlines; i++)
printf("%s\n",
lineptr[i]);
}
/* writelines: write output lines */
void writelines(char *lineptr[], int nlines)
{
while (nlines-- > 0)
printf("%s\n",
*lineptr++);
}
/* qsort: sort v[left]...v[right] into
increasing order */
qsort(char *v[], int left, int right)
{
int i, last;
void swap(char *v[], int i, int j);
if (left >= right)
/* do nothing if array
contains */
return;
/* fewer than
two elements */
swap(v, left, (left + right)/2);
last = left;
for (i = left+1; i <= right; i++)
if (strcmp(v[i], v[left])
< 0)
swap(v, ++last, i);
swap(v, left, last);
qsort(v, left, last-1);
qsort(v, last+1, right);
}
/* swap: interchange v[i] and v[j] */
void swap(char *v[], int i, int j)
{
char *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}