C Programlama diliyle şamatalar

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

l0rd

Alıntı yapılan: vitruvius - 27 Ocak 2018, 13:52:32
1) Adreslere bakip bir elemanin adresi 62FE30'dan basliyor, bir sonraki eleman da 62FE34'ten basliyor diye onceki elemanin 4 byte kapladigini soylemek yanlis olur. Detayli bilgi icin Byte Alignment konusunu buradan okuyabilirsin.

2) Bir degiskenin adresine ulasmak istiyorsan & operatorunu kullanmalisin.

Teşekkürler verdiğiniz kaynaktaki padding kavramını okudum ve neden 4byte olduğunu anladım..Ama 2. soruda demek istediğim struct içindeki herhangi bir elemanın adrese erişmek için  &(*structpointer).eleman  dışında bir kullanımın olup olmadığı ?

Alıntı yapılan: Pyrodigy - 27 Ocak 2018, 14:52:11
Merhaba
Yazdıkların ile bilgisayarının 64 bit lik işletim sisteminde bellekte ayrılmış yapı nesnelerinin adreslerini görüyorsun. Bu arada Dikkat et belirsiz adreslere yazacağın bilgiler sistemini çökertebilir. Malloc gibi fonksiyonları kullanmanı tavsiye ediyorum.
Eğer pic, arm, atmel...vs gibi işlemciler ile program yazmak istiyorsan ki bu forumda sana yardımcı olan üstadların ana bilim dalılarıdır o halde seçeceğin çip ile uyumlu derleyici ! İle çalışmalısın.
Bu konuda forum senin temel kaynağın olsun.
Sevgiler

teşekkürler , haklısınız bir denetleyici alıp onun üzerinde denemeler yapmak mantıklı
what you do that defines you

l0rd

#include<stdio.h>

int main()
{
	
	unsigned short uSh;          //2byte
	char ch;                          //1byte
	uSh=0xFF10;
	ch=uSh;
		
	printf("uSh: %d , Ch:%d",uSh,ch);        //uSh:65296  Ch:16

return 0;
}


#include<stdio.h>

int main()
{
	
	unsigned short uSh;          //2byte
	char ch;                          //1byte
	uSh=0xFF10;
	ch=(char)uSh;
		
	printf("uSh: %d , Ch:%d",uSh,ch);        //uSh:65296  Ch:16

return 0;
}



Bu iki program arasında fark nedir?Tür dönümü yapsam da yapmasam da aynı sonucu alıyorum..

what you do that defines you

vitruvius

Alıntı yapılan: l0rd - 28 Ocak 2018, 13:19:56
Bu iki program arasında fark nedir?Tür dönümü yapsam da yapmasam da aynı sonucu alıyorum..

Cunku C99 Standardi, 6.5.16.1 Simple assignment, Semantics, Madde 2 der ki:

Alıntı YapIn simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.

l0rd

#include<stdio.h>
int main(){
	int num1=1,num2=2;
	float div;
	div=num1/num2;
	printf("%f",div);
}


#include<stdio.h>
int main(){
	int num1=1,num2=2;
	float div;
	div=(float)num1/num2;
	printf("%f",div);
}


Ozaman bu iki programın sonucunun aynı çıkmamasının sebebi (yani C99 a göre sağ taraf değerinin ,sol taraf değerinin türüne değiştirildikten sonra, sol taraf değerinde depolanmamasının sebebi)  Eşittir(=) ifadesinden sonra bir işlem olması mı?

"simle assignment" demek verdiğim örneklerdeki gibi mi ( sadece sol taraf deferi = sağ taraf değeri olan)
a=b;
a=45;
a=0x055F;   

int* ptr
ptr=5;      Burada int türünü (int *) türüne atarken
what you do that defines you

vitruvius

