Что происходит в * s ++? - PullRequest
0 голосов
/ 02 марта 2019
#include <string.h>
#include <stdio.h>

#define bool int
#define true 1
#define false 0

static bool is_digit(char c){
    return c > 47 && c < 58;
}

static bool is_all_digit(char *s){
    while(s){
        if(is_digit(*s++)){
            continue;
        }
        return false;
    }
    return true;
}


int main(){
    char *s = "123456";
    int i;
    printf("len = %d\n", strlen(s));
    for(i = 0; i<strlen(s); ++i){
        printf("%c : %s\n", *s, is_digit(*s++)? "true" : "false");
        //printf("%c : %s\n", s[i], is_digit(s[i])? "true" : "false");
    }
    return 0;
}

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

Это заканчивается 3 и 4 ~ 6 исчезает.Моя рабочая среда - win10 gcc 6.3.0

Ответы [ 2 ]

0 голосов
/ 02 марта 2019
for(i = 0; i<strlen(s); ++i){
    s++;
}

В этом цикле for i увеличивается, а strlen(s) уменьшается.Потому что operator ++ меняет указатель s;(s++)

Сначала s указывают всю строку "123456";Но после одного цикла указатель s перемещается как один байт.Так что s означает «23456».Следовательно, strlen(s) теперь возвращает 5.

После того, как напечатано "3", strlen(s) возвращает 3. И i также равно 3. Так что цикл for завершен.

выражение *s++ просто означает * «увеличение и разыменование» (Правка: «разыменование и увеличение».) Это поможет: https://en.cppreference.com/w/cpp/language/operator_precedence

Благодаря прочтению.

0 голосов
/ 02 марта 2019

Есть ряд проблем с этим.

  1. Вы printf используете неверную строку формата. Используйте %zu для size_t, а не %d.

  2. Ваш printf имеет неопределенное поведение, поскольку у вас есть *s и *s++в том же выражении, без точки последовательности между ними.

  3. Вы пересчитываете strlen(s) на каждой итерации цикла, и это значение уменьшается ивниз и вниз, потому что вы продолжаете увеличивать s.Я бы кешировал strlen(s) в переменную с именем n (или что-то подобное) перед началом, так как n не изменится.

Мой компилятор предупреждал меня обо всем, крометретий баг.

Эта программа работает:

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

#define bool int
#define true 1
#define false 0

static bool is_digit(char c){
    return c > 47 && c < 58;
}


int main(){
    const char *s = "123456";
    size_t i;
    const size_t n = strlen(s);
    printf("len = %zu\n", n);
    for(i = 0; i<n; ++i){
        printf("%c : %s\n", *s, is_digit(*s)? "true" : "false");
        s++;
    }
    return 0;
}

( live demo )

Вы также можете пропустить strlen полностью и простоищите нулевой терминатор:

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

#define bool int
#define true 1
#define false 0

static bool is_digit(char c){
    return c > 47 && c < 58;
}


int main(){
    const char *s = "123456";
    while (*s) {
        printf("%c : %s\n", *s, is_digit(*s)? "true" : "false");
        s++;
    }
    return 0;
}

( live demo )

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