C Programlama diliyle şamatalar

Başlatan z, 23 Ekim 2011, 15:32:04

Gökhan BEKEN

#570
Dizi kaç eleman, mesela 9 eleman. 10. elemana 0 değerini verin.
örn:
deneme[]="123456789";
deneme[10]=0;
Özel mesaj okumuyorum, lütfen göndermeyin.

kantirici

char *a  ile pointer tanımlarısınız. a içerisine değişken uzunlukta veri yükleyebilirsiniz. char a[5] veya char a[]={1,2,3,4,5} şeklinde tanımlarsanız 5 elemanlı bir dizi tanımlarsınız ve daha fazla yükleme yapamazsınız.

Siz deneme123 yüklmeiş fakat 20 adet veri çekmeye çalışmışsınız.Bu durumda bellekte başka bir değişkene karşılık yada boş rastgele değerler çekiyorsunuz. uzunluğa göre işlem yaparsanız sorun hallolur.

Klein

İşaretçi (pointer) bir veri alanı değildir. istediğimiz kadar veri yükleyemeyiz.
işaretçiler veri alanlarının adreslerini bulundururlar.

everygelem

Pointer mantığını kavramaya çalışıyorum fakat burada neden char[] dizisi bittikten sonrada rastgele değerler gelebilirken char* pointerin gösterdiği değeri artımama rağmen herhangi bir değer gelmediği. neticede ikiside pointer (ilk byte in bellektekiş adresi) ? Bunu compiler mı engelliyor? çokta aklıma takılmadı ama merak ediyorum hala. cevap veren arkadaşlara da teşekkürker.

Klein

Normalde pointer'de olsa dizi de olsa işaretçiyi artırdığınızda gösterdiği yerde ne varsa gelmesi gerekir. Bu durum bir tesadüf olabilr.

char *p = "xxxxxxx"
char *t = "yyyyyyy"

şeklinde p işaretçisinin hemen ardına başka bir dizi yerleştirin. p işarteçisi taşınca t'nin içeriğinden bir şeyler geliyor mu bir bakın.

everygelem

İşte taşmasını beklerken taşma olmamasını anlayamadım. Dediğinizi yaptım yani. gcc varsayılan derleme acaba pointer bellek taşmasını engelliyormu?

Klein

bir de şöyle yapın. Muhtemelen herhangi bir snırlama olmayacak. 

char a[] = "xxxxxxx";
char *p = a;


fatih6761

@Klein hocam bu arada iyileştirmelerin/optimizasyonların açık olmaması da önemli...

everygelem

Alıntı yapılan: Klein - 03 Eylül 2013, 12:19:43
bir de şöyle yapın. Muhtemelen herhangi bir snırlama olmayacak. 

char a[] = "xxxxxxx";
char *p = a;
Evet bu şekilde taşma oluyor. Ama buda zaten o dizi nin kendisi oluyor.
birde şöyle yazayım dedim ve dizi tanımlamasıyla pointerin (galiba) bellekte oldukça farklı yerlerde olduklarını gördüm.pointerden içindeki değerden sonra gelen veriler aslında tanımlanan yerde değilde printf() ile ekrana yazılan alanla aynı yerde.Bu nedemek bilmiyorum ama %p ile gelen bellek adresleri farklı yerdeler.Bu yüzden taşma olsada gösterecek bir değeri olmuyor döngünün. C de yeniyim bu yüzden oldukça kurcalayarak, deneme-yanımayla öğrenmeye çalışıyorum.

#include "stdio.h"
int main()
{ 
char a[]="test";
char *p="test";
int i=0;
for(i=0;i<100;i++){
printf("Döngü adet:%i AdresPointer:%p  DegerPointer:%c   AdresDizi:%p   DegerDizi:%c\n",i,&(p[i]),p[i],&(a[i]),a[i]);
}
return 0;
}
Ekran çıktısı :
#gcc -o d d.c