Alıntı yapılan: l0rd - 28 Ocak 2018, 16:12:19
Ozaman bu iki programın sonucunun aynı çıkmamasının sebebi (yani C99 a göre sağ taraf değerinin ,sol taraf değerinin türüne değiştirildikten sonra, sol taraf değerinde depolanmamasının sebebi)  Eşittir(=) ifadesinden sonra bir işlem olması mı?

Oradaki durum farkli. Arithmetic bir islem var orda. Onun icin standardin farkli bir bolumunu okuman lazim (6.3.1 Arithmetic Operands). Kisaca, ilk orneginde integer division var. Iki integer sayiyi bolersen sonuc olarak integer elde edersin. Ikinci orneginde float bir sayiyi integer bir sayiya boluyorsun, bu yuzden sonuc olarak float bir deger elde ediyorsun.

Compiler'lar her islem icin gerekli degisken turunu hesaplar ve aksi belirtilmezse gerekli gordugu yerde buna gore kendisi cast islemi yapar (implicit cast). Bunlari gormek her zaman kolay olmayabilir ve bulmasi zor hatalara sebep olabilir. Bu konulari daha iyi anlaman icin implicit cast, integer promotions, conversions, arithmetic operands gibi konulari her sabah kahvaltidan sonra okumani tavsiye ederim.

l0rd

Alıntı yapılan: vitruvius - 28 Ocak 2018, 21:39:16
Oradaki durum farkli. Arithmetic bir islem var orda. Onun icin standardin farkli bir bolumunu okuman lazim (6.3.1 Arithmetic Operands). Kisaca, ilk orneginde integer division var. Iki integer sayiyi bolersen sonuc olarak integer elde edersin. Ikinci orneginde float bir sayiyi integer bir sayiya boluyorsun, bu yuzden sonuc olarak float bir deger elde ediyorsun.

Compiler'lar her islem icin gerekli degisken turunu hesaplar ve aksi belirtilmezse gerekli gordugu yerde buna gore kendisi cast islemi yapar (implicit cast). Bunlari gormek her zaman kolay olmayabilir ve bulmasi zor hatalara sebep olabilir. Bu konulari daha iyi anlaman icin implicit cast, integer promotions, conversions, arithmetic operands gibi konulari her sabah kahvaltidan sonra okumani tavsiye ederim.

Teşekkür ederim , öğrenecek çok şey varmış :) bunları da araya sıkıştıracağım
what you do that defines you

l0rd

(int *) türden bir pointer tanımlayalım , tanımladığımız bu pointerı artırıp azalttığımızda bize güvenli hafıza bölgesinden mi yer ayırır ? Bir sonraki/bir önceki adresin kullanılabilirlik durumu/reserved durumu vs bakar mı?

mesela şöyle bir program olsun

#include<stdio.h>
#define COUNT 2
int main(void){
	
	int sayi;
	int i=0;
	int *ptr;
	ptr=&sayi;
	
	while(i<COUNT){
		
	printf("sayi gir\n");
	scanf("%d",ptr);
	printf("girilen sayi %d  \n",*ptr);
	++ptr;
	
	}

	
	return 0;
}


burada ++p yaparak bir sonraki adrese yeni bir değer girdim , o adresin güvenlilik durumu nedir?
what you do that defines you

SpeedyX

Yok bakmaz, sıradakine yazmaya çalışır ve her türlü probleme müsaittir. Eğer COUNT değerin int boyutundan büyük olsaydı tehlike başlamıştı diyebiliriz.

mir_as82

Burada stack boyutu ile ilgili bir sorun çıkabilir.
İşin kısacası yazılmaması gereken bir kod

l0rd



Alıntı yapılan: SpeedyX - 01 Şubat 2018, 20:28:51
Eğer COUNT değerin int boyutundan büyük olsaydı tehlike başlamıştı diyebiliriz.

COUNT:2  ve  int türü 4byte olduğu için bir sonraki eleman 4 byte sonrasına yerleşecek.Yani 1 integer saklayacak alanı aştık bile. Sormak istediğim bir sonraki integer in saklanacağı alanın güvenilirliğiydi , sanırım emin olamıyoruz o alanın güvenilirliği hakkında..

