Вопросы и ответы по программированию.

Для тех, кто хочет сделать мир лучше.
Сообщение
Автор
Аватара пользователя
nikit-xxx
Лейтенант
Лейтенант
Сообщения: 208
Зарегистрирован: 28.11.2007
Благодарил (а): 44 раза
Поблагодарили: 5 раз

#151 Сообщение 20.10.2011, 17:18

нужна помощь по примеру 5.11 из K&R
Скрытое содержимое

Код: Выделить всё

#include <stdio.h>
#include <string.h>

#define MAXLINES 5000	//max число строк
char *lineptr[MAXLINES]; //Указатели на строки

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
		int(*comp)(void *, void *));
int numcp(char *, char *);

/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
	int nlines;//кол-во считанных строк
	int numeric = 0; //1 если числовая сортировка

	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
		qsort_((void **) lineptr, 0, nlines-1,
				(int (*)(void *, void *))(numeric ? numcp : strcmp));//указатель на функцию вида int function(void *, void *); к function присвоится numcp либо strcmp
		writelines(lineptr, nlines);
		return 0;
	}else{
		printf("input too big to sortn");
		return 1;
	}
}
/////////////////////////
/////////////////////////
/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
		int (*comp)(void *, void *))
{
	int i, last;
	void swap(void *v[], int i, int j);

	if (left >= right)	//ничего не делать, если в массиве
		return;			//меньше двух элементов
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left+1; i<= right; i++)
		if((*comp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort_(v, left, last-1, comp);
	qsort_(v, last+1, right, comp);
}

#include <stdlib.h>
/*numcp: сравнение строк s1 и s2  по числовым значениям*/
int numcp(char *s1, char *s2)
{
	double v1, v2;

	v1 = atof(s1);
	v2 = atof(s2);
	if (v1 < v2)
		return -1;
	else if (v1 > v2)
		return 1;
	else
		return 0;
}

void swap(void *v[], int i, int j)
{
	void *temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);

/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
	int len, nlines;
	char *p, line[MAXLEN];

	nlines = 0;
	while ((len = getline(line, MAXLEN)) >0)
		if(nlines >= maxlines || (p = alloc(len)) == NULL)
			return -1;
		else {
			line[len-1] = '\0';/*удаление конца строки*/
			strcpy(p, line);
			lineptr[nlines++] = p;
		}
	return nlines;
}

/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
	int i;

	for(i = 0; i< nlines; i++)
		printf("%sn", lineptr[i]);
}

/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
	int c, i;

	for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='n'; ++i)
		s[i] = c;
	if (c == 'n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	return i;
}

#define ALLOCSIZE 10000 //объём имеющейся памяти

static char allocbuf[ALLOCSIZE]; //буфер памяти для alloc
static char *allocp = allocbuf; //Следующая свободная позиция

char *alloc(int n) //возвращает указатель на n символов
{
	if (allocbuf + ALLOCSIZE - allocp >= n) { //есть место
		allocp += n;
		return allocp - n; //старый p
	} else //недостаточно места в буфере
		return 0;
}
первую проблему "уже определена ф-я qsort();" я решил переименованием в qsort_(),
сейчас компилятор выдаёт

Код: Выделить всё

Examples 35.11.c||In function 'main':|
Examples 35.11.c|23|warning: pointer type mismatch in conditional expression|
||=== Сборка закончена: 0 ошибок, 1 предупреждений ===|
я не понимаю, где/почему в 23-ей строке компилятор находит несоответствие типов, и не совсем понимаю как в этой строке работает в 4-ом аргументе qsort_ конструкция

qsort_((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(numeric ? numcp : strcmp));

в частности скобки ()(), выделенные розовым, где можно посмотреть подробнее про этот приём?

Насколько я понял, в 4-й аргумент qsort_ пойдёт в зависимости от истинности numeric указатель на numcp или strcmp, но тогда зачем прописывать тип возвращаемого значения и аргументы функции, на которую указывает этот указатель ?

Объясните плз чтобы нубу понятно было.

P. S. компилятор gcc-4.4.1., среда Code::Blocks 10.5

Добавлено спустя 2 часа 20 минут 20 секунд:
путь ложный, не смотреть

Код: Выделить всё

qsort_((void **) lineptr, 0, nlines-1,
				(int (*)(void *, void *))(numeric ? numcp : strcmp));
Заменил на это (так вообще можно делать???)

Код: Выделить всё

if(numeric){
	qsort_((void **) lineptr, 0, nlines-1, *numcp);
}else{
	qsort_((void **) lineptr, 0, nlines-1, *strcmp);
}
но компилятор всёравно ругается

Код: Выделить всё

\Examples 3\5.11 new fix by me.c||In function 'main':|
\Examples 3\5.11 new fix by me.c|25|warning: passing argument 4 of 'qsort_' from incompatible pointer type|
\Examples 3\5.11 new fix by me.c|9|note: expected 'int (*)(void *, void *)' but argument is of type 'int (*)(char *, char *)'|
\Examples 3\5.11 new fix by me.c|27|warning: passing argument 4 of 'qsort_' from incompatible pointer type|
\Examples 3\5.11 new fix by me.c|9|note: expected 'int (*)(void *, void *)' but argument is of type 'int (*)(const char *, const char *)'|
||=== Сборка закончена: 0 ошибок, 2 предупреждений ===|
то есть по какой-то причине разрабы GCC запретили обобщение указателя при помощи void*
Последний раз редактировалось nikit-xxx 20.10.2011, 18:51, всего редактировалось 1 раз.
Откуда иксы в моём нике
Изображение
Изображение
скачать С. Прата. Язык программирования C++. Лекции и упражнения. 5-е изд (*Выровнена нумерация страниц, *Содержание)
Краткая инструкция по созданию пиратки-распака CS/HL
Изображение
Использование тэга подсветки синтаксиса
[syntax lang="cpp" lines="n"]
#include <iostream>
using namespace std;

struct cl{
static void f() { cout << "Hi, user!\n"; }
int i;
};

int main()
{
cl::f();
//cl::i = 1;
return 0;
}
[/syntax]

Аватара пользователя
Pr0Ger
Модератор
Модератор
Сообщения: 1829
Зарегистрирован: 16.01.2009
Благодарил (а): 17 раз
Поблагодарили: 214 раз
Контактная информация:

#152 Сообщение 20.10.2011, 18:23

nikit-xxx писал(а):но тогда зачем прописывать тип возвращаемого значения и аргументы функции, на которую указывает этот указатель ?
numcp имеет тип int(*)(char*, char*), а strcmp int(*)(const char*, const char*)
а то время как qsort хочет int(*)(void*, void*)
поэтому и нужно сначала приведение типов сделать

Аватара пользователя
nikit-xxx
Лейтенант
Лейтенант
Сообщения: 208
Зарегистрирован: 28.11.2007
Благодарил (а): 44 раза
Поблагодарили: 5 раз

#153 Сообщение 20.10.2011, 18:56

Pr0Ger
спасибо, теперь картина проясняется: первая пара розовых скобок -- приведение типов выражения, которое получится во второй паре розовых скобок.

Собственно, как теперь найти общий язык с компилятором, чтобы он понял что в 23-ей строке требуется сделать приведение типов, и не ругался на неё?
Пробовал запускать компилятор с флагом -ansi, т. к. сие присутствует в названии книжки, но всё равно выдаёт то же предупреждение "warning: pointer type mismatch in conditional expression"
nikit-xxx писал(а):по какой-то причине разрабы GCC запретили обобщение указателя при помощи void*
это верно?
Откуда иксы в моём нике
Изображение
Изображение
скачать С. Прата. Язык программирования C++. Лекции и упражнения. 5-е изд (*Выровнена нумерация страниц, *Содержание)
Краткая инструкция по созданию пиратки-распака CS/HL
Изображение
Использование тэга подсветки синтаксиса
[syntax lang="cpp" lines="n"]
#include <iostream>
using namespace std;

struct cl{
static void f() { cout << "Hi, user!\n"; }
int i;
};

int main()
{
cl::f();
//cl::i = 1;
return 0;
}
[/syntax]

Аватара пользователя
Pr0Ger
Модератор
Модератор
Сообщения: 1829
Зарегистрирован: 16.01.2009
Благодарил (а): 17 раз
Поблагодарили: 214 раз
Контактная информация:

#154 Сообщение 20.10.2011, 19:43

nikit-xxx
вбил бы чей ошибку в гугл, первая ссылка на stackoverflow, где как раз вопрос про этот пример, откуда идет ссылка на другой вопрос, где как раз есть ответ, с объяснением

MOZGIII
Разработчик
Разработчик
Сообщения: 910
Зарегистрирован: 09.01.2009
Откуда: Переезжаю в /dev/null
Благодарил (а): 7 раз
Поблагодарили: 65 раз
Контактная информация:

#155 Сообщение 21.10.2011, 01:29

nikit-xxx
Замени всю строку на:

Код: Выделить всё

(numeric ? (int (*)(void *, void *))numcp : (int (*)(void *, void *))strcmp));
Кеп? %)
Компилятор не понимает что ты хочешь сделать, т.к. ( ... ? ... : ... ) - он вообще не знает что эта штука будет возвращать - она не типизированная. От этого и варнинг (у меня, gcc version 4.5.2 (GCC), тоже mingw, правда с моими примочками).

PS: дада, наконец-то, теперь я шарю и в сях xD

Аватара пользователя
nikit-xxx
Лейтенант
Лейтенант
Сообщения: 208
Зарегистрирован: 28.11.2007
Благодарил (а): 44 раза
Поблагодарили: 5 раз

#156 Сообщение 21.10.2011, 11:04

фикс вариант 1

Код: Выделить всё

#include <stdio.h>
#include <string.h>

#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
		int(*comp)(void *, void *));
int numcp(const char *, const char *);

/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
	int nlines; /*кол-во считанных строк*/
	int numeric = 0; /*1 если числовая сортировка*/

	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
		qsort_((void **) lineptr, 0, nlines-1,
				(int (*)(void *, void *))(numeric ? numcp : strcmp));
		writelines(lineptr, nlines);
		return 0;
	}else{
		printf("input too big to sort\n");
		return 1;
	}
}


/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
		int (*comp)(void *, void *))
{
	int i, last;
	void swap(void *v[], int i, int j);

	if (left >= right)	/*ничего не делать, если в массиве*/
		return;			/*меньше двух элементов*/
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left+1; i<= right; i++)
		if((*comp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort_(v, left, last-1, comp);
	qsort_(v, last+1, right, comp);
}

#include <stdlib.h>
/*numcp: сравнение строк s1 и s2  по числовым значениям*/
int numcp(const char *s1, const char *s2)
{
	double v1, v2;

	v1 = atof(s1);
	v2 = atof(s2);
	if (v1 < v2)
		return -1;
	else if (v1 > v2)
		return 1;
	else
		return 0;
}

void swap(void *v[], int i, int j)
{
	void *temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);

/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
	int len, nlines;
	char *p, line[MAXLEN];

	nlines = 0;
	while ((len = getline(line, MAXLEN)) >0)
		if(nlines >= maxlines || (p = alloc(len)) == NULL)
			return -1;
		else {
			line[len-1] = '\0';/*удаление конца строки*/
			strcpy(p, line);
			lineptr[nlines++] = p;
		}
	return nlines;
}

/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
	int i;

	for(i = 0; i< nlines; i++)
		printf("%s\n", lineptr[i]);
}

/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
	int c, i;

	for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
		s[i] = c;
	if (c == '\n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	return i;
}

#define ALLOCSIZE 10000 /*объём имеющейся памяти*/

static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/

char *alloc(int n) /*возвращает указатель на n символов*/
{
	if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
		allocp += n;
		return allocp - n; /*старый p*/
	} else /*недостаточно места в буфере*/
		return 0;
}
фикс вариант 2

Код: Выделить всё

#include <stdio.h>
#include <string.h>

#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
		int(*comp)(const void *, const void *));
int numcp(const char *, const char *);

/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
	int nlines; /*кол-во считанных строк*/
	int numeric = 0; /*1 если числовая сортировка*/

	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
		qsort_((void **) lineptr, 0, nlines-1,
				(int (*)(const void *, const void *))(numeric ? numcp : strcmp));
		writelines(lineptr, nlines);
		return 0;
	}else{
		printf("input too big to sort\n");
		return 1;
	}
}


