Σημειώσεις - Εισαγωγή στον Προγραμματισμό

Κεφάλαιο 6: Δυναμική μνήμη, συμβολοσειρές και πολυδιάστατοι πίνακες

Δυναμική δέσμευση μνήμης

Συμβολοσειρές

Πίνακες δεικτών και δείκτες σε δείκτες

Ορίσματα γραμμής εντολών

Πολυδιάστατοι πίνακες

Αρχικοποίηση πινάκων

Δείκτες σε συναρτήσεις

Διαχείριση ορισμάτων στη γραμμή εντολής

/* File: cmdlineargs.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int checkint(char *);
void reverse(char *);

int main(int argc, char *argv[])
{ int sum = 0;   /* Initialize sum of integers in command line */
  while (--argc) {         /* Loop while arguments are present */
    if(checkint(*++argv))           /* Is argument an integer? */
      sum += atoi(*argv); /* Then, sum it into the accumulator */
    else {
      reverse(argv[0]); /* Else, reverse argument and print it */
      printf("Reversed argument: %s\n", argv[0]);
    }
  }                 /* Finally, print sum of integer arguments */
  printf("\nSum of integers given is: %d\n", sum);
  return 0;
}

int checkint(char *s)
{ char *start;
  while(*s == ' ' || *s == '\t') s++;    /* Eat all whitespace */
  if (*s == '-' || *s == '+') s++;             /* Eat one sign */
  start = s;                   /* Mark the begining of numbers */
  while(*s >= '0' && *s <= '9') s++;        /* Eat all numbers */
  return (*s == '\0' && start != s);
             /* Return if there where numbers and nothing else */
}

void reverse(char *s)
{ char c;
  int i, j;
  for (i=0, j=strlen(s)-1 ; i < j ; i++, j--) {
    c = s[i];  /* Visit string from start and end concurrently */
    s[i] = s[j];       /* and exchange characters in symmetric */
    s[j] = c;             /* positions until middle is reached */
  }
}
% gcc -o cmdlineargs cmdlineargs.c
% ./cmdlineargs This is a test
Reversed argument: sihT
Reversed argument: si
Reversed argument: a
Reversed argument: tset

Sum of integers given is: 0
% ./cmdlineargs And 123 another 12
Reversed argument: dnA
Reversed argument: rehtona

Sum of integers given is: 135
% ./cmdlineargs minus five -5 plus twenty two 22
Reversed argument: sunim
Reversed argument: evif
Reversed argument: sulp
Reversed argument: ytnewt
Reversed argument: owt

Sum of integers given is: 17
%

Πρόσθεση πολυψήφιων αριθμών

/* File: addnumbs.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *addnumbs(char *, char *);

int main(int argc, char *argv[])
{ char *sum;
  if (argc != 3) {               /* Run with exactly two arguments */
    printf("Usage: %s <numb1> <numb2>\n", argv[0]); return 1; }
  if ((sum = addnumbs(argv[1], argv[2])) == NULL) { /* Compute sum */
    printf("Sorry, a memory problem occurred\n"); return 1; }
  printf("%s + %s = %s\n", argv[1], argv[2], sum);
  free(sum);                  /* Free memory malloc'ed by addnumbs */
  return 0;
}
char *addnumbs(char *s1, char *s2)
{ int i, j, k, d1, d2, sum, carry;
  char *s3, *tmp, *result;
  i = strlen(s1)-1;     /* Index to last character of first number */
  j = strlen(s2)-1;    /* Index to last character of second number */
  k = (i > j) ? (i+1) : (j+1);   /* Index to last character of sum */
  if ((s3 = malloc((k+2)*sizeof(char))) == NULL)
    return NULL;                     /* Allocate memory for result */
  s3[k+1] = '\0';        /* Proper termination of resulting string */
  carry = 0;                         /* Initial carry for addition */
  for ( ; k >= 0 ; i--, j--, k--) {
                    /* Loop till first digit of result is computed */
    d1 = (i >= 0) ? (s1[i]-'0') : 0;       /* Get i-th digit of s1 */
    d2 = (j >= 0) ? (s2[j]-'0') : 0;       /* Get j-th digit of s2 */
    sum = d1+d2+carry;                           /* Sum two digits */
    carry = sum/10;                                  /* Next carry */
    s3[k] = sum%10+'0';                /* Put k-th digit of result */
  }
  tmp = s3;                   /* Save s3 for freeing it afterwards */
  while (*s3 == '0')               /* Eat leading 0s in the result */
    s3++;
  if(*s3 == '\0')                  /* At least one digit is needed */
    s3--;
  if ((result = malloc((strlen(s3)+1)*sizeof(char))) == NULL)
    return NULL;  /* Allocate memory for result without leading 0s */
  strcpy(result, s3);               /* Copy corrected s3 to result */
  free(tmp);                                   /* Free original s3 */
  return result;
}
% gcc -o addnumbs addnumbs.c
% ./addnumbs 12345 67890
12345 + 67890 = 80235
% ./addnumbs 125 88275346771923625166
125 + 88275346771923625166 = 88275346771923625291
% ./addnumbs 999999999999999 999999
999999999999999 + 999999 = 1000000000999998
% ./addnumbs 0000000000023 00000057
0000000000023 + 00000057 = 80
% ./addnumbs 3252352362364362362366 3262363262362363622
3252352362364362362366 + 3262363262362363622 = 3255614725626724725988
% ./addnumbs 0000000 0000000000
0000000 + 0000000000 = 0
%
  1. Στον τυπικό ορισμό της malloc, ο τύπος του size είναι size_t, αλλά αυτό πρακτικά είναι unsigned int. ↩

  2. Επισήμως ο τύπος επιστροφής της συνάρτησης είναι size_t, αλλά αυτός, πρακτικά, είναι unsigned int. ↩

  3. Πώς θα υλοποιούσαμε τις strlen και strcat; ↩

  4. 15 ↩

  5. Μόνο, προσοχή και εδώ, το i πρέπει να κυμαίνεται, στο παράδειγμά μας, από 0 έως 9 και το j από 0 έως 7. ↩

  6. Εδώ το funvar είναι το όνομα συγκεκριμένης συνάρτησης, όχι δείκτης σε συνάρτηση, που επιστρέφει δείκτη σε ακέραιο (int *) και έχει μία τυπική παράμετρο τύπου char *. ↩

Κατεβάστε το κεφάλαιο: PDF · Markdown