Döngü adet:0 AdresPointer:0x80485a0  DegerPointer:t   AdresDizi:0xbfee80d7   DegerDizi:t
Döngü adet:1 AdresPointer:0x80485a1  DegerPointer:e   AdresDizi:0xbfee80d8   DegerDizi:e
Döngü adet:2 AdresPointer:0x80485a2  DegerPointer:s   AdresDizi:0xbfee80d9   DegerDizi:s
Döngü adet:3 AdresPointer:0x80485a3  DegerPointer:t   AdresDizi:0xbfee80da   DegerDizi:t
Döngü adet:4 AdresPointer:0x80485a4  DegerPointer:   AdresDizi:0xbfee80db   DegerDizi:
Döngü adet:5 AdresPointer:0x80485a5  DegerPointer:   AdresDizi:0xbfee80dc   DegerDizi:
Döngü adet:6 AdresPointer:0x80485a6  DegerPointer:   AdresDizi:0xbfee80dd   DegerDizi:J
Döngü adet:7 AdresPointer:0x80485a7  DegerPointer:   AdresDizi:0xbfee80de   DegerDizi:
Döngü adet:8 AdresPointer:0x80485a8  DegerPointer:D   AdresDizi:0xbfee80df   DegerDizi:
Döngü adet:9 AdresPointer:0x80485a9  DegerPointer:�   AdresDizi:0xbfee80e0   DegerDizi:5
Döngü adet:10 AdresPointer:0x80485aa  DegerPointer:�   AdresDizi:0xbfee80e1   DegerDizi:
Döngü adet:11 AdresPointer:0x80485ab  DegerPointer:n   AdresDizi:0xbfee80e2   DegerDizi:z
Döngü adet:12 AdresPointer:0x80485ac  DegerPointer:g   AdresDizi:0xbfee80e3   DegerDizi:
Döngü adet:13 AdresPointer:0x80485ad  DegerPointer:�   AdresDizi:0xbfee80e4   DegerDizi:P
Döngü adet:14 AdresPointer:0x80485ae  DegerPointer:�   AdresDizi:0xbfee80e5   DegerDizi:J
Döngü adet:15 AdresPointer:0x80485af  DegerPointer:    AdresDizi:0xbfee80e6   DegerDizi:
Döngü adet:16 AdresPointer:0x80485b0  DegerPointer:a   AdresDizi:0xbfee80e7   DegerDizi:
Döngü adet:17 AdresPointer:0x80485b1  DegerPointer:d   AdresDizi:0xbfee80e8   DegerDizi:
Döngü adet:18 AdresPointer:0x80485b2  DegerPointer:e   AdresDizi:0xbfee80e9   DegerDizi:�
Döngü adet:19 AdresPointer:0x80485b3  DegerPointer:t   AdresDizi:0xbfee80ea   DegerDizi:�
Döngü adet:20 AdresPointer:0x80485b4  DegerPointer::   AdresDizi:0xbfee80eb   DegerDizi:
Döngü adet:21 AdresPointer:0x80485b5  DegerPointer:%   AdresDizi:0xbfee80ec   DegerDizi:
Döngü adet:22 AdresPointer:0x80485b6  DegerPointer:i   AdresDizi:0xbfee80ed   DegerDizi:
Döngü adet:23 AdresPointer:0x80485b7  DegerPointer:    AdresDizi:0xbfee80ee   DegerDizi:
Döngü adet:24 AdresPointer:0x80485b8  DegerPointer:A   AdresDizi:0xbfee80ef   DegerDizi:
Döngü adet:25 AdresPointer:0x80485b9  DegerPointer:d   AdresDizi:0xbfee80f0   DegerDizi:
Döngü adet:26 AdresPointer:0x80485ba  DegerPointer:r   AdresDizi:0xbfee80f1   DegerDizi:�
Döngü adet:27 AdresPointer:0x80485bb  DegerPointer:e   AdresDizi:0xbfee80f2   DegerDizi:
Döngü adet:28 AdresPointer:0x80485bc  DegerPointer:s   AdresDizi:0xbfee80f3   DegerDizi:
Döngü adet:29 AdresPointer:0x80485bd  DegerPointer:P   AdresDizi:0xbfee80f4   DegerDizi:
Döngü adet:30 AdresPointer:0x80485be  DegerPointer:o   AdresDizi:0xbfee80f5   DegerDizi:
Döngü adet:31 AdresPointer:0x80485bf  DegerPointer:i   AdresDizi:0xbfee80f6   DegerDizi:
Döngü adet:32 AdresPointer:0x80485c0  DegerPointer:n   AdresDizi:0xbfee80f7   DegerDizi:
Döngü adet:33 AdresPointer:0x80485c1  DegerPointer:t   AdresDizi:0xbfee80f8   DegerDizi:x
Döngü adet:34 AdresPointer:0x80485c2  DegerPointer:e   AdresDizi:0xbfee80f9   DegerDizi:�
Döngü adet:35 AdresPointer:0x80485c3  DegerPointer:r   AdresDizi:0xbfee80fa   DegerDizi:
Döngü adet:36 AdresPointer:0x80485c4  DegerPointer::   AdresDizi:0xbfee80fb   DegerDizi:�
Döngü adet:37 AdresPointer:0x80485c5  DegerPointer:%   AdresDizi:0xbfee80fc   DegerDizi:7
Döngü adet:38 AdresPointer:0x80485c6  DegerPointer:p   AdresDizi:0xbfee80fd   DegerDizi:N
Döngü adet:39 AdresPointer:0x80485c7  DegerPointer:    AdresDizi:0xbfee80fe   DegerDizi:y
Döngü adet:40 AdresPointer:0x80485c8  DegerPointer:    AdresDizi:0xbfee80ff   DegerDizi:
Döngü adet:41 AdresPointer:0x80485c9  DegerPointer:D   AdresDizi:0xbfee8100   DegerDizi:
Döngü adet:42 AdresPointer:0x80485ca  DegerPointer:e   AdresDizi:0xbfee8101   DegerDizi:
Döngü adet:43 AdresPointer:0x80485cb  DegerPointer:g   AdresDizi:0xbfee8102   DegerDizi:
Döngü adet:44 AdresPointer:0x80485cc  DegerPointer:e   AdresDizi:0xbfee8103   DegerDizi:
Döngü adet:45 AdresPointer:0x80485cd  DegerPointer:r   AdresDizi:0xbfee8104   DegerDizi:�
Döngü adet:46 AdresPointer:0x80485ce  DegerPointer:P   AdresDizi:0xbfee8105   DegerDizi:�
Döngü adet:47 AdresPointer:0x80485cf  DegerPointer:o   AdresDizi:0xbfee8106   DegerDizi:
Döngü adet:48 AdresPointer:0x80485d0  DegerPointer:i   AdresDizi:0xbfee8107   DegerDizi:�
Döngü adet:49 AdresPointer:0x80485d1  DegerPointer:n   AdresDizi:0xbfee8108   DegerDizi:�
Döngü adet:50 AdresPointer:0x80485d2  DegerPointer:t   AdresDizi:0xbfee8109   DegerDizi:�
Döngü adet:51 AdresPointer:0x80485d3  DegerPointer:e   AdresDizi:0xbfee810a   DegerDizi:
Döngü adet:52 AdresPointer:0x80485d4  DegerPointer:r   AdresDizi:0xbfee810b   DegerDizi:�
Döngü adet:53 AdresPointer:0x80485d5  DegerPointer::   AdresDizi:0xbfee810c   DegerDizi:
Döngü adet:54 AdresPointer:0x80485d6  DegerPointer:%   AdresDizi:0xbfee810d   DegerDizi:�
Döngü adet:55 AdresPointer:0x80485d7  DegerPointer:c   AdresDizi:0xbfee810e   DegerDizi:
Döngü adet:56 AdresPointer:0x80485d8  DegerPointer:    AdresDizi:0xbfee810f   DegerDizi:
Döngü adet:57 AdresPointer:0x80485d9  DegerPointer:    AdresDizi:0xbfee8110   DegerDizi:�
Döngü adet:58 AdresPointer:0x80485da  DegerPointer:    AdresDizi:0xbfee8111   DegerDizi:�
Döngü adet:59 AdresPointer:0x80485db  DegerPointer:A   AdresDizi:0xbfee8112   DegerDizi:�
Döngü adet:60 AdresPointer:0x80485dc  DegerPointer:d   AdresDizi:0xbfee8113   DegerDizi:�
Döngü adet:61 AdresPointer:0x80485dd  DegerPointer:r   AdresDizi:0xbfee8114   DegerDizi:
Döngü adet:62 AdresPointer:0x80485de  DegerPointer:e   AdresDizi:0xbfee8115   DegerDizi:/
Döngü adet:63 AdresPointer:0x80485df  DegerPointer:s   AdresDizi:0xbfee8116   DegerDizi:
Döngü adet:64 AdresPointer:0x80485e0  DegerPointer:D   AdresDizi:0xbfee8117   DegerDizi:
Döngü adet:65 AdresPointer:0x80485e1  DegerPointer:i   AdresDizi:0xbfee8118   DegerDizi:M
Döngü adet:66 AdresPointer:0x80485e2  DegerPointer:z   AdresDizi:0xbfee8119   DegerDizi:�
Döngü adet:67 AdresPointer:0x80485e3  DegerPointer:i   AdresDizi:0xbfee811a   DegerDizi:
Döngü adet:68 AdresPointer:0x80485e4  DegerPointer::   AdresDizi:0xbfee811b   DegerDizi:
Döngü adet:69 AdresPointer:0x80485e5  DegerPointer:%   AdresDizi:0xbfee811c   DegerDizi:
Döngü adet:70 AdresPointer:0x80485e6  DegerPointer:p   AdresDizi:0xbfee811d   DegerDizi:
Döngü adet:71 AdresPointer:0x80485e7  DegerPointer:    AdresDizi:0xbfee811e   DegerDizi:
Döngü adet:72 AdresPointer:0x80485e8  DegerPointer:    AdresDizi:0xbfee811f   DegerDizi:
Döngü adet:73 AdresPointer:0x80485e9  DegerPointer:    AdresDizi:0xbfee8120   DegerDizi:`
Döngü adet:74 AdresPointer:0x80485ea  DegerPointer:D   AdresDizi:0xbfee8121   DegerDizi:�
Döngü adet:75 AdresPointer:0x80485eb  DegerPointer:e   AdresDizi:0xbfee8122   DegerDizi:
Döngü adet:76 AdresPointer:0x80485ec  DegerPointer:g   AdresDizi:0xbfee8123   DegerDizi:�
Döngü adet:77 AdresPointer:0x80485ed  DegerPointer:e   AdresDizi:0xbfee8124   DegerDizi:1
Döngü adet:78 AdresPointer:0x80485ee  DegerPointer:r   AdresDizi:0xbfee8125   DegerDizi::
Döngü adet:79 AdresPointer:0x80485ef  DegerPointer:D   AdresDizi:0xbfee8126   DegerDizi:
Döngü adet:80 AdresPointer:0x80485f0  DegerPointer:i   AdresDizi:0xbfee8127   DegerDizi:
Döngü adet:81 AdresPointer:0x80485f1  DegerPointer:z   AdresDizi:0xbfee8128   DegerDizi:
Döngü adet:82 AdresPointer:0x80485f2  DegerPointer:i   AdresDizi:0xbfee8129   DegerDizi::
Döngü adet:83 AdresPointer:0x80485f3  DegerPointer::   AdresDizi:0xbfee812a   DegerDizi:
Döngü adet:84 AdresPointer:0x80485f4  DegerPointer:%   AdresDizi:0xbfee812b   DegerDizi:
Döngü adet:85 AdresPointer:0x80485f5  DegerPointer:c   AdresDizi:0xbfee812c   DegerDizi:H
Döngü adet:86 AdresPointer:0x80485f6  DegerPointer:
   AdresDizi:0xbfee812d   DegerDizi:�
Döngü adet:87 AdresPointer:0x80485f7  DegerPointer:   AdresDizi:0xbfee812e   DegerDizi:�
Döngü adet:88 AdresPointer:0x80485f8  DegerPointer:   AdresDizi:0xbfee812f   DegerDizi:�
Döngü adet:89 AdresPointer:0x80485f9  DegerPointer:   AdresDizi:0xbfee8130   DegerDizi:
Döngü adet:90 AdresPointer:0x80485fa  DegerPointer:   AdresDizi:0xbfee8131   DegerDizi:
Döngü adet:91 AdresPointer:0x80485fb  DegerPointer:   AdresDizi:0xbfee8132   DegerDizi:
Döngü adet:92 AdresPointer:0x80485fc  DegerPointer:   AdresDizi:0xbfee8133   DegerDizi:
Döngü adet:93 AdresPointer:0x80485fd  DegerPointer:   AdresDizi:0xbfee8134   DegerDizi:
Döngü adet:94 AdresPointer:0x80485fe  DegerPointer:   AdresDizi:0xbfee8135   DegerDizi:�
Döngü adet:95 AdresPointer:0x80485ff  DegerPointer:   AdresDizi:0xbfee8136   DegerDizi:�
Döngü adet:96 AdresPointer:0x8048600  DegerPointer:   AdresDizi:0xbfee8137   DegerDizi:
Döngü adet:97 AdresPointer:0x8048601  DegerPointer:   AdresDizi:0xbfee8138   DegerDizi:
Döngü adet:98 AdresPointer:0x8048602  DegerPointer:   AdresDizi:0xbfee8139   DegerDizi:
Döngü adet:99 AdresPointer:0x8048603  DegerPointer:   AdresDizi:0xbfee813a   DegerDizi:

fatih6761

@everygelem hocam sorununuzun cevabı tam olarak yok aslında. Bu olay derleyiciye ve platforma çok bağlı. Ancak Windows ve Visual C için düşünürsek, basit bir assembly çıktısı olayı çözüyor.
Asıl mesele programın nasıl çalıştırıldığı. Sizin programınız .exe halinde iken farklı kısımlara(section) sahiptir. Bunlardan ilki .text sectionıdır. Bu kısımda sizin çalıştırılabilir kodunuz saklanır.
Bir diğeri .rdata kısmıdır. GCC için .rodata dır. Bu kısmın adı Read Only DATA'dır. Yani yalnızca okunabilir olan veriler buraya kaydedilir. İşletim sistemi bu kısımları RAM'e kopyalayarak çalıştırır.
Sizin programınızdan daha basit olan şu kodu ele alalım:
#include <stdio.h>

void main()
{
	char a[] = "bu dizi seklinde";
	char * b = "bu ptr seklinde";
	
	printf("%d %d %d %d", a, b);
}

Kod basitçe bir dizi ve bir pointer oluşturup bunların adreslerini ekrana basıyor. Bu programı derlediğinizde iki metin de ("bu dizi seklinde" ve "bu ptr seklinde") .rdata sectionına konulur.
Programın Assembly çıktısına bakarak olayların nasıl geliştiğini görebiliriz:
; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.20617.1 

	TITLE	C:\Users\Fatih\Desktop\deneme.c
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

_DATA	SEGMENT
$SG3045	DB	'bu dizi seklinde', 00H
	ORG $+3
$SG3047	DB	'bu ptr seklinde', 00H
$SG3048	DB	'%d %d %d %d', 00H
_DATA	ENDS
PUBLIC	_main
EXTRN	_printf:PROC
EXTRN	@__security_check_cookie@4:PROC
EXTRN	___security_cookie:DWORD
; Function compile flags: /Odtp
_TEXT	SEGMENT
_b$ = -28						; size = 4
_a$ = -24						; size = 17
__$ArrayPad$ = -4					; size = 4
_main	PROC
; File c:\users\fatih\desktop\deneme.c
; Line 4
	push	ebp
	mov	ebp, esp
	sub	esp, 28					; 0000001cH
	mov	eax, DWORD PTR ___security_cookie
	xor	eax, ebp
	mov	DWORD PTR __$ArrayPad$[ebp], eax
; Line 5
	mov	eax, DWORD PTR $SG3045
	mov	DWORD PTR _a$[ebp], eax
	mov	ecx, DWORD PTR $SG3045+4
	mov	DWORD PTR _a$[ebp+4], ecx
	mov	edx, DWORD PTR $SG3045+8
	mov	DWORD PTR _a$[ebp+8], edx
	mov	eax, DWORD PTR $SG3045+12
	mov	DWORD PTR _a$[ebp+12], eax
	mov	cl, BYTE PTR $SG3045+16
	mov	BYTE PTR _a$[ebp+16], cl
; Line 6
	mov	DWORD PTR _b$[ebp], OFFSET $SG3047
; Line 8
	mov	edx, 1
	imul	eax, edx, 0
	add	eax, DWORD PTR _b$[ebp]
	push	eax
	mov	ecx, 1
	imul	edx, ecx, 0
	lea	eax, DWORD PTR _a$[ebp+edx]
	push	eax
	mov	ecx, DWORD PTR _b$[ebp]
	push	ecx
	lea	edx, DWORD PTR _a$[ebp]
	push	edx
	push	OFFSET $SG3048
	call	_printf
	add	esp, 20					; 00000014H
; Line 9
	xor	eax, eax
	mov	ecx, DWORD PTR __$ArrayPad$[ebp]
	xor	ecx, ebp
	call	@__security_check_cookie@4
	mov	esp, ebp
	pop	ebp
	ret	0
_main	ENDP
_TEXT	ENDS
END

Parça parça ele alırsak:
_DATA	SEGMENT
$SG3045	DB	'bu dizi seklinde', 00H
	ORG $+3
$SG3047	DB	'bu ptr seklinde', 00H
$SG3048	DB	'%d %d %d %d', 00H
_DATA	ENDS

Burası data segmentini oluşturuyor. .rdata'nın en başına ilk mesajımız yazılıyor. 3 byte ileri atlanıp sonraki mesajımız yazılıyor ve pesine printf'deki stringimiz yazılıyor.
Buraya kadar mesajlarımız aynı yerdeymiş gibi görünüyor. Doğru, dosyada peş peşeler ancak sonrasında durum değişiyor.
mov	eax, DWORD PTR $SG3045
	mov	DWORD PTR _a$[ebp], eax
	mov	ecx, DWORD PTR $SG3045+4
	mov	DWORD PTR _a$[ebp+4], ecx
	mov	edx, DWORD PTR $SG3045+8
	mov	DWORD PTR _a$[ebp+8], edx
	mov	eax, DWORD PTR $SG3045+12
	mov	DWORD PTR _a$[ebp+12], eax
	mov	cl, BYTE PTR $SG3045+16
	mov	BYTE PTR _a$[ebp+16], cl

Burada a dizimize .rdata section'undaki metin 4'er 4'er kopyalanıyor. Yani _a değişkeni aslında bellekte rastgele bir yerde, biz metnimizi oraya kopyalıyoruz. Örneğin dosyamız diskten alında ve işletim sistemi dosyayı açtı, .rdata kısmını ramin 0x1000 adresine çıkardı. Ancak bizim _a değişkenimiz (ki bu .text içinden alındı) bellekte 0x1234'te oluşturuldu(heap). Kodumuz, .rdata'daki metni 0x1000'den 0x1234'e kopyaladı.
Bu yüzden programı her çalıştırdığınızda a'nın adresi farklı bir değer alır.
İkinci kısma gelelim:
mov	DWORD PTR _b$[ebp], OFFSET $SG3047

Buradaki işlem çok basit. Yalnızca ikinci metnin offset adresi alınıyor ve _b nin içine kopyalanıyor. _b burada bir pointer olduğundan sadece verinin adresini saklıyor.
Şimdi, nasıl oluyor da _a ile _b çok farklı yerlere gidiyor? Başka bir deyişle _a her seferinde değişirken _b sabit kalıyor. Bu noktada virtual memory diye bir olay ortaya çıkıyor. İşletim sistemi MMU birimini kullanarak bize hep sahte adresler veriyor. Hiç bir zaman gerçek fiziksel adresleri kullanmıyoruz. Bu adresler sadece bize bildirilen 4GB'lık sanal bellek alanında oluşturulmuş adresler, bu yüzden bizim programımız kendini hep bellekte 100 adresine yüklenmiş sanıyor. Verilerin adresleri de buna göre offsetleniyor. Yani bizim ikinci metnimiz gerçek fiziksel bellekte çok farklı yerlede de olsa, biz onu kendi bellek alanımızda aynı yerde sanıyoruz.
Sonuçta bu iki mesaj ram'de ard arda olsalar bile biz ikincisini yanımızda sanıyoruz.
En başta çok değişken demiştim. Bu durumda bundan kaynaklanıyor. Eğer bu kodu işletim sistemi olmadan bir PIC ile çalıştırırsanız, ard arda adresler görebilirsiniz. Ya da GCC ile farklı, VC++ ile farklı sonuçlar elde edebilirsiniz.
Yanlışım varsa düzeltin.
İyi çalışmalar...

arslan74

char a[]="test";
char *p="test";


yukarkıda ki,

char a[]="test"; anlamı

içinde "test" yazısı tutan ve const olmayan bir değişkendir.

onu şöylede yazabilirsiniz.

char a[]={'t','e','s','t',0};

oysa  char *p="test";  ise aynı anlama gelmiyor. Büyük ihtimalle de yukarıda ki şekilde yazdığımızda hata verir.

"test" = const bir yazı dizisidir. Bu const dizi adresini bir pointere (p ye) yükleyip ona oradan işlem yapıyoruz.

RAM (const olmayan ) ile ROM (const olan) değişkenlerin adresleri farklı yerlerdir. ondan farklı adres vermiştir. Dediğimi ispatlamanın bir yoluda

a[0]='m';
p[0]='m';

yazdğımızda a nın değiştiği ama p nin değişmediğini gördüğümüzde anlarız.

everygelem

burdan anladığım C çalışmaya devam edicem demek ki hızı artırarak. Zaman ayırıp yanıt veren arkadaşlara tekrar teşekkürler.

Gökhan BEKEN

@arslan74 hocam sabit olarak kalacak yazıları dizi değişken tanımlamak , değişecek verileride pointerter tanımlamak mı mantık lı?
Hangisini hangi durumda kullanmak mantıklı?
Özel mesaj okumuyorum, lütfen göndermeyin.

CLR

Alıntı yapılan: meftun - 05 Eylül 2013, 17:49:50
@arslan74 hocam sabit olarak kalacak yazıları dizi değişken tanımlamak , değişecek verileride pointerter tanımlamak mı mantık lı?
Hangisini hangi durumda kullanmak mantıklı?

Merhaba,
Sabit kalacak, değişmeyecek yazıları, verileri const tanımlaki ram'den yemesin.
Değişecek veriler için ister pointer kullan istersen array(dizi).
Değişkenlere pointer atanacağı gibi değişmeyenler içinde pointer tanımlayabilirsin, pointer sadece const olur yani point ettiği adresi okursun ama o adrese yazamazsın. 
Knowledge and Experience are Power

Gökhan BEKEN

Ben şunu anlamadım:
char a[]="test\0";
char *p="test";

bu iki satır aynı anlama gelmiyor mu?

a[0]='m';
p[0]='m';

yazdığımda neden değişmiyor anlamadım, ikiside ram de tanımlı değil mi, p neden değişmiyor?

char *p="test";

Bu tanımlamada, pointeri sabit mi tanımlamış oluyoruz?
Özel mesaj okumuyorum, lütfen göndermeyin.