LINUX.ORG.RU

Си


2

4
#include <stdlib.h>
#include <stdio.h> 

int main(int argc, char *argv[]) {

char *num = «5555»; 	
	
	if (argc != 2) {
	printf(«No param\n»);
		exit(0);
	}
	
	if (argv[1] != num) {
	printf(«Fail num %s\n»,num);
	printf(«Fail arg %s\n»,argv[1]);
		exit(0);
	}

...
}

Подскажите, почему сравниваются два одинаковых значения, но определяются, как - неодинаковые!

Вывод программы:

Fail num 5555
Fail arg 5555

Сравниваются адреса массивов символов. Почитай какой-нибудь учебник по Си.

tailgunner ★★★★★ ()

Патамушта num у тебя — указатель на char*, и сравнение его с указателем на первый аргумент, переданный в main заведомо бессмысленно. Делай так:

if(strcmp(num, argv[1]) == 0)
{/* Is equal */
...
}
one_more_hokum ★★★ ()

Потому что это C, а не йава! Welcome!

nanoolinux ★★★★ ()

Платиновые треды ЛОРа.

Deleted ()
Ответ на: комментарий от Anon

Да ладно, типичная ошибка начинающего, все так делали в своё время

Gvidon ★★★★ ()
Ответ на: комментарий от Gvidon

Все зависит от того, с какого языка "все" начинали ☺

Anon ()
Ответ на: комментарий от Gvidon

все так делали в своё время

вот не надо. Говори за себя. Так делали только криворукие ламеры, которые не читали и не думали перед тем как писать.

Bad_ptr ★★★★ ()
Ответ на: комментарий от nanoolinux

В йаве тоже ошибка будет, референсы же разные.

PolarFox ★★★★★ ()

потому что ты писал на жабе и не в курсе, что с С и С++ указатель - это именно что указатель, который может показывать хоть на луну. это число такое размером с long

ckotinko ☆☆☆ ()
Ответ на: комментарий от ckotinko

Сколько в этом треде людей, не знающих жабу >_<

new String("hello") == new String("hello")

будет false, т.к. ссылки на разные объекты.

PolarFox ★★★★★ ()

потому что num это {'5','5','5','5','\0'}

а то что в буфере stdio это {'5','5','5','5',\n','\0'}

Строки тупо разной длинны.

blogdron ()
Ответ на: комментарий от PolarFox

Сколько в этом треде людей, не знающих жабу >_<

+1

а ты сабж читал?

emulek ()
Ответ на: комментарий от nanoolinux

Да, чёрт. Но я не йавист, мне простительно.

Следующий раз пиши c#, точно не ошибёшься.

anonymous ()
Ответ на: комментарий от Bad_ptr

Ну, "hello" == "hello" будет true и в це, если компилятор умнее табуретки.

PolarFox ★★★★★ ()
Последнее исправление: PolarFox (всего исправлений: 1)
Ответ на: комментарий от blogdron

Строки тупо разной длинны.

ещё один... Тут не строки сравниваются, а их адреса. В строках может быть и одно и тоже, а вот адрес argv[1] явно другой, не такой, как у char *num. Этот быдлокод всегда будет говорить «не равно». Ну кроме случая, когда тупо рухнет, ибо вообще говоря, сравнивать (т.е. вычитать) указатели на разные массивы это UB.

emulek ()
Ответ на: комментарий от PolarFox

А тот, кто такое написал - дураком, ибо ничего подобного в стандарте нету.

nanoolinux ★★★★ ()

strcmp тебе в помощь

bvn13 ★★★★★ ()
Ответ на: комментарий от nanoolinux
int main() {
    char* a = "hello";
    char* b = "hello";
    if (a == b) {
        printf("Bam!\n");
    }
}

Можешь скомпилировать сам и проверить. В gcc срабатывает, в tcc, естественно, нет.

PolarFox ★★★★★ ()
Ответ на: комментарий от ckotinko

Да уж, не зря мне Go в последнее время нравится всё больше и больше. ;)

$ cat test.go
package main

import "fmt"

const str1 = "abrakadabra"
const str2 = "not abrakadabra"

func main() {
	if str1 == str2[4:] {
		fmt.Println("Mama-mia!")
	}
}
$ go run test.go
Mama-mia!
$

UPD: поправил, для чистоты эксперимента.

beastie ★★★★★ ()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от PolarFox

Ну, «hello» == «hello» будет true и в це, если компилятор умнее табуретки.

а сам ты как? Мой пишет

t.c:3:16: предупреждение: comparison with string literal results in unspecified behavior [-Waddress]
  return "true" == "true";
перевод нужен? ОК, только не обижайся: «автор == быдлкодер».

emulek ()
Ответ на: комментарий от emulek

Фе, это всего лишь варнинг. Главное что компилится же и даже иногда работает.

PolarFox ★★★★★ ()
Ответ на: комментарий от nanoolinux

Потому что это C, а не йава! Welcome!