Alıntı yapılan: mir_as82 - 01 Şubat 2018, 22:57:01
Burada stack boyutu ile ilgili bir sorun çıkabilir.


her eleman için 4 byte ayıracak , boyut sınırı olmacağını düşünmüyorumda.Bu yer derleyici tarafından ayrılmıyor mu da güvensiz orayı anlayamadım.

Mesela yukarıdaki programda 000000000062FE44 adresi derleyici tarafından ayrılıyor bundan eminim ve orası güvenli (kitapta okumustum) ama adresi bir artırdığımda elde ettiğimiz 000000000062FE48  adresini ben belirlemiş oldum , derleyici belirlemediği için güvensiz olma ihtimali olabilir mi?

what you do that defines you

SpeedyX

Sonraki adres, başka bir değişken için ayrılmış bir alan olabileceği gibi geçersiz bir adres de olabilir yada iyi ihtimalle kullanılmayan geçerli bir adres olabilir.

mir_as82

Hocam benim tahminim, senin son tanımladığın değişken int *ptr olduğu için veya döngün az sayıda olduğu için sorun olmuyor. Onun için başka değişkenleri ezmiyor. Bunu denemek için döngü sayısını arttırıp deneyin.
Daha sonra int *ptr yi programın en başında tanımlayın daha sonra ondan sonra değişken tanımlarsanız ve onlara değerler verirseniz o değişkenleri ezeceğiniz aşikar bellidir.


Mucit23

#1077
Selamlar

STM32'de STRTOL fonksiyonunu kullanmam gerekti ama bir sorun yaşıyorum. STM32 çipimde Usart Kesmesi Timer Kesmesi gibi donanımlar çalışıyor bazı rutin işler yapıyorum. Uart Üzerinden String olarak Hexadesimal veriler alıyorum. "55", "A7" gibi. Bu değerleri integer türünde hexadesimal değerlere çevirmem gerekiyor. Bunun için STRTOL fonksiyonunu kullandım. Aşağıdaki gibi bir kullanımı var.

Addr=strtol(substr,NULL,16);

Tek başına iyi çalışıyor fakat timer kesmesi geldiği anda işlemci hardfaulta düşüyor. Kesmelerle birlikte çalışmıyor bu fonksiyon.

Bu neden olur daha önce başına gelen varmı? Bu fonksiyonun yaptığı işi kendim sade bir şekilde nasıl yaparım?

Ekleme: Gerek Kalmadı Kendim benzer bir fonksiyon yazarak hallettim.
string halde gelen hexadesimal verileri integere dönüştüren programç

uint8_t mystrtol(char *ptr)
{
	 uint8_t asciint=0,sayi=0;
	
   while (*ptr!='\0')
	 {
	    if(*ptr>='0' && *ptr<='9')	
	    {
	  	  asciint=*ptr-48; 
	    }
	    else if(*ptr>='A' && *ptr<='F')
	    {
	      asciint=(10+*ptr-65);
	    }
		else
		{
		  asciint=0;
		}
	  sayi=sayi*16+asciint;
		ptr++;
	 }
	 return sayi;
}

OptimusPrime

prototipi bu mu? strtol long int strtol(const char *nptr, char **endptr, int base)

exception firlatiyor olabilir mi? veya basarili bir sekilde geri donup donmedigine bakiyor musun? veya hatali bir degeri dondurdugunden dolayi islemci ben oynamiyorum moduna giriyor olabilir mi?
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

Mucit23

Evet prototipi o şekilde. Yazdığım kod anlık ürettiğim çözümdü, Çalışıyor.

Sorunun sebebini aslında anlayamadım. Çünkü İşlemci içerisinde Herhangi bir kesme açık değilken fonksiyon aynı şekilde çalışıyor. Fakat kesmeler açık iken fonksiyonu çalıştırsam işlemci çalışmayı bırakıyor.