/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
		int (*comp)(const void *, const void *))
{
	int i, last;
	void swap(void *v[], int i, int j);

	if (left >= right)	/*ничего не делать, если в массиве*/
		return;			/*меньше двух элементов*/
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left+1; i<= right; i++)
		if((*comp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort_(v, left, last-1, comp);
	qsort_(v, last+1, right, comp);
}

#include <stdlib.h>
/*numcp: сравнение строк s1 и s2  по числовым значениям*/
int numcp(const char *s1, const char *s2)
{
	double v1, v2;

	v1 = atof(s1);
	v2 = atof(s2);
	if (v1 < v2)
		return -1;
	else if (v1 > v2)
		return 1;
	else
		return 0;
}

void swap(void *v[], int i, int j)
{
	void *temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);

/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
	int len, nlines;
	char *p, line[MAXLEN];

	nlines = 0;
	while ((len = getline(line, MAXLEN)) >0)
		if(nlines >= maxlines || (p = alloc(len)) == NULL)
			return -1;
		else {
			line[len-1] = '\0';/*удаление конца строки*/
			strcpy(p, line);
			lineptr[nlines++] = p;
		}
	return nlines;
}

/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
	int i;

	for(i = 0; i< nlines; i++)
		printf("%s\n", lineptr[i]);
}

/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
	int c, i;

	for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
		s[i] = c;
	if (c == '\n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	return i;
}

#define ALLOCSIZE 10000 /*объём имеющейся памяти*/

static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/

char *alloc(int n) /*возвращает указатель на n символов*/
{
	if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
		allocp += n;
		return allocp - n; /*старый p*/
	} else /*недостаточно места в буфере*/
		return 0;
}
фикс вариант от MOZGIII

Код: Выделить всё

#include <stdio.h>
#include <string.h>

#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
		int(*comp)(void *, void *));
int numcp(char *, char *);

/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
	int nlines; /*кол-во считанных строк*/
	int numeric = 0; /*1 если числовая сортировка*/

	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
		qsort_((void **) lineptr, 0, nlines-1,
				numeric ? (int (*)(void *, void *))numcp : (int (*)(void *, void *))strcmp);
		writelines(lineptr, nlines);
		return 0;
	}else{
		printf("input too big to sort\n");
		return 1;
	}
}


/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
		int (*comp)(void *, void *))
{
	int i, last;
	void swap(void *v[], int i, int j);

	if (left >= right)	/*ничего не делать, если в массиве*/
		return;			/*меньше двух элементов*/
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left+1; i<= right; i++)
		if((*comp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort_(v, left, last-1, comp);
	qsort_(v, last+1, right, comp);
}

#include <stdlib.h>
/*numcp: сравнение строк s1 и s2  по числовым значениям*/
int numcp(char *s1, char *s2)
{
	double v1, v2;

	v1 = atof(s1);
	v2 = atof(s2);
	if (v1 < v2)
		return -1;
	else if (v1 > v2)
		return 1;
	else
		return 0;
}

void swap(void *v[], int i, int j)
{
	void *temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);

/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
	int len, nlines;
	char *p, line[MAXLEN];

	nlines = 0;
	while ((len = getline(line, MAXLEN)) >0)
		if(nlines >= maxlines || (p = alloc(len)) == NULL)
			return -1;
		else {
			line[len-1] = '\0';/*удаление конца строки*/
			strcpy(p, line);
			lineptr[nlines++] = p;
		}
	return nlines;
}

/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
	int i;

	for(i = 0; i< nlines; i++)
		printf("%s\n", lineptr[i]);
}

/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
	int c, i;

	for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
		s[i] = c;
	if (c == '\n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	return i;
}

#define ALLOCSIZE 10000 /*объём имеющейся памяти*/

static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/

char *alloc(int n) /*возвращает указатель на n символов*/
{
	if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
		allocp += n;
		return allocp - n; /*старый p*/
	} else /*недостаточно места в буфере*/
		return 0;
}
Pr0Ger, MOZGIII, спасибо, теперь у меня есть 3 варианта, в которых компилятор не ругается, 2-й более-менее понятен.

