Dyskusja:C/Operatory

Treść strony nie jest dostępna w innych językach.
Z Wikibooks, biblioteki wolnych podręczników.

dlaczego w dymku {{TODO|...}} wyswietla mi sie {{{1}}} ???
Noisy 14:06, 25 lis 2006 (CET)[odpowiedz]

Czasem gdy poda się zbyt skomplikowany kod po |, MediaWiki sobie nie radzi. Trzeba wtedy zamiast | użyć |1= i pójdzie. --Derbeth talk 14:08, 25 lis 2006 (CET)[odpowiedz]

Czemu akurat float[edytuj]

Czemu niby generalnie najczęściej będziemy używać float? Nie widzę powodów, dla których miałby on mieć jakieś obiektywne zalety w stosunku do typu double. Co więcej, kojarzy mi się że na jakiejś architekturze koprocesor arytmetyczny nie był w stanie operaować na zmiennych typu float i programy, które ten typ wykorzystywały działały wolniej od programów korzystających z double bo porzebna była kowersja. -- Mina86

Bo jest mniejszy? Bo nie potrzebujemy tu dużej dokładności? Zdaje mi się, że w podręcznikach częściej używa się typu float. --Derbeth talk 15:42, 5 sty 2007 (CET)[odpowiedz]
Za różnego rodzaju konwersje (w tym float <-> double) odpowiada kompilator. Sam procesor (mówię o architekturze i386) także ma taką możliwość (instrukcje CVTxxx), jednak kompilator w ramach optymalizacji kodu sam powinien się tym zająć. Wracając do tematu - oszczędność pamięci jest dobrym nawykiem. W większości przypadków początkujący programista raczej nie będzie korzystał z precyzji, którą oferują typy double czy long double. Dlatego też stosowanie typu float jest całkowicie uzasadnione w przypadku podręcznika, który ma nauczyć podstaw języka. --Kj 16:03, 5 sty 2007 (CET)[odpowiedz]

Błąd w wersji PDF[edytuj]

Znalazłem kolejny błąd w wersji PDF. Na stronie 36 (według numeracji na górach stron) w podpunkcie "Operacje bitowe" negacja bitowa nie ma żadnego znaku w cudzysłowie (powinien być "~") a alternatywa bitowa ma zły symbol ("--" zamiast "|"). Na 41 stronie w podpunkcie "Inne operatory" są również błędy jak i na 42 stronie w tabeli (brakuje niektórych operatorów). -- mad5ci 09:26, 2 wrz 2008 (CET)[odpowiedz]

Dziwność[edytuj]

Zaskakująca może się wydać linijka oznaczona przez [1]. Niejawna konwersja z typu
const char* do typu char* nie jest dopuszczana przez standard C. Jednak literały napisowe
(które są typu const char*) stanowią tutaj  wyjątek.

A niejawna konwersja z typu const int do typu int jest dopuszczana?

int z = 2;

Może czegoś nie rozumiem, bo na moje oko konwersja w żadnym z tych przypadków nie zachodzi, najwyżej interpretacja.

"int z=2" to nie konwersja, tylko przypisanie wartości do zmiennej. Natomiast między wskaźnikiem na const i wskaźnik na nie-const jest duża różnica, bo drugi pozwala zmieniać coś, co nie powinno być zmieniane --Lethern 16:19, 9 sty 2010 (CET)[odpowiedz]
To rozumiem, jednak wzmiankowana linijka wygląda tak:
char *str = "foo";       /* konwersja z const char* do char*  [1] */

W tym przypadku kompilator GCC wyrzuci ostrzeżenie (np. [Warning] deprecated conversion from string constant to 'char*' ), ale nie error. Jednak tutaj jest error (w przypadku standardu C, tzn. "gcc -ansi" ):

const char *cstr;
char *str = cstr;

--Lethern 01:05, 16 sty 2010 (CET)[odpowiedz]

Nie wiem czemu napisałem 'int z = 2;' skoro chciałem napisać 'int *z = 2;'. Chodzi to, że taka konstrukcja tworzy wskaźnik do obszaru pamięci danych programu i pozwala ją nadpisywać, a to jest niewskazaną praktyką?

Teoretycznie taka konstrukcja tworzy wskaźnik wskazujący na dane zawarte pod adresem 0x00000002 (i386) w pamięci. Czy jest to niewskazana praktyka? I tak i nie. Na pewno wszędzie tam, gdzie system operacyjny zarządza pamięcią programu, czyli w tym podręczniku - praktycznie zawsze. W takim przypadku pierwsza próba odczytu/zapisu danych przy użyciu tego wskaźnika zapewne spowoduje wywrócenie się programu, o ile system nie przeznaczył programowi tak niskiego adresu pamięci. Inna sprawa, gdy programujesz bezpośrednio urządzenie. Tam wolno Ci nieco więcej i taka konstrukcja może po prostu przejść. Niemniej jednak, w tym podręczniku taka konstrukcja jest zdecydowanie _niezalecana_, gdyż posługiwanie się nią wymaga dość dużej wiedzy i wykracza poza ramy kursu podstawowego. --Kj 21:47, 21 sty 2010 (CET)[odpowiedz]
  • Możliwe, że miałeś na myśli jeszcze coś innego:
int *z;
*z = 2;

W tym przypadku jest to coś zbliżonego do tego, co opisałeś, tzn. przypisane liczby pod losowy obszar pamięci (nie koniecznie obszar pamięci danych programu). Chociaż nie widzę związku z poprzednią dyskusją. --Lethern 23:56, 21 sty 2010 (CET)[odpowiedz]

Błędy w wersji PDF![edytuj]

Znalazłem następujące błędy w wersji PDF:
-na stronie 46 w dziale "Operacje bitowe" jest "negacja bitowa (“ ”),", a powinno być "negacja bitowa (“~”)," oraz "alternatywa bitowa (“—”) i", a powinno być "alternatywa bitowa (“|”) i"
-na stronie 51 w dziale "Inne operatory" jest "operator “” opisany przy okazji opisywania tablic;", a powinno być "operator “[]” opisany przy okazji opisywania tablic;"
--Pwl (dyskusja) 21:12, 23 paź 2010 (CEST)[odpowiedz]

operator przesunięcia[edytuj]

"Skasowałem opis związany z interpretacją działania tego operatora jako dzielenie/mnożenie przez 2)" Czy ta interpretacje jest nieprawidłowa ? Jeśli nie to ja proszę o pozostawienie tego punktu. --Adam majewski (dyskusja) 10:34, 4 cze 2016 (CEST)[odpowiedz]

Przesunięcie bitowe w prawo[edytuj]

Przesunięcie w prawo oznacza przemieszczenie wszystkich bitów argumentu w prawo o określoną liczbę miejsc oraz powielenie najstarszego bitu na skrajnej lewej pozycji.

Czy to zdanie na pewno jest poprawne? Z tego co mi wiadomo przesunięcie bitowe w prawo powoduje pojawienie się zer na skrajnej lewej pozycji. Później jest podany taki przykład:

printf ("6 >> 2 = %d\n", a>>2);  /* wypisze 1 */

Gdyby było jak autor twierdzi, to wynikiem 6 >> 2 nie byłoby 1 a 7. Nie wiem jak w tym przypadku działa zwykły int (ze znakiem), więc mogę się mylić.


"Przesunięcia w prawo. Operator prawy shift powoduje, że wzorzec bitowy w shift-expression lekkie po prawej stronie przez liczbę pozycji określoną przez additive-expression. W przypadku liczb bez znaku, pozycje bitów, które zostały zwolnione w wyniku operacji przesunięcia, są wypełniane przez zera. W przypadku liczb ze znakiem, bit znaku jest używany do wypełniania opuszczonych pozycji bitów. Innymi słowy, jeśli liczba jest dodatnia, używane jest 0, a jeśli liczba jest ujemna, używane jest 1." [1]

HTH --Adam majewski (dyskusja) 16:55, 29 paź 2017 (CET)[odpowiedz]

Operacje_bitowe[edytuj]

Witam,

operacje bitowe nie mają przykładowego programu. Próbowałem, ale wcale nie jest to łatwe. Poproszę o pomoc

#include <stdio.h>

/*     
https://stackoverflow.com/questions/699968/display-the-binary-representation-of-a-number-in-c
Chris Lutz
*/
void PrintBitsOfUChar(unsigned char v) {
  int i; // for C89 compatability
  for(i = 7; i >= 0; i--) putchar('0' + ((v >> i) & 1));
}



void TestBitwiseNot (unsigned char a ){

	printf ("decimal number  a = %3u;\t ", a );
	printf ("it's binary expansion = ");
	PrintBitsOfUChar(a);
	printf("\n"); 
	printf ("decimal number ~a = %3u;\t ", (unsigned char) ~a );
	printf ("it's binary expansion = ");
	PrintBitsOfUChar((unsigned char) ~a);
	printf("\n"); 
	
}






int main ()
{
 //unsigned char a;
 //char buffer[8];
 
 printf("unsigned char	has size = 1 byte = 8 bits and range from 0 to 255\n\n");
 
 TestBitwiseNot(0);
 TestBitwiseNot(255);
 TestBitwiseNot(5);
 TestBitwiseNot(3);
    
 
 return 0;
}

Wynik :

gcc b.c -Wall
./a.out
unsigned char	has size = 1 byte = 8 bits and range from 0 to 255

decimal number  a =   0;	 it's binary expansion = 00000000
decimal number ~a = 255;	 it's binary expansion = 11111111
decimal number  a = 255;	 it's binary expansion = 11111111
decimal number ~a =   0;	 it's binary expansion = 00000000
decimal number  a =   5;	 it's binary expansion = 00000101
decimal number ~a = 250;	 it's binary expansion = 11111010
decimal number  a =   3;	 it's binary expansion = 00000011
decimal number ~a = 252;	 it's binary expansion = 11111100

W tabeli są używane 4 bitowe liczby, c nie ma takiego typu TIA --Adam majewski (dyskusja) 19:35, 9 gru 2018 (CET)[odpowiedz]

  1. msdn.microsoft : Operatory przesunięcia w lewo i w prawo