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

Chapter 5 - Pointers and Arrays
5.7 Multi-dimensional Arrays
5.8 Initialization of Pointer Arrays
5.9 Pointers vs. Multi-dimensional Arrays
5.10 Command-line Arguments
5.11 Pointers to Functions
5.12 Complicated Declarations

Многомерни масиви

Пример:
Високосна година

static char daytab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

};

/* day_of_year: set day of year from month & day */
int day_of_year(int year, int month, int day)

{
    int i, leap;
    leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
    for (i = 1; i < month; i++)

        day += daytab[leap][i];
    return day;

}

/* month_day: set month, day from day of year */
void month_day(int year, int yearday, int *pmonth, int *pday)
{

    int i, leap;
    leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
    for (i = 1; yearday > daytab[leap][i]; i++)

        yearday -= daytab[leap][i];
    *pmonth = i;

    *pday = yearday;

}



Инициализация на масиви от указатели

/* month_name: return name of n-th month */
char *month_name(int n)
{    
    static char *name[] = {

        "Illegal month",
        "January", "February", "March", "April", "May", "June",
        "July", "August", "September", "October", "November", "December"
    };
    return (n < 1 || n > 12) ? name[0] : name[n];
}


Указатели срещу многомерни масиви

 int a[10][20];
 int *b[10];


(картинка)

Аргументи от командния ред

Пример:
Отпечатване на аргументи от командния ред

#include <stdio.h>

/* echo command-line arguments; 1st version */
int main(int argc, char *argv[])

{
    int i;
    for (i = 1; i < argc; i++)
        printf("%s%s", argv[i], (i < argc-1) ? " " : "");
    printf("\n");
    return 0;
}



#include <stdio.h>

/* echo command-line arguments; 2nd version */
main(int argc, char *argv[])

{
    while (--argc > 0)
        printf("%s%s", *++argv, (argc > 1) ? " " : "");
    printf("\n");
    return 0;
}


Указатели към функции

Пример:
Програма, соято сортира низове и числа, в зависимост от входен параметър.

#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(void *lineptr[], int left, int right, int (*comp)(void *, void *));

int numcmp(char *, char *);

/* sort input lines */
int main(int argc, char *argv[])
{

    int nlines;         /* number of input lines read */
    int numeric = 0;     /* 1 if numeric sort */

    if (argc > 1 && strcmp(argv[1], "-n") == 0)
        numeric = 1;

    if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
        qsort((void**) lineptr, 0, nlines-1,

            (int (*)(void*,void*))(numeric ? numcmp : strcmp));
        writelines(lineptr, nlines);

        return 0;
    }
    else {

        printf("input too big to sort\n");
        return 1;

    }
}



/* qsort: sort v[left]...v[right] into increasing order */
void qsort(void *v[], int left, int right,

            int (*comp)(void *, void *))
{
    int i, last;

    void swap(void *v[], int, int);

    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 ((*comp)(v[i],
v[left]) < 0)
            swap(v, ++last, i);
     
    swap(v, left, last);
    qsort(v, left, last-1, comp);
    qsort(v, last+1, right, comp);

}



#include <stdlib.h>

/* numcmp: compare s1 and s2 numerically */
int numcmp(char *s1, char *s2)

{
       double v1, v2;
       v1 = atof(s1);
       v2 = atof(s2);
       if (v1 < v2)
           return -1;
       else if (v1 > v2)
           return 1;
       else
           return 0;
}
ebook - The C Programming Language Ritchie & kernighan -.doc

void swap(void *v[], int i, int j;)
{

    void *temp;
    temp = v[i];
    v[i] = v[j];
    v[j] = temp;
}


Сложни декларации

Задачи:
1. Дадена е матрица nxm от цели числа. Да се намерят сумите на рeдовете и стълбовете и да се оформи подходяща таблица.
вход:
2 3
10 11 12
13 14 15

изход:
10 11 12 33
13 14 15 42
23 25 27


2. Да се напише програма, която да шифрира и дешифрира текст с шифъра на Цезар, като ключът се задава от командния ред.
>code 3 < a.txt > b.txt

3. Да се напише функция, която сравнява два низа.

4. Да се напише програма за намиране на максимален елемент на масив, за произволни елементи на мсива, за които е дефинирана функция за сравнение.
int gmax(void *arr,  int size,  int (*comp)(void *, void *));