Не ясно, почему, если функции qsort_(); в 4-м аргументе нужен указатель comp такого вида int(*comp)(void *, void *), и мы приводим его к этому виду, но
если одна из приводимых функций strcmp(const char *, const char *); а другая numcp(char *, char *); то компилятор ругается,
а если же обе таковы strcmp(const char *, const char *); numcp(const char *, const char *); то компилится нормально(1-й вариант).

MOZGIII
вообще не знает что эта штука будет возвращать - она не типизированная
в исходном варианте её пытаются привести к нужному типу (int (*)(void *, void *)), но почему-то это компилятор считает неправильным


Не пойму разницу [с точки зрения компилятора]

Код: Выделить всё

(int (*)(void *, void *))(numeric ? numcp : strcmp) //исходный вар-т, 4-й аргумент: преобразовать к нужному типу указатель, полученный после условного оператора : ?

numeric ? (int (*)(void *, void *))numcp : (int (*)(void *, void *))strcmp //в 4-й аргумент направить уже преобразованный к нужному типу ук-ль
по смыслу вроде одинаковые вещи, в 1-м случае результат, получившийся после действия условного оператора приводится к нужному типу, а во 2-м аргументы условного оператора преобразуются к нужному типу.
Откуда иксы в моём нике
Изображение
Изображение
скачать С. Прата. Язык программирования C++. Лекции и упражнения. 5-е изд (*Выровнена нумерация страниц, *Содержание)
Краткая инструкция по созданию пиратки-распака CS/HL
Изображение
Использование тэга подсветки синтаксиса
[syntax lang="cpp" lines="n"]
#include <iostream>
using namespace std;

struct cl{
static void f() { cout << "Hi, user!\n"; }
int i;
};

int main()
{
cl::f();
//cl::i = 1;
return 0;
}
[/syntax]

Deus_Ex_Machina
Капитан
Капитан
Сообщения: 492
Зарегистрирован: 23.05.2010
Благодарил (а): 14 раз
Поблагодарили: 43 раза
Контактная информация:

#157 Сообщение 21.10.2011, 19:04

nikit-xxx
MOZGIII писал(а):Компилятор не понимает что ты хочешь сделать, т.к. ( ... ? ... : ... ) - он вообще не знает что эта штука будет возвращать - она не типизированная.
Компилятор на слово тебе верить не станет, вдруг то, что вернет ?:, нельзя будет привести к тому, что ты от него требуешь.

Аватара пользователя
nikit-xxx
Лейтенант
Лейтенант
Сообщения: 208
Зарегистрирован: 28.11.2007
Благодарил (а): 44 раза
Поблагодарили: 5 раз

#158 Сообщение 22.10.2011, 17:32

Спасибо всем ответившим, теперь понял так:
Компилятор ругается на шаге, когда просматривает типы(а они различаются) возможных результатов, которые может вернуть ? :, здесь он ещё не знает, что тип результата мы собираемся привести к нужному. То есть он защищает от ситуации, когда в зависимости от истинности/ложности проверочного_выражения мы бы получали результаты разных типов. Исходный вариант должен работать без ошибок(несмотря на warning), т. к. тип результата мы приводим к нужному.
Откуда иксы в моём нике
Изображение
Изображение
скачать С. Прата. Язык программирования C++. Лекции и упражнения. 5-е изд (*Выровнена нумерация страниц, *Содержание)
Краткая инструкция по созданию пиратки-распака CS/HL
Изображение
Использование тэга подсветки синтаксиса
[syntax lang="cpp" lines="n"]
#include <iostream>
using namespace std;

struct cl{
static void f() { cout << "Hi, user!\n"; }
int i;
};

int main()
{
cl::f();
//cl::i = 1;
return 0;
}
[/syntax]

Аватара пользователя
EvgenKo423
Нович0к
Нович0к
Сообщения: 9
Зарегистрирован: 05.04.2011
Откуда: Екатеринбург

#159 Сообщение 20.11.2011, 17:33

