Указатель C: * p ++ и p ++ разница - PullRequest
1 голос
/ 13 октября 2011

Я только начал изучать C.

void function(char *str1, char *str2) {
    printf("%p\n", str1);
    printf("%p\n", str2);
    str1++; //*str++;
    str2++; //*str++;
    printf("%p\n", str1);
    printf("%p\n", str2);
}

int main(int argc, char *argv[]) {
    function(argv[1], argv[2]);
    return 0;
}

, если argv[1] "базовый" argv[2] это "программный";

, когда я заменяю код частью комментарияэто дало бы тот же самый результат, который "a" "r";но если я скомпилирую его с флагом -Werror, он выдаст «предупреждение: вычисленное значение не используется»

В чем разница между str1++ и *str1++;?

каков код, если я хочу увеличить символ, на который он указывает, до

для строки: function(argv[1], argv[2]); здесь argv[1] и agrv[2], которые я передаюфункция, они указатели или они массив? что такое *argv[1] и *argv[2]

Ответы [ 4 ]

4 голосов
/ 13 октября 2011

в чем разница между str1 ++ и * str1 ++

Они имеют одинаковые побочные эффекты (увеличивают указатель).

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

function (argv [1], argv [2]);здесь argv [1] и agrv [2], которые я передаю функции, являются ли они указателями или массивом?

Они являются указателями на char, т.е.строки.В частности, 1-й и 2-й параметры командной строки.

2 голосов
/ 13 октября 2011

Разница лучше всего иллюстрируется некоторыми изменениями вашей функции.Имейте в виду, что ++ x отличается от x ++ только возвращаемым значением:

void function(char *str1, char *str2) 
{
    printf("%s\n", str1);
    printf("%s\n", str2);
    printf("%s\n", ++str1);
    printf("%s\n", ++str2);
}

вызывающая функция, так как function("hello", "world") напечатает

 hello
 world
 ello
 orld

Теперь давайте изменим функцию для использования *++str вместо ++str

void function(char *str1, char *str2) 
{
    printf("%s\n", str1);
    printf("%s\n", str2);
    printf("%c\n", *++str1);
    printf("%c\n", *++str2);
}

Теперь вывод того же вызова:

hello
world
e
o

* просто разыменовывает все, что идет после него, в данном случае начало строки.

2 голосов
/ 13 октября 2011

Каждое (под) выражение в C (с несколькими исключениями) имеет значение и, возможно, побочный эффект.

Выражения могут использоваться только для значения, как в 42 ниже.

int a = 42;

Их также можно использовать только для побочного эффекта, как показано ниже

printf("Hello, world!\n");

И, конечно, они могут использоваться как для значения, так и для побочного эффекта (getchar ниже):

while ((ch = getchar()) != EOF) /* void */;

Ваш компилятор просто жалуется, что вы вычислили значение и не использовали его. Компилятор знает, что не следует жаловаться на обычную конструкцию, такую ​​как printf(), но не в конкретном случае *str++


Выражение *str++ имеет значение *str и побочный эффект увеличения str. Поскольку вы не используете значение, оно совпадает с str++ (со значением str и тем же побочным эффектом и обычной конструкцией, на которую компилятор не жалуется).

0 голосов
/ 13 октября 2011

Указатели имеют фиксированные размеры, а массивы - нет. sizeof (char *) == sizeof (int) == sizeof (float **) и так далее. Идея в том, что вы передаете указатель фиксированного размера на этот массив символов вместо копирования всего объекта. Вы получаете значение массива символов путем разыменования с помощью *, но это в большинстве случаев бесполезно для строк. Динамические строки обычно оставляются как указатели, чтобы они могли учитывать произвольный размер. Я не знаю ни одной причины, по которой вы хотели бы увеличить указатель, но увеличение любой буквы в строке имело бы смысл.

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

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