Угу, в жабе даже 5555 == 5555 может дать False.

Miguel ★★★★★ ()
Ответ на: комментарий от nanoolinux

А тот, кто такое написал - дураком, ибо ничего подобного в стандарте нету.

есть. UB называется. Про «дураком» — согласен.

emulek ()
Ответ на: комментарий от Miguel

Угу, в жабе даже 5555 == 5555 может дать False.

Да ладно? Пример в студию!

anonymous ()
Ответ на: комментарий от Gvidon

под «все» ты конечно же подразумеваешь каких то деградантов?

x0r ★★★★★ ()
Ответ на: комментарий от PolarFox

Фе, это всего лишь варнинг.

Не могу понять: ты так пытаешься шутить или и в самом деле не в курсе, что там происходит и почему это иногда работает?

beastie ★★★★★ ()
Ответ на: комментарий от PolarFox

Фе, это всего лишь варнинг.

за ЭТОТ варниг бьёт канделябрами по голове. Ибо UB.

Главное что компилится же и даже иногда работает.

а КАК оно работает тебя конечно не волнует?

emulek ()
Ответ на: комментарий от emulek

А теперь сделай, как написано в исходном соообщении, т.е. через константные указатели

Gvidon ★★★★ ()
#include <stdlib.h>
#include <stdio.h> 

int main(int argc, char *argv[]) {

char *num = "5555"; 	
	
	if (argc != 2) {
	printf("No param\n");
		exit(0);
	}
	
	if (argv[1] != num) {
	printf("Fail num %s\n",num);
	printf("Fail arg %d\n",argv[1]);
		exit(0);
	}

  return 0;
 }
dron@nix:~$ gcc  '/test.c' ; ./a.out
No param
blogdron ()
Ответ на: комментарий от beastie

Я знаю как там изнутри это работает (компилятор видит 2 одинаковых строковых константы и размещает их один раз в одной области памяти, соответственно у них одинаковый адрес).

А про варнинг: если явно ошибочная строчка выдаёт всего лишь варнинг, то рано или поздно она попадёт в кодовую базу крупного проекта.

PolarFox ★★★★★ ()
Ответ на: комментарий от emulek

Кто бьёт? Компилятор не бьёт, если -Werror=all не стоит.

PolarFox ★★★★★ ()
Ответ на: комментарий от PolarFox

А на хрена сравнивать заведомо разные значения адресов?

int main() {
    char* a = "hello";
    char* b = "hello";
    if (*a == *b) {
        printf("Bam!\n");
    }
}
blogdron ()
Ответ на: комментарий от Gvidon

А теперь сделай, как написано в исходном соообщении, т.е. через константные указатели

1. никаких const в первом посте нет.

2. я и так вижу, что это быдлокод и UB. ТСу срочно прописываю man 3 strcmp, а тебе — живительную эфтаназию.

emulek ()
Ответ на: комментарий от emulek

Что UB? Сравнение двух указателей? И давно это у вас?

Gvidon ★★★★ ()
Ответ на: комментарий от PolarFox

Кто бьёт?

да первый же встреченный тобой программист, который действительно знает C, и имеет хоть какой-то опыт отладки кода(особенно чужого). Уж поверь мне на слово, он тебя уже ЛЮТО, БЕШЕНО НЕНАВИДИТ, ибо таких как ты — 95%.

emulek ()
Ответ на: комментарий от Gvidon

Что UB? Сравнение двух указателей? И давно это у вас?

оно, да, ЕМНИП с первого стандарта, если не с K&R.

Арифметические действия допустимы только с указателями на один и тот же массив, включая ещё и указатель на эл-т за последним эл-том этого массива. Всякие <,>,== это тоже арифметика.

emulek ()
Ответ на: комментарий от emulek

за ЭТОТ варниг бьёт канделябрами по голове. Ибо UB.

почему? цитату из стандарта можно?

alex_custov ★★★★★ ()
Ответ на: комментарий от emulek

Я тут на быдлохабре автору некоей PVS-studio сказал, что -Wall -Werror спасут от 99% случаев, в которых его "студия" используется, мягко намекнув на ненужность сего продукта. А он обиделся и начал что-то доказывать.

Anon ()
Ответ на: комментарий от emulek

ЗЫЖ особенно опасно это тем, что компилятор только в простых случаях может это увидеть. Если-бы сравнивались простые указатели, то компилятор-бы этого не заметил, но UB осталось, и рано или поздно выстрелило.

emulek ()
Ответ на: комментарий от PolarFox

Я понял, что нужно использовать strcmp ...

Кстати, работает и так:

if (printf("%s",argv[1]) != printf("%s",num))

печатает на вывод только ) ...

Изучаю язык, поэтому прошу не оскорблять. Если вопросы кажутся «тупыми» - просьба промолчать ....

Еще вопрос по указателям: по идее должно быть равно так:

if ((*argv[1])) != (*num))

anonymus123 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.