Как делает, “в то время как (*s ++ = *t ++)” копируют строку?

Вы можете просто иметь функцию-член шаблона и static_assert, которая гарантирует, что вы не берете производную, которая не поддерживается вашим классом. Например:

template <int n, /* other stuff */>
class f
{
  /* Other stuff not shown */
  template <int p>
  Real prime(Real x)
  {
    static_assert(p <= n, "unsupported derivative");
    /* do whatever you need to to implement the pth derivative */
  }
};

Таким образом, объект типа f < 1> будет поддерживать простое < 1> (), но не простое < 2> () и т. Д. Если вы случайно вызовите простое число < 3> для объекта типа f < 1> компилятор вызовет вас на него. Вам решать, хотите ли вы считать prime<0> идентичным operator () или изменить свой static_assert, чтобы включить проверку для p > 0.

52
задан user87166 14 February 2015 в 22:32
поделиться

11 ответов

It is equivalent to this:

while (*t) {
    *s = *t;
    s++;
    t++;
}
*s = *t;

When the char that t points to is '\0', the while loop will terminate. Until then, it will copy the char that t is pointing to to the char that s is pointing to, then increment s and t to point to the next char in their arrays.

39
ответ дан 7 November 2019 в 09:18
поделиться

Yes, it does have to do with pointers.

The way to read the code is this: "the value that is pointed to by the pointer "s" (which gets incremented after this operation) gets the value which is pointed to by the pointer "t" (which gets incremented after this operation; the entire value of this operation evaluates to the value of the character copied; iterate across this operation until that value equals zero". Since the value of the string null terminator is the character value of zero ('/0'), the loop will iterate until a string is copied from the location pointed to by t to the location pointed to by s.

-1
ответ дан 7 November 2019 в 09:18
поделиться

it copies a string because arrays are always passed by reference, and string is just a char array. Basically what is happening is (if i remember the term correctly) pointer arithmetic. Here's a bit more information from wikipedia on c arrays.

You are storing the value that was dereferenced from t in s and then moving to the next index via the ++.

0
ответ дан 7 November 2019 в 09:18
поделиться

It works by copying characters from the string pointed to by 't' into the string pointed to by 's'. For each character copies, both pointers are incremented. The loop terminates when it finds a NUL character (equal to zero, hence the exit).

1
ответ дан 7 November 2019 в 09:18
поделиться

Yes this uses pointers, and also does all the work while evaluating the while condition. C allows conditional expressions to have side-effects.

The "*" operator derefereces pointers s and t.

The increment operator ("++") increments pointers s and t after the assignment.

The loop terminates on condition of a null character, which evaluates as false in C.

One additional comment.... this is not safe code, as it does nothing to ensure s has enough memory allocated.

-1
ответ дан 7 November 2019 в 09:18
поделиться

запускает цикл while ....

* s = * t идет первым, это назначает то, на что указывает точка, на какую точку указывает. т.е. он копирует символ из строки t в строку s.

то, что присваивается, передается условию while ... любое ненулевое значение равно "true", поэтому оно будет продолжено, а 0 равно false, оно остановится .... и это просто происходит, когда конец строки также ноль.

s ++ и t ++ они увеличивают указатели

, и все начинается снова

, поэтому он продолжает присваивать циклы, перемещая указатели, пока не достигнет 0, что является концом строки

-1
ответ дан 7 November 2019 в 09:18
поделиться

Скажите у вас есть что-то вроде этого:

char *someString = "Hello, World!";

someString указывает на первый символ в строке - в данном случае 'H'.

Теперь, если вы увеличите указатель на единицу:

someString++

someString будет теперь указывают на 'e'.

while ( *someString++ );

будет зацикливаться до тех пор, пока все, на что указывает someString , не станет NULL, что означает, что конец строки («NULL завершен»).

И код:

while (*s++ = *t++);

равно:

while ( *t != NULL ) { // While whatever t points to isn't NULL
    *s = *t;           // copy whatever t points to into s
    s++;
    t++;
}
0
ответ дан 7 November 2019 в 09:18
поделиться

СОВЕТЫ: ​​

  • Что делает оператор '='?
  • Какое значение имеет выражение «a = b»? Например: если вы делаете "c = a = b" какое значение получает c?
  • Что завершает строку C? Оценивает ли он значение true или false?
  • Какой оператор имеет более высокий приоритет в "* s ++"?

СОВЕТ:

  • Вместо этого используйте strncpy ().
1
ответ дан 7 November 2019 в 09:18
поделиться

The aspect that is mysterious about this is the order of operations. If you look up the C language spec, it states that in this context, the order of operations is as follows:

1. * operator
2. = (assignment) operator
3. ++ operator

So the while loop then becomes, in english:

while (some condition):
  Take what is at address "t" and copy it over to location at address "s".
  Increment "s" by one address location.
  Increment "t" by one address location.

