Məzmuna keç
Educora
Orta18 dəq5 / 8

Massivlər və sətirlər

Eyni tipli çoxlu qiyməti massivdə saxla, massivləri funksiyalara ötür, sətirlərin '\0' ilə bitən simvol massivləri olduğunu öyrən və string.h funksiyalarından təhlükəsiz istifadə et.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Massiv elan etmək, ona ilkin qiymətlər vermək və elementlərini dövrlə emal etmək
  • Massivi uzunluğu ilə birlikdə funksiyaya ötürmək
  • Sətrin sonundakı '\0' simvolunun rolunu izah etmək
  • strlen, strcpy, strcat və strcmp funksiyalarını bufer daşmasına yol vermədən işlətmək

Sinifdə 25 şagird var və hər birinin qiymətini saxlamaq lazımdır. 25 ayrı dəyişən — mark1, mark2, ..., mark25 yaratmaq həm yorucu, həm də əlverişsizdir: onları dövrlə gəzmək mümkün deyil. Bunun üçün massiv var — eyni tipli qiymətlərin yaddaşda yan-yana düzülmüş sırası. C-də mətn də massivdir, sadəcə simvollardan ibarət massiv.

Massivlər

Massiv elan edərkən tipi, adı və kvadrat mötərizədə elementlərin sayını yazırıq: int marks[5];. Elementlərə indekslə müraciət olunur və indekslər 0-dan başlayır: ilk element marks[0], sonuncu isə marks[4]-dür. Başlanğıc qiymətləri fiqurlu mötərizədə vermək olar; az qiymət verilsə, qalan elementlər 0 olur. Məsələn, int counts[10] = {0}; bütün elementləri sıfırlayır.

C
#include <stdio.h>

int main(void) {
    int marks[5] = {5, 4, 3, 5, 4};
    int n = sizeof(marks) / sizeof(marks[0]);
    int sum = 0;
    int best = marks[0];
    for (int i = 0; i < n; i++) {
        sum += marks[i];
        if (marks[i] > best) {
            best = marks[i];
        }
    }
    printf("Count: %d\n", n);
    printf("First: %d, last: %d\n", marks[0], marks[n - 1]);
    printf("Average: %.2f\n", (double) sum / n);
    printf("Best: %d\n", best);
    return 0;
}
Gözlənilən nəticə
Count: 5
First: 5, last: 4
Average: 4.20
Best: 5

Massivi funksiyaya ötürəndə funksiya onun uzunluğunu bilmir, ona görə uzunluq ayrıca parametr kimi verilir. Bir fərq də var: adi dəyişəndən fərqli olaraq massiv surətlənmir — funksiya orijinal elementlərlə işləyir və onları dəyişə bilər. Bunun səbəbini növbəti dərsdə, göstəricilərlə birlikdə görəcəksən. Massivi dəyişməyəcək funksiyada parametrə const yazmaq yaxşı vərdişdir.

C
#include <stdio.h>

int find(const int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        if (arr[i] == target) {
            return i;
        }
    }
    return -1;
}

void double_all(int arr[], int n) {
    for (int i = 0; i < n; i++) {
        arr[i] *= 2;
    }
}

int main(void) {
    int prices[4] = {3, 7, 1, 10};
    printf("7 is at index %d\n", find(prices, 4, 7));
    printf("5 is at index %d\n", find(prices, 4, 5));
    double_all(prices, 4);
    printf("After: %d %d %d %d\n", prices[0], prices[1], prices[2], prices[3]);
    return 0;
}
Gözlənilən nəticə
7 is at index 1
5 is at index -1
After: 6 14 2 20
find tapılmayan qiymət üçün mövcud olmayan indeks olan −1 qaytarır. double_all isə orijinal massivi dəyişdi.
İnteraktiv
Simulyasiya yüklənir…
find funksiyası məhz belə işləyir: elementləri 0-cı indeksdən başlayaraq bir-bir yoxlayır.

Sətirlər: '\0' ilə bitən simvol massivləri

C-də ayrıca sətir tipi yoxdur. Sətir — sonunda xüsusi null-simvol '\0' olan char massividir. printf, strlen kimi funksiyalar sətrin harada bitdiyini məhz bu simvoldan bilir. char word[] = "milk"; yazanda kompilyator 4 hərf və '\0' üçün 5 baytlıq massiv yaradır.

İndeks01234
word[i]'m''i''l''k''\0'
"milk" sətri yaddaşda belə görünür: 4 hərf və sonda null-simvol.
C
#include <stdio.h>
#include <string.h>

int main(void) {
    char word[] = "milk";
    printf("Word: %s\n", word);
    printf("strlen: %zu\n", strlen(word));
    printf("sizeof: %zu\n", sizeof(word));
    printf("First letter: %c\n", word[0]);
    word[0] = 's';
    printf("Changed: %s\n", word);
    return 0;
}
Gözlənilən nəticə
Word: milk
strlen: 4
sizeof: 5
First letter: m
Changed: silk
strlen '\0'-a qədər olan simvolları sayır, sizeof isə massivin bütün baytlarını.

string.h funksiyaları

Massivi başqa massivə = ilə mənimsətmək və sətirləri == ilə müqayisə etmək olmur. Bunun üçün string.h başlığındakı funksiyalar işlədilir: strcpy(dest, src) sətri köçürür, strcat(dest, src) sona əlavə edir, strcmp(a, b) isə müqayisə edir. strcmp sətirlər eynidirsə 0, a əlifba sırasında əvvəl gəlirsə mənfi, sonra gəlirsə müsbət ədəd qaytarır.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    char first[20] = "Baku";
    char second[20];
    strcpy(second, first);
    printf("Copy: %s\n", second);
    strcat(second, " city");
    printf("Joined: %s (%zu chars)\n", second, strlen(second));
    if (strcmp(first, "Baku") == 0) {
        printf("Equal\n");
    }
    if (strcmp("apple", "banana") < 0) {
        printf("apple comes first\n");
    }
    return 0;
}
Gözlənilən nəticə
Copy: Baku
Joined: Baku city (9 chars)
Equal
apple comes first

Əsas fikirlər

  • Massiv eyni tipli qiymətləri yan-yana saxlayır; indekslər 0-dan n - 1-ə qədərdir.
  • C massivin sərhədlərini yoxlamır — sərhəddən kənara çıxmaq ciddi səhvdir.
  • Funksiyaya massivlə yanaşı onun uzunluğu da ötürülür; funksiya orijinal elementləri dəyişə bilər.
  • Sətir '\0' ilə bitən char massividir: "milk" 5 bayt tutur, strlen isə 4 verir.
  • Sətirləri strcpy ilə köçür, strcmp ilə müqayisə et və hədəfin ölçüsünü həmişə yoxla.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
int a[10]; massivinin son elementinin indeksi neçədir?