Portál AbcLinuxu, 1. května 2025 00:44

Side Effects of C Macros

11.3.2017 20:27 | Přečteno: 1146× | Ostatní | poslední úprava: 11.3.2017 20:38

After typing Ctrl-D the fgets() function will read EOF and the program will be terminated.
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define myupper(c)	((c) >= 'A' && (c) <= 'Z')

enum {
	MAX = 100
}; 

int main()
{	
	int uppermacro(char *str);
	int ctypefun(char *str);
	
	
	char str[MAX];
	int nupper;	
	
	while (fgets(str, MAX, stdin) != NULL) {
	
		if (str[strlen(str) - 1] == '\n')
			str[strlen(str) - 1] = '\0';
	
		nupper = uppermacro(str); 
		printf("upper macro: %d\n", nupper);
	
		nupper = ctypefun(str);
		printf("ctype function: %d\n", nupper);
	}
	
	return 0;
}

int uppermacro(char *str)
{
	int nupper = 0;
	
	while (*str != '\0')	{
		if (myupper(*str++))	
			nupper++;		
	}
	
	return nupper;	
}	

int ctypefun(char *str)
{
	int nupper = 0;
	
	while (*str != '\0')	{
		if (isupper(*str++))
			nupper++;		
	}
	
	return nupper;	
}

        /* 
	while (myupper(c = getchar())) ...	ERROR
	while (isupper(c = getchar())) ...	WORKS
	while ((c = getchar()) != EOF &&
	isupper(c)) ... 			SAFER
	*/
Takový blog sem ještě patří?        

Hodnocení: 17 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře. , Tisk

Vložit další komentář

⧠ A = 0 avatar 11.3.2017 20:43 ⧠ A = 0 | skóre: 11 | blog: Technokratovo_zrcadlo | Helsinki
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Odpovědět | Sbalit | Link | Blokovat | Admin
А какой же это блог?
Nevolte zmrdy.
11.3.2017 21:34 Dušan Kreheľ | skóre: 9 | blog: krehel_sk___informovat_o_novych_verziach_softveru | Prešov
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Definície (lokalných) funkcií nedefinuj v main(), ale mimo main(), pred definície globalných premenných.

Píš štylom, že main() funkcia je ako posledná v zdrojáku, alebo na konci je posledná najdôležitejšia funkcia v zdrojáku, ak sa tam nenachádza funkcia main.

Tá podmienka if je zbytočná:
if (str[strlen(str) - 1] == '\n')
   str[strlen(str) - 1] = '\0';
Lebo:
fgets()  reads in at most one less than size characters from stream and
       stores them into the buffer pointed to by s.
echo -e "123456"|./check_end_fgets 
49 '1'
50 '2'
51 '3'
0 ''
Testovací kód:
#include <stdio.h>
#include <stdlib.h>

void check_end_fgets()
{
	char buffer[4];
	int a;
	char *p;
	
	if(fgets(buffer, 4, stdin) == NULL)
		return;
	
	for(p=buffer,a=0;a<4 && *p != '\n'; a++,p++)
		printf("%d '%c'\n", *p, *p);
	
}

int main(void)
{
	check_end_fgets();
	return 0;
}
11.3.2017 21:52 Dušan Kreheľ | skóre: 9 | blog: krehel_sk___informovat_o_novych_verziach_softveru | Prešov
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Máš chybu:
echo "LLLLLLLLLLLLLL"|./cod
upper macro: 7
ctype function: 14
Oprav si chybu vo funkcií uppermacro().
12.3.2017 07:38 sad
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Tu chybu jsem tam udělal schválně. Jedná se o srovnání dvou stejných funkcí, které vrací počet velikých písmen s tím rozdílem, že jedna používá vlastní makro myupper() a druhá funkci isupper() ze standardní knihovny.

Problém je v tom, že se ta dekrementace do makra přenese dvakrát:
((*str++) >= 'A' && (*str++) <= 'Z')
12.3.2017 07:39 sad
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Inkrementace.
12.3.2017 09:17 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Proto je např. v manuálové stránce ke getc() upozornění, že na rozdíl od fgetc() může být implementována jako makro, které argument vyhodnocuje víc než jednou.
12.3.2017 09:54 sad
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Tak to jsem nevěděl. Díky za upozornění.
11.3.2017 21:26 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Odpovědět | Sbalit | Link | Blokovat | Admin
Hodil by se k tomu nejaky komentar...
Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
11.3.2017 21:57 Dušan Kreheľ | skóre: 9 | blog: krehel_sk___informovat_o_novych_verziach_softveru | Prešov
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Pozri komentár na konci zdrojáku.
12.3.2017 11:08 Dušan Kreheľ | skóre: 9 | blog: krehel_sk___informovat_o_novych_verziach_softveru | Prešov
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Poznáš príkaz:
cpp source.c -o source_cpp.h
12.3.2017 13:02 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Ano, znam preprocesor i jeho ulohu a to do te miry, abych vedel, ze vystupem preprocesoru neni hlavickovy soubor, ale soubor ciste v jazyce C.

Jinak ma poznamka se tykala toho, ze bez dalsiho komentare je ten clanek zbytecny. Trochu zkuseny programator na prvni pohled vidi, v cem je problem. Zacatecnikovi to moc nerekne a ani nevi, jak se z toho poucit pri psani maker.
Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
11.3.2017 23:48 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Odpovědět | Sbalit | Link | Blokovat | Admin
#define myupper(c) ((c) >= 'A' && (c) <= 'Z')

se dá nahradit něčim jako

#define myupper(c) ((unsigned long)(c - 'A') <= 'Z' - 'A')

(ale je to trochu prasárna)
SPD vůbec není proruská
12.3.2017 02:30 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Odpovědět | Sbalit | Link | Blokovat | Admin
C makra? Tohle byla taky vtipná situace. Stringifikace jména argumentu pro vnitřní makro :-D.
Intel meltdown a = arr[x[0]&1]; karma | 帮帮我,我被锁在中国房
13.3.2017 19:48 Odin1918 | skóre: 6 | blog: Valhalla
Rozbalit Rozbalit vše Re: Side Effects of C Macros
Odpovědět | Sbalit | Link | Blokovat | Admin
Pouzivat makra na toto je antipattern a stejne tak je antipattern inkrementovat argument v ramci volani procedury, ktera je v tomto pripade jeste k tomu makrem. Vede to k errorprone kodu, ktery se neda cist. Vice radek muze byt nekdy citelnejsi.

Založit nové vláknoNahoru

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.