Указатели и масиви - 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;
}