Jadvallar va markerlar C ++

Nimaga marker o'zgaruvchiga tayinlangan bo'lishi mumkin, ammo qator o'zgaruvchisi bajarilmaydi? Boshqa so'zlar bilan aytganda, 4-bayonnomaning noqonuniyligi kod snippetasidan past bo'lishi kerakmi?

1.int a[10];
2.int *p; 
3.p=a;     //legal operation
4.a=p;   //Illegal operation
0
a = p nima qilishini kutmoqdasiz?
qo'shib qo'ydi muallif rustyx, manba
Men sizlarga C ++ ni ikki xat bilan o'rgatishimiz mumkin deb o'ylamayman. Siz C ++ haqida butun kitobni (va, ehtimol, ko'proq) o'qiyotganda, albatta, kunlarni o'tkazishingiz kerak
qo'shib qo'ydi muallif Basile Starynkevitch, manba
@David Bu to'g'ri emas va juda sodda. const * dan ishlab chiqarish ham ishlamaydi. O'tkazish bitta usulda amalga oshirilishi mumkin, shuning uchun parchalanish . Bu bir xil emas.
qo'shib qo'ydi muallif luk32, manba
@DavidChoweller Men (umid qilamanki) buni tushuntirib beradigan javob yozdim.
qo'shib qo'ydi muallif luk32, manba
a o'zgaruvchi emas.
qo'shib qo'ydi muallif Ray Tayek, manba
@Hurkyl a, albatta, int * kabi o'zgaruvchi emas, balki int * const.you kabi o'zgartira olmaydi. faqat elementlarni o'zgartirishi mumkin.
qo'shib qo'ydi muallif Ray Tayek, manba
@Ray: a = < int [10] turidagi o'zgaruvchidir.
qo'shib qo'ydi muallif Hurkyl, manba
Jadvallar doimiy ko'rsatkichlar bo'lgani uchun.
qo'shib qo'ydi muallif David Choweller, manba
@ luk32 men tushundim. Siz batafsilroq gapira olasizmi?
qo'shib qo'ydi muallif David Choweller, manba
Rahmat, @ luk32. Bu juda foydali.
qo'shib qo'ydi muallif David Choweller, manba
qo'shib qo'ydi muallif Liam Gray, manba
@David Arrays doimiy ko'rsatkichlar emas. Ushbu havolasini ko'rib chiqing
qo'shib qo'ydi muallif Kaushal, manba

6 javoblar

Sizning so'rovingiz 3. ga parchalanish deb nom berishining sababi bor. O'tkazish bitta usuldir, chunki ko'rsatkichlar va qatorlar bir xil emas.

Chiziq ko'rsatgichga aylantirilganda, uning hajmi haqida ma'lumot yo'qoladi. Uni qayta tiklash mumkin emas, shuning uchun teskari konvertatsiya to'liq bajarilmaydi. Ie. int [WHAT] ga qaytib kerakmi?

Mening boshimdagi ikkita asosiy farq:

  1. Agar ni tekshirsangiz, uning hajmi haqida ma'lumotni o'z ichiga oladi, ko'rsatgich ko'rsatmaydi. sizeof (a) , sizeof (p) va sizeof (* p) ni tekshiring.

  2. a ba'zi elementlarning mavjudligini kafolatlaydi (c ++ nol o'lchovli qatorlarni taqiqlaydi).

Lekin p muayyan kontekstlarda decltype (p) turidagi muxtor bo'lmagan qatorini davolash uchun mantiqan to'g'ri keladi. Xususan elementlarning joylashtirilishi ma'lum bir elementni xotiraga joylashtirishni hisoblash oson. Pointer arifmetikasi bilan bir xil. Shuning uchun notation bir xil, masalan. har ikkala kod

[6] va a [6] . Shunday qilib, massivlarni qabul qiluvchi funktsiyalar o'zboshimchalikli o'lchamdagi massivlarni qabul qilishi mumkin.

Lekin bu bir xil emas.

Boshqa bir o'lcham qo'shilganda farqlar aniq ko'rinadi. (Kattalik kattaligi) qatori elementni aritmetik joylashtirishni yuqoridagidek hisoblashingiz mumkin, u xotirada ulashgan va siz har bir "qator" hajmini bilasiz.

Lekin int ** uchun chegaralarni bilmagan ikki darajaga ega bo'lasiz. Ie. siz arifmetik hisoblash elementini int ** elementidagi holatini 1-darajali hal qilishingiz kerak emas va keyin hisoblashni ishlata olmaysiz. Har bir "qator" turli uzunlikka ega bo'lishi mumkin.

Shuning uchun siz quyidagi xatolarga yo'l qo'yasiz:

main.cpp: 11: 8: xatolik: 'int **' ni '1 (1) dan' void f (int () 'ga o'zgartirish uchun int () ga [5] 5]) "

1-o'lchovni ko'rsatgichga biriktirib qo'yganligini unutmang, lekin siz qatorni faqat bitta o'lchamda (konvensiya bo'yicha - 1-chi) ochishingiz mumkin!

http://coliru.stacked-crooked.com/a/5063a9d19739278a ga qarang.

void f(int a[3][5]){}

int main() {
    int ** p = new int*;
    int b[4][5];//works because 1st dimension can decay to pointer (unbound array)
    int c[3][6];//doesn't work because 2st dimension cannot decay to pointer
    f(p); f(b); f(c);
    return 0;
}
2
qo'shib qo'ydi

Using p=a you are assigning the base address of an array to a pointer so it is legal or you can write p=&a[0]; but a=p doesn't make any sense it is not a single location.

0
qo'shib qo'ydi
int * p

Texnik jihatdan bu bitta tamsaytning manzili yoki o'lchamini e'tiborsiz qoldiradigan qatorning manzili (MAYBE 10dan ortiq)

int a[10];

Bu ma'lum bir o'lchamdagi ob'ekt

Shuning uchun siz aniq bir narsaga manzilni belgilashingiz mumkin emas.

0
qo'shib qo'ydi

Mozorlar qanday ishlashi haqida qiziqarli narsalar mavjud, ammo asosiy narsalar quyidagilardir:

  • Bir qator - ob'ektlar to'plami
  • Pointer ob'ektga ishora qiladi

Jadvallar qanday aniqlanganligi haqidagi tafsilotlarga asoslanib, qatorni dastlabki holatga aylantirish uchun bir qator ma'nolarni beradi, bu qatorni dastlabki elementga markerni aylantirib (va ushbu konversiyaning aniq bajarilishini talab qiladigan til) ikkinchidan birinchisiga aylantirish juda mantiqiy.

0
qo'shib qo'ydi

Asosan, ular [seriallar va ko'rsatgichlar] turli xil narsalardir. Pointer qatorning birinchi elementiga ishora qilishi mumkin va ma'lum hollarda qatorni ko'rsatgichga aylantirishi mumkin (siz C ++ tilining standartiga murojaat qilishingiz mumkin 4.4.2), lekin aksincha emas.

Shuningdek, bu javobiga qarang.

0
qo'shib qo'ydi

Agar qatorni xotirada bir nechta joylarni saqlaydigan ko'rsatgich sifatida ko'rib olsangiz bo'ladi. a - bu qatorni ko'rsatadigan ko'rsatkichdir. Agar siz p = a dan foydalansangiz, siz pointer p ga ko'rsatadigan markerni tayinlaysiz. lekin bir nechta ob'ekt va P bir joyga ishora qilgani uchun a = p dan foydalana olmaysiz

0
qo'shib qo'ydi