Now, what is "some condition"? The C lang specification also says that the value of an assignment expression is the assigned value itself, which in this case is *t.

So "some condition" is "t points to something that is non-zero", or in a simpler way, "while the data at location t is not NULL".

3
ответ дан 7 November 2019 в 09:18
поделиться

Предположим, что s и t являются char * s, которые указывают на строки (и предполагаем с ] по крайней мере так же велико, как т ). В C все строки заканчиваются на 0 (ASCII "NUL"), правильно? Итак, что это делает:

*s++ = *t++;

Во-первых, он делает * s = * t , копируя значение из * t в * s . Затем он выполняет s ++ , поэтому s теперь указывает на следующий символ. И затем он делает t ++ , поэтому t указывает на следующий символ. Это связано с приоритетом оператора и префиксом по сравнению с постфиксным увеличением / уменьшением .

Приоритет оператора - это порядок, в котором разрешаются операторы. Для простого примера посмотрите:

4 + 2 * 3

Это 4 + (2 * 3) или (4 + 2) * 3 ? Ну, мы знаем, что это первый из-за приоритета - двоичный файл * (оператор умножения) имеет более высокий приоритет, чем двоичный файл + (оператор сложения), и разрешается первым.

В * s ++ мы имеем унарный * (оператор разыменования указателя) и унарный ++ (оператор приращения постфикса). В этом случае ++ имеет более высокий приоритет (также называемый «крепче связывать»), чем * . Если бы мы сказали ++ * s , мы бы увеличили значение на * s , а не на адрес , на который указывают s , потому что Приращение префикса имеет меньший приоритет * как разыменование, но мы использовали постфиксный приращение , который имеет более высокий приоритет. Если бы мы хотели использовать приращение префикса, мы могли бы сделать * (++ s) , так как скобка перекрыла бы все более низкие приоритеты и вынудила бы сначала ++ s , но это может привести к нежелательному побочному эффекту - оставить пустой символ в начале строки.

Обратите внимание, что только потому, что он имеет более высокий приоритет, это не означает, что это произойдет первым. Постфиксный прирост, в частности, происходит после того, как используется значение, поэтому его * s = * t происходит до s ++ .

Итак, теперь вы понимаете ] * s ++ = * t ++ . Но они помещают это в цикл:

while(*s++ = *t++);

Этот цикл ничего не делает - действие находится в состоянии. Но проверьте это условие - оно возвращает «false», если * s равно 0, что означает, что * t было 0, что означает, что они были в конце строки (yay для ASCII "NUL"). Таким образом, этот цикл выполняется до тех пор, пока в t есть символы, и покорно копирует их в s , увеличивая s и t на все путь. Когда этот цикл завершается, s завершается NUL и является правильной строкой. Единственная проблема в том, что s указывает на конец. Держите под рукой еще один указатель, указывающий на начало с (то есть с до цикла while () ) - , что будет вашим скопированная строка:

char *s, *string = s;
while(*s++ = *t++);
printf("%s", string); // prints the string that was in *t

В качестве альтернативы, проверьте это:

size_t i = strlen(t);
while(*s++ = *t++);
s -= i + 1;
printf("%s\n", s); // prints the string that was in *t

Мы начали с получения длины, поэтому, когда мы закончили, мы сделали больше арифметики указателей, чтобы вернуть s в начало, где оно началось.

Конечно, этот фрагмент кода (и все мои фрагменты кода) игнорируют проблемы с буфером для простоты. Лучшая версия такова:

size_t i = strlen(t);
char *c = malloc(i + 1);
while(*s++ = *t++);
s -= i + 1;
printf("%s\n", s); // prints the string that was in *t
free(c);

Но вы уже знали об этом или скоро зададите вопрос об этом на любимом веб-сайте каждого. ;)

* На самом деле, они имеют одинаковый приоритет, но это разрешается разными правилами. Они фактически имеют более низкий приоритет в этой ситуации.

)

* На самом деле, они имеют одинаковый приоритет, но это разрешается разными правилами. Они фактически имеют более низкий приоритет в этой ситуации.

)

* На самом деле, они имеют одинаковый приоритет, но это разрешается разными правилами. Они фактически имеют более низкий приоритет в этой ситуации.

19
ответ дан 7 November 2019 в 09:18
поделиться

This has so much going on under the covers:

while (*s++ = *t++);

The s and t variables are pointers (almost certainly characters), s being the destination. The following steps illustrate what's happening:

  • the contents of t (*t) are copied to s (*s), one character.
  • s and t are both incremented (++).
  • the assignment (copy) returns the character that was copied (to the while).
  • the while continues until that character is zero (end of string in C).

Effectively, it's:

while (*t != 0) {
    *s = *t;
    s++;
    t++;
}
*s = *t;
s++;
t++;

but written out in a much more compact way.

30
ответ дан 7 November 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: