Я нашел эту загадку в газете способности C.
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
}
int main()
{
int i = 5;
change();
i = 10;
printf("%d", i);
return 0;
}
Любые решения.?
Вот Действительно Дешевый ответ:
void
change()
{
printf("%d", 5);
exit(0);
}
: - P
Вот другой:
void change()
{
#define printf(x,y) printf("5",x,y);
}
я получаю «наименьшего #define для решения глупой проблемы "?
Другой использует Microsoft Moles ( рамка изоляции для .NET ).
MDateTime.NowGet = () => new DateTime(2000, 1, 1);
-121--712024-Moles позволяет заменить любой .NET метод с делегатом. Опоры молей статические или невиртуальные методы. Родинки опирается на профилировщик из Pex.
Короткий ответ: Есть несколько сервисных компаний, которые продвигаются в этом направлении, но это сложный путь. Ваша способность продавать методологию и убеждать клиента в том, что вы можете поставить, будет высокой.
Клиенты не хотят рисковать оплатой решения, которое никогда не будет поставлено.
Типичными подходами к решению этой проблемы являются «не превышающие» затраты. Однако, если вы не можете контролировать область, вы принимаете на себя весь риск.
Короче говоря, вы ищете клиентов, которые подписались бы на контракты T & M (время и материалы) до того, как Agile стал последним увлечением (я являюсь частью этого увлечения, но это всего лишь один из длинной линейки процессов разработки. Аспекты его продолжат расти и некоторая его перестановка будет иметь другое название через несколько лет).
-121--1622680- Я подозреваю, что «правильным» ответом на это является изменение обратного адреса в стеке в функции change ()
, так что при возврате поток управления пропускает команду i = 10
и переходит непосредственно к printf
.
Если это так, то это ужасный, уродливый вопрос, и (не портативный) ответ требует знания архитектуры и набора команд.
Вот еще одна возможность:
void change()
{
char const *literal = "%d";
char * ptr = (char*)literal;
ptr[0] = '5';
ptr[1] = 0;
}
Это гораздо более портативное, чем изменение обратного адреса, но требует от вас (а) иметь компилятор, который объединяет строковые литералы (большинство), а также (B ) иметь компилятор, который не размещает константы в разрезе только для чтения, или работать на архитектуре без MMU (вряд ли в эти дни).
void change()
{
#define printf(x,y) fprintf(stdout,x,y-5)
}
У вас в стеке есть локальная переменная i, которая для начала имеет значение 5.
С помощью change() вам нужно изменить следующую инструкцию на 5, чтобы переопределение буфера было в том месте, где установлено 10, и чтобы оно было установлено в 5.
да, это безопасно.
-121--1477904- Yes -- free
принимает указатель на пустоту, поэтому при его вызове указатель (неявно) приводится к указателю на пустоту в любом случае.
Остальная часть вашего кода не очень безопасна:
void* p = (void*)malloc(sizeof(foo));
Вы должны не отбрасывать возврат из malloc (в C). Это может скрыть ошибку забывания # include < stdlib.h >
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
#define i a=5,b
}
определить?
#include <stdio.h>
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
#define printf_ printf
#define printf(a, b) printf_("5");
}
int main()
{
int i = 5;
change();
i = 10;
printf("%d", i);
return 0;
}
echo
- это не функция, а оператор языка. Он не может быть переопределен. Если вы хотите заранее представить свою выходную разметку, посмотрите на Tidy .
Можно использовать метод поиска/замены среды IDE и заменить все инструкции echo
на echo PHP_EOL,
. При этом перед выводом будет добавлен символ (ы) новой строки для конкретной ОС. Обратите внимание на запятую после PHP_EOL, поскольку это важно.
Вы можете вывести несколько значений с эхо:
echo 'one', $foo, PHP_EOL,
'two', $bar, PHP_EOL;
, поэтому нет необходимости записывать эхо
в каждую строку.
Однако я согласен с любым, кто предложил использовать более специализированный подход к разделению содержимого и макета, например, используя ракурсы шаблонов или HereDoc.
В дополнение, очень мало выигрыша в наличии довольно разметки. Если вы используете такие инструменты, как Firebug для проверки HTML, вы будете иметь правильно отформатированные разметки независимо от беспорядка разметки на самом деле. Кроме того, на сайтах с большим количеством посетителей вы часто найдете разметку, которая является противоположностью тому, что вы пытаетесь сделать, просто потому, что все эти новые строки и вкладки добавляют к весу страницы, что приводит к более медленной загрузке страницы и увеличению стоимости трафика.
-121--2478550-Поскольку оба x и y являются кубическими параметрическими функциями, нет замкнутого решения с точки зрения простых функций. Численная интеграция - это путь. Либо интегрирование выражения длины дуги, либо простое добавление длин отрезков - зависит от точности, после которой вы будете работать, и от того, сколько усилий вы хотите приложить.
Точный и быстрый метод «Добавление длины отрезков линий»:
Использование рекуррентного подразделения (форма алгоритма де Кастельо) для генерации точек может дать вам высокоточное представление с минимальным количеством точек. Подразделы подразделяются только в том случае, если они не соответствуют критериям. Обычно критерии основаны на длине, соединяющей контрольные точки (корпус или клеть). Для кубических обычно сравнивают близость P0P1 + P1P2 + P2P3 к P0P3, где P0, P1, P2 & P3 являются контрольными точками, которые определяют ваш безье.
Код Delphi можно найти здесь: Текст ссылки
Преобразование в Python должно быть относительно простым. Он будет генерировать точки. Код уже вычисляет длину сегментов для проверки критериев. Вы можете просто накапливать эти значения длины по пути.
-121--3950554-Вызовите требуемый # include и замените комментарий несбалансированным текстом в скобках:
} int printf(const char *s, ...) { return fprintf(stdout,"%d",5);
Протестировано успешно. Спасибо dreamlax и Крису Лутцу за багфиксы.
Как насчет чего-то вроде этого: (только x86)
change()
{
__asm__( "mov eax, [ebp+4]\n\t"
"add eax, 4\n\t"
"mov [ebp+4], eax\n\t" );
}
Это POSIX ответ, который действительно делает то, о чём просит проблема :)
Он не будет работать на некоторых архитектурах/компиляторах, но он работает здесь.
#include <stdio.h>
void
change () {
void _change();
_change();
}
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
void
_change()
{
int main();
uintptr_t m=(uintptr_t)main;
uintptr_t ps=sysconf(_SC_PAGESIZE);
m/=ps;
m*=ps;
mprotect((void*)m,ps,PROT_READ|PROT_WRITE|PROT_EXEC);
char *s=(char*)(intptr_t)main;
s=memchr(s,10,ps);
*s=5;
mprotect((void*)m,ps,PROT_READ|PROT_EXEC);
}
int
main() {
int i=5;
change();
i=10;
printf ("%d\n",i);
return 0;
}
EDIT: Это должно сделать его более надежным для людей с бойкотирующими заголовками.
Просто:
void change()
{
printf("%d\n", 5);
int foo;
close(0);
close(1);
dup2(foo, 1);
dup2(foo, 0);
}
Немного более сложный:
void change()
{
int *outfd = malloc(2 * sizeof(int));
char buf[3];
pipe(outfd);
if(!fork())
{
read(outfd[0], buf, 2);
if(buf[0] == '1' && buf[1] == '0')
{
printf("5\n");
}
else
{
write(1, buf, 2);
}
while(1);
}
else
{
close(1);
dup2(outfd[1], 1);
}
}
-121--2227021- Малое дополнение к ответу Джейсона :
ToShortDateString ()
чувствительно к культуре. От MSDN:
последовательность, возвращенная Метод ToShortDateString имеет значение чувствительный к культуре. Он отражает образец, определенный текущим объект DateTimeFormatInfo культуры. Например, для культуры en-US, стандартный образец краткой даты: «М/д/гггг»; для культуры de-DE, является «dd.MM.yyyy»; для ja-JP культура, это «гггг/М/д». определенная последовательность формата для конкретного компьютер также может быть настроен так что он отличается от стандарта короткая последовательность формата даты.
Это означает, что лучше использовать метод ToString ()
и явно определять формат (как сказал Джейсон). Хотя если эта последовательность появляется в пользовательском интерфейсе, то ToShortDateString ()
является хорошим решением, поскольку возвращает последовательность, знакомую пользователю.
DateTime.Today
. Вывод printf («% d», i);
вызов в main ()
не заканчивается в новой строке, поведение программы определяется реализацией.
Я утверждаю, что на моей реализации программа, которая не может записать завершающую новую строку для последней строки, всегда печатает 5
, за которой следует новая строка в качестве своей последней строки.
Таким образом, выход будет всегда 5, независимо от определения change ()
.: -)
(Другими словами, какой смысл в таких вопросах, если они не предназначены для запуска на определенном оборудовании, компиляторе и т.д.)
Простой:
void change()
{
printf("%d\n", 5);
int foo;
close(0);
close(1);
dup2(foo, 1);
dup2(foo, 0);
}
Немного более сложный:
void change()
{
int *outfd = malloc(2 * sizeof(int));
char buf[3];
pipe(outfd);
if(!fork())
{
read(outfd[0], buf, 2);
if(buf[0] == '1' && buf[1] == '0')
{
printf("5\n");
}
else
{
write(1, buf, 2);
}
while(1);
}
else
{
close(1);
dup2(outfd[1], 1);
}
}
Кто-нибудь думал об использовании atexit?
void change (void)
{
static int i = 0;
if (i == 0) atexit (change);
if (i == 1) printf ("\r5 \b\n");
++i;
}
Обратите внимание, что в основной функции нет завершающего символа новой строки, если мы отправим 2 символа возврата на стандартный вывод, 10 будут стерты, и будут напечатаны только 5.
Я не уверен, что это всегда будет работать, но как насчет размещения переменной i в стеке следующим образом:
void change()
{
int j, *p;
for (j=-100, p=&j; j<0; j++, p++)
if (*p == 10) { *p = 5; break; }
}