Доброго времени суток, господа кодеры. У меня следующий вопрос: как можно модифицировать библиотеку игры, чтобы из нее вызывалась функция из моей собственной библиотеки? Вообще как создатели эмулей модифицируют игровые библиотеки??
Everything that has a beginning has an end.
I had a dream of my wife. She was dead... but it was all right.

Deus_Ex_Machina
Капитан
Капитан
Сообщения: 492
Зарегистрирован: 23.05.2010
Благодарил (а): 14 раз
Поблагодарили: 43 раза
Контактная информация:

#160 Сообщение 21.11.2011, 19:36

Нужно написать свою библиотеку, где для нужных функций будут вызываться свои, а для остальных будет идти обращение к оригинальному длл.

Аватара пользователя
EvgenKo423
Нович0к
Нович0к
Сообщения: 9
Зарегистрирован: 05.04.2011
Откуда: Екатеринбург

#161 Сообщение 21.11.2011, 19:45

А библиотека че сама к игре подключится от того что я ее просто в папку закину?????
Наверно надо вызывать функции своей библиотеки из модифицированной игровой? Хотя бы одну.....
Everything that has a beginning has an end.
I had a dream of my wife. She was dead... but it was all right.

Аватара пользователя
Monk
VIP
VIP
Сообщения: 4713
Зарегистрирован: 21.11.2009
Благодарил (а): 418 раз
Поблагодарили: 1053 раза
Контактная информация:

#162 Сообщение 21.11.2011, 19:47

Заменяешь игровую DLL своей, а твоя уже адресует запросы реальной + творит твои темные дела. Любой чит на кс16 в целом думаю тебе поможет.
«По ночам компьютеры собираются вместе и смеются над людьми, если те делают работу, которую могли бы делать компьютеры» (с) habrahabr
 
[hide_num=64]Изображение
Изображение

Не стоит становиться на одно колено ради девушки, которая ради тебя не готова встать на два. (С)
640K ought to be enough for anybody (с) BG[/hide_num]

Аватара пользователя
EvgenKo423
Нович0к
Нович0к
Сообщения: 9
Зарегистрирован: 05.04.2011
Откуда: Екатеринбург

#163 Сообщение 24.11.2011, 21:18

Возникают какие-то странные ошибки.....
Я начал с простого:
1. Скачал последние реверсы библиотек стима (от 17 ноября)
2. Создал свою библиотеку steam_api.dll с простой перекрывающей функцией

Код: Выделить всё

S_API bool STEAM_CALL SteamAPI_InitSafe()
{
	printf("InitSafe called!!!");

	return true;
}
3. Заменил оригинал, получил "Точка входа в процедуру SteamAPI_GetSteamInstallPath не найдена в библиотеке DLL steam_api.dll"
4. Прописал функцию из ошибки в экспорт
steam_api.def:

Код: Выделить всё

LIBRARY "steam_api"

EXPORTS
SteamAPI_GetSteamInstallPath

5. Повторял пункты 3 и 4 пока не получил следующую странную ошибку при компиляции:

Код: Выделить всё

1>steam_api.def : error LNK2001: unresolved external symbol SteamAPI_UseBreakpadCrashHandler
1>E:\CSSServer\VoiDeD-open-steamworks-16ab5b54c3e3\Release\steam_api.lib : fatal error LNK1120: 1 unresolved externals
1>
1>Build FAILED.
И как мне это понимать??? :dash: Сервер запрашивает у меня функцию, которая описана в Steamclient.h, но почему-то отсутствует в реверсе steam_api.lib.......
Everything that has a beginning has an end.
I had a dream of my wife. She was dead... but it was all right.

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#164 Сообщение 27.11.2011, 08:15

EvgenKo423
Для правильной загрузки тебе надо описать не 1, а ВСЕ экспортируемые функции данной библиотеки.
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
EvgenKo423
Нович0к
Нович0к
Сообщения: 9
Зарегистрирован: 05.04.2011
Откуда: Екатеринбург

#165 Сообщение 27.11.2011, 18:05

Я про то, что в реверсе есть не все функции
Everything that has a beginning has an end.
I had a dream of my wife. She was dead... but it was all right.

Ответить Вложения 1