MVC очень хорошо известен так да, мы используем шаблоны разработки довольно много. Теперь, если Ваше выяснение о Банде Четырех шаблонов, существуют несколько, что я использую, потому что другие специалисты по обслуживанию будут знать дизайн и чего мы работаем для в коде. Существуют несколько, хотя это остается довольно неясным для того, что мы делаем, поэтому если я использую тот, я не извлекаю полную пользу из использования шаблона.
они важный, да, потому что это дает Вам метод разговора о разработке программного обеспечения быстрым эффективным и общепринятым способом. Можно ли сделать лучшие настраиваемые решения, хорошо да (sorta)?
исходные шаблоны GoF вытянули от производственного кода, таким образом, они каталогизировали то, что уже использовалось в дикой природе. Они не просто или даже главным образом академическая вещь.
Нет, это не одно и то же. Предположим, что d
является указателем на int
:
int n = 0;
int* d = &n;
*d++; // d++ then *d, but d++ is applied after the statement.
(*d)++; // == n++, just add one to the place where d points to.
Я думаю, что в K&R есть пример, где нам нужно скопировать c-строку в другую:
char* first = "hello world!";
char* second = malloc(strlen(first)+1);
....
while(*second++ = *first++)
{
// nothing goes here :)
}
Код следующий: просто, поместите символ, на который указывает сначала
, в символ, на который указывает второй
, затем увеличивайте оба указателя после выражения. Конечно, когда копируется последний символ, которым является '\ 0', выражение приводит к false
и останавливается!
Приращение ++
имеет более высокий приоритет оператора, чем разыменование *
, поэтому * d ++
увеличивает указатель d
, чтобы указать на следующее место в массиве, но результатом ++
является исходный указатель d
, поэтому * d
возвращает исходный указываемый элемент. И наоборот, (* d) ++
просто увеличивает указанное значение на единицу.
Пример:
// Case 1
int array[2] = {1, 2};
int *d = &array[0];
int x = *d++;
assert(x == 1 && d == &array[1]); // x gets the first element, d points to the second
// Case 2
int array[2] = {1, 2};
int *d = &array[0];
int x = (*d)++;
assert(x == 1 && d == &array[0] && array[0] == 2);
// array[0] gets incremented, d still points there, but x receives old value
Первый увеличивает указатель, второй увеличивает указанное значение.
В качестве эксперимента попробуйте следующее:
int main() {
int x = 20;
int *d = &x;
printf("d = %p\n", d);
int z = (*d)++;
printf("z = %d\n", z);
printf("d = %p\n", d);
int y = *d++;
printf("y = %d\n", y);
printf("d = %p\n", d);
}
Они действительно возвращают тот же результат, но изменение состояния в вашей программе совершенно другое.
Это легче всего понять, если мы просто расширим операции.
x = *d++;
// same as
x = *d;
d += 1; // remember that pointers increment by the size of the thing they point to
x = (*d)++;
// same as
x = *d;
*d += 1; // unless *d is also a pointer, this will likely really just add 1
В официальной терминологии C эти выражения дают те же результаты , как и должны. В правильной терминологии «результат» непустого выражения - это то, что это выражение оценивает. Оба ваших выражения вычисляют начальное значение * d
, поэтому неудивительно, что результаты одинаковы.
Однако добавление к «результату» каждое выражение в C имеет ноль или более называется «побочными эффектами». И побочные эффекты этих двух выражений совершенно разные. Первое выражение увеличивает значение указателя 'd'. Второе выражение увеличивает значение '* d' (указанное значение).
У меня нет под рукой компилятора.
a = (*d)++;
b = (*d);
это a == b? я не думаю, что это так.