C Programlama diliyle şamatalar

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

baran123

29 Eylül 2017, 17:51:34 #1050 Son düzenlenme: 29 Eylül 2017, 17:56:24 baran123
Yanlış değil.
Ona blok açmak deniyordu sanırım.

"C ile Programlama Prof.Dr.Mitat Uysal"
2.Baskı Sayfa 209

Kısaca değişken tanımlandığı blok dışında kullanılamaz.
İdrak i meali bu küçük akla gerekmez, zira bu terazi bu kadar sıkleti çekmez.

vitruvius

Alıntı yapılan: unknownperson - 29 Eylül 2017, 17:09:31
Merhabalar, C'nin hangi türüne mutaassıp olduğunu bilmiyorum ama şu tür bir yazım ile karşılaştım ne anlama geliyor, ne amaçla kullanılıyor bilmiyorum. Aşağıda buluna kod parçasında parantezler ne bir if ne de herhangi bir döngü için kullanılmış bu süslü parantezlerin kullanım amacı nedir ?

Kod Seç
int16_t data
{
int16_t data;    
data 3
	

}



Scope yaratmada kullanilir. Bazen belli degiskenlerin kisa omurlu olsun, bir scope icinde kalsin isteyebilirsin.

Misal:

Kod Seç
#include "stdio.h"

int main()
{
  
int num 0;
  
printf("num: %d\n"num);
  {
    
int num 0;
    
num 5;
    
printf("num: %d\n"num);
  }
  
printf("num: %d\n"num);
}


Bu kod parcasi asagidaki ciktiyi verecektir:
Kod Seç
num0
num
5
num
0


Farkettiysen 5 degerini atadigimiz "num" degiskeni scope'un disina ciktiginda ucup gitti.

Ayni kodu asagidaki gibi degistirirsek:
Kod Seç
#include "stdio.h"

int main()
{
  
int num 0;
  
printf("num: %d\n"num);
  {
    
int num1 0;
    
num 5;
    
printf("num: %d\n"num);
  }
  
printf("num1: %d\n"num1);
}


Soyle bir hata alirsin:
Kod Seç
aaa.c:12:24error: use of undeclared identifier 'num1'did you mean 'num'?
  
printf("num1: %d\n"num1);
                       ^~~~
                       
num
aaa
.c:5:7note'num' declared here
  int num 
0;
      ^


Burada kendi olusturdugumuz kucuk scope icinde "num" degiskenine erisip onu degistirmekte sorun yok. Ancak, en sondaki printf "num1"in degerini yazmaya calisiyor. C dilinde degiskenler tanimli olduklari scope araliginda varolurlar. Yani buradaki hata "num1"e scope disinda erismeye calismak.

Tabi verdigin kod cok eski bir kod ise pre-ANSI C donemlerinde baska bir kullanimi daha var {}'in ama bosuna kafa sisirmeyelim :)

unknownperson

Çok iyi anlatmışsınız aslında kodu biraz salladım başka bir yerde görmüştüm bu iki parantez arası işlem yaptırıyordu. Ben de sizin dediğiniz gibi tahmin etmiştim parantezler arası tanımlı oluyor diye. Fakat bu dediğim süslü parantezler sık kullanılıyor genelde main boardlarda. Sizin dediğinize göre sanırım sadece o parantezler arası tanımlı olduğundan oradan çıkınca değer uçuyor ve az hafıza kullanıyor şeklinde yani az alan kapsaması için mi kullanılıyor ? Yoksa başka amaçlar içinde kullanılabilir mi mesela pre-ANSI C 'den az bahsedebilir misiniz ?

vitruvius

Evet bir degiskenin run-time omrunu azaltmak icin scope kullanabilirsin/kullanmalisin. Scope disina ciktiginda stack'ten silinirler. Boylece RAM'den birazcik kar edersin :)

Ya da ayni kod parcasini ya da degisken ismini tekrar kullanmak istiyorsan o kod parcasini/degisken tanimlamasini kopyalayip {} icine koyabilirsin. Boylece bir sikinti olmaz.

Yanlis hatirlamiyorsam pre-ANSI C'de fonksiyonlar soyle tanimlaniyordu.

Kod Seç
int sum(ab)
int a;
int b;
{
    return 
a+b;
}


Soyle de bir durum var C99 standardi oncesinde kafana gore bir yerde degisken tanimlayamazsin. Bir scope'un en basinda tanimlaman gerekir.

Mesela asagidaki kodu C90 standardi ile derleyelim:
Kod Seç
int main()
{
  
int x1 1;
  
x1 5;
  
int x2 3;
  
printf("Sum: %d\n"x1 x2);
  return 
0;
}


Asagidaki gibi bir uyari aliriz:
Kod Seç
aaa.c:7:7errorISO C90 forbids mixing declarations and code [-Werror,-Wdeclaration-after-statement]
  
int x2 3;
      ^


Ama bir scope olusturup bunun en basinda tanimlarsan bir sorun olmaz. Bu arada scope olusturmak icin illa basi bos {} yapmaya gerek yok. Bir if{} de bir scope'dur, bir while(){} da.

Kodu asagidaki gibi degistirelim:
Kod Seç
int main()
{
  
int x1 1;
  
x1 5;

  if (
x1 >5) {
    
int x2 3;
    
printf("Sum: %d\n"x1 x2);
  }
  return 
0;
}


Gordugun gibi burada if ile bir scope olusturup, en basinda degiskenimi tanimladim. Derleyince herhangi bir hata vermedi. He bana inanmaz da kendin derlemek istersen :) ve gcc kullaniyorsan:

Kod Seç
--pedantic-errors

flag'i ile derlemen gerekir. Yoksa gcc'yi C80-90 standardi kullanmaya zorlayamazsin.

unknownperson

Çok çok yararlı oldu @vitruvius hocam, anlatım için teşekkür ederim  :D

F493

30 Eylül 2017, 00:08:46 #1055 Son düzenlenme: 30 Eylül 2017, 00:10:35 F493
Yanlış yere yazıldı.
Sırtındaki kocaman damlaya rağmen tutunmaya çalışan Uğur böceği.

foseydon

yeni birşey daha öğrenmiş oldum. Ama bu nasıl kullanılır pek aklım kesmedi işin açığı.

unknownperson

13 Kasım 2017, 19:54:46 #1057 Son düzenlenme: 13 Kasım 2017, 21:04:55 unknownperson
-

l0rd

İlk değer verilmemiş ya da bir atama yapılmamış değişkenlerin davranışını aşağıdaki gibi öğrenmiştim.
Yerel Değişken-> Çöp bir değer ile başlar (O an bellekte o değişken için ayrılmış  yerde bulunan 1 ve 0 bitlerinin oluşturduğu değer)
Statik Yerel Değişken , Global Değişken -> Sıfır değeri ile başlaması derleyici tarafından sağlanır.

Şimdi aşağıdaki programı Borland Dev C++ 5.4 ile derlediğimde görüyorum ki , hem yerel değişken hem de global değişken SIFIR değeri ile başlamış.Global değişkenim için bu değer(SIFIR) doğru fakat yerel değişken içinde çöp bir değer olması gerekmez mi?

Kod Seç
#include<stdio.h>

int globalVariable;

int main(void){
	
int localVariable;
	
printf("LocalV: %d\n",localVariable);
	
printf("GlobalV: %d",globalVariable);
	

	
return 
0;
}



what you do that defines you

vitruvius

Alıntı yapılan: l0rd - 26 Ocak 2018, 21:45:06
İlk değer verilmemiş ya da bir atama yapılmamış değişkenlerin davranışını aşağıdaki gibi öğrenmiştim.
Yerel Değişken-> Çöp bir değer ile başlar (O an bellekte o değişken için ayrılmış  yerde bulunan 1 ve 0 bitlerinin oluşturduğu değer)
Statik Yerel Değişken , Global Değişken -> Sıfır değeri ile başlaması derleyici tarafından sağlanır.

Şimdi aşağıdaki programı Borland Dev C++ 5.4 ile derlediğimde görüyorum ki , hem yerel değişken hem de global değişken SIFIR değeri ile başlamış.Global değişkenim için bu değer(SIFIR) doğru fakat yerel değişken içinde çöp bir değer olması gerekmez mi?

Kod Seç
#include<stdio.h>

int globalVariable;

int main(void){
	
int localVariable;
	
printf("LocalV: %d\n",localVariable);
	
printf("GlobalV: %d",globalVariable);
	

	
return 
0;
}






Cop derken? O an o hafiza alaninda ne varsa onu alir. Demek ki sifir varmis. C Standardini acip bakarsan:

C99 standardi, 6.7.8 Initialization der ki:

AlıntıIf an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
-- if it has pointer type, it is initialized to a null pointer;
-- if it has arithmetic type, it is initialized to (positive or unsigned) zero;
-- if it is an aggregate, every member is initialized (recursively) according to these rules;
-- if it is a union, the first named member is initialized (recursively) according to these rules.

l0rd

Alıntı yapılan: vitruvius - 26 Ocak 2018, 22:29:07
Cop derken? O an o hafiza alaninda ne varsa onu alir. Demek ki sifir varmis. C Standardini acip bakarsan:

C99 standardi, 6.7.8 Initialization der ki:


Sanırım dediğiniz ki .. SAĞOLUN   ( aşağıda sağlamasını yapmaya çalıştım )



what you do that defines you

l0rd

Struct türünden bir pointer tanımladım ve pointer ile struct elemanlarına erişmeyi denedim . Yazdığım test programı aşağıdadır .

1.char 0x000000000062FE30  adresinden baslamıs 0x000000000062FE34 adresinde bitmis yani 4 byte , diğer türler içinde bu geçerli olmuş.(Ekran görüntüsü 2 ye bakabilirsiniz) Neden 4 byte ? Ben 1 byte diye biliyordum..

2.Struct içindeki elemanların adreslerini * operatörü ve & operatörünü aynı anda kullanmadan nasıl gösterebiliriz ? Yani   &(*pointer).eleman  seklinde kullanmadan?
ben pointer.eleman denedim hata verdi , *pointer.eleman denedim olmadıı...

Kod Seç

#include<stdio.h>

int main(void){
	

	
struct myStr {
	
	
char myChVar
	
	
int myIntVar;
	
	
float myFltVar;               
	
}
myStrVar={'k',50,5.4} , *myPtrVar;
	

    
myPtrVar=&myStrVar;
    
    
    
printf("Degisken ile erisim  Ch:%c Int:%d Flt:%f \n",myStrVar.myChVar,myStrVar.myIntVar,myStrVar.myFltVar);
    
printf("Gosterici ile erisim Ch:%c Int:%d Flt:%f \n",myPtrVar->myChVar,myPtrVar->myIntVar,myPtrVar->myFltVar);
    
    
    
    
printf("Struct un adresi:%p \n",myPtrVar);
    
printf("Elemanlarin adresleri(degiskenin adresi ile erisim)  Ch:%p Int:%p Flt:%p \n",&myStrVar.myChVar,&myStrVar.myIntVar,&myStrVar.myFltVar);
    
printf("Elemanlarin adresleri(Gosterici ile erisim) Ch:%p Int:%p Flt:%p",&(*myPtrVar).myChVar,&(*myPtrVar).myIntVar,&(*myPtrVar).myFltVar);
    
    return 
0;
}




what you do that defines you

foseydon

Char 8bit,  İnt 16 bit, Float 32 bit değişkenlerdir. Senin verileri tuttuğun bellek kaç bit işe ona göre bellek adreslerine yerleşirler. Bu ne demek. Misal bellek 8 bit işe, char 1 adrese int 2 adrese, float 4 adrese yayılır, toplam adres sayısı 7 olur.

Struct pointer in elemanlarına -> operatörü ile erişebilirsin.

vitruvius

Alıntı yapılan: l0rd - 27 Ocak 2018, 03:21:04
Struct türünden bir pointer tanımladım ve pointer ile struct elemanlarına erişmeyi denedim . Yazdığım test programı aşağıdadır .

1.char 0x000000000062FE30  adresinden baslamıs 0x000000000062FE34 adresinde bitmis yani 4 byte , diğer türler içinde bu geçerli olmuş.(Ekran görüntüsü 2 ye bakabilirsiniz) Neden 4 byte ? Ben 1 byte diye biliyordum..

2.Struct içindeki elemanların adreslerini * operatörü ve & operatörünü aynı anda kullanmadan nasıl gösterebiliriz ? Yani   &(*pointer).eleman  seklinde kullanmadan?
ben pointer.eleman denedim hata verdi , *pointer.eleman denedim olmadıı...


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.

Pyrodigy

27 Ocak 2018, 17:52:11 #1064 Son düzenlenme: 27 Ocak 2018, 17:56:48 Pyrodigy
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

Persistance is the name of the game in this business....