作为指针的参数未正确递增

Parameter as pointer not being correctly incremented

我有一个函数可以计算字符串中元音和辅音的数量:

void CountVowelsConsonants(char* str, int *vowels, int *consonants){
    size_t size=strlen(str);
    //size-1 because of the '\n' at the end of the string when pressing enter
    for (int i = 0; i < size ; ++i) {
        char c = str[i];
            if(c=='A' || c== 'E' || c=='I' || c== 'O' || c=='U' ||
                    c=='a' || c== 'e' || c=='i' || c== 'o' || c=='u'){
                *vowels++;
            }
        }
    *consonants= size-1 - *vowels;
    }

但是当我调用这个函数时,例如:

int vowels;
int consonants;
CountVowelsConsonants("abc", &vowels, &consonants);

它returns:

Vowels: -858993460
Consonants: 858993463

而不是:

Vowels: 1
Consonants: 2

我想知道为什么会这样。

我有一个阶乘函数,它具有与指针类似的实现并且可以正常工作:

void factorial(int n, int*fac){
    *fac=1;
    for (int i = 2; i <=  n; ++i) {
        *fac*=i;
    }
}

访问阶乘函数中的事实指针将正确改变值。唯一的区别是,在 CountVowelsConsonants 函数中,我递增 1 而不是乘以。

但是,如果我访问 CountVowelsConsonants 函数中的元音指针来递增,它将在计数中产生错误。

我的IDE(CLion)会把*vowels中的*灰掉,说明指针运算符在 *vowels++;没用。

关于为什么会这样有什么想法吗?

而不是:

*vowels++;

相当于:

*vowels;            // this does nothing, that's what your IDE was telling you
vowel = vowels + 1; // this increments the vowels pointer,
                    // which is also pretty useless here

你需要这样写:

(*vowels)++;

这相当于你真正想要的:

*vowels = *vowels + 1;

++运算符的precedence为1,而*(解引用)运算符的优先级为2。

对于初学者来说,如果变量 vowelsconsonants 在 main(或其他函数)中声明,那么它们不会被初始化并且具有不确定的值。你需要写

int vowels = 0;
int consonants = 0;
CountVowelsConsonants("abc", &vowels, &consonants);

第一个函数参数应该用限定符 const 声明,因为传递的字符串在函数中没有改变。

void CountVowelsConsonants( const char* str, int *vowels, int *consonants);

顺便说一下,第二个和第三个参数的类型应为 size_t.

void CountVowelsConsonants( const char* str, size_t *vowels, size_t *consonants);

在函数中,对传递的字符串的 strlen 调用效率低下。

size_t size=strlen(str);

循环中的变量 i 应声明为 size_t.

类型
for ( size_t i = 0; i < size ; ++i) {

但如果不调用函数 strlen,循环看起来会更简单

for ( ; *str != '[=15=]'; ++str ) {
    char c = *str;
    if(c=='A' || c== 'E' || c=='I' || c== 'O' || c=='U' ||
            c=='a' || c== 'e' || c=='i' || c== 'o' || c=='u'){
        ++*vowels;
    }
    else {
       ++*consonants;
    }
 }

这个表达式

*vowels++;

不正确。它等价于表达式

*( vowels++ );

也就是指针本身是递增的。

你应该写

++*vowels;

这个表达式

*consonants= size-1 - *vowels;

也不正确。

如果您正在使用通过调用 strlen 获得的变量 size 那么您必须写

*consonants= size -*vowels;

注意,如果传递的字符串包含空格或标点符号,函数将无法正常运行。

所以在函数内声明循环至少用下面的方式会更正确

#include <ctype.h>

//...

for ( ; *str != '[=21=]'; ++str ) {
    char c = *str;

    if ( isalpha( ( unsigned char )c ) ) {
        if(c=='A' || c== 'E' || c=='I' || c== 'O' || c=='U' ||
                c=='a' || c== 'e' || c=='i' || c== 'o' || c=='u'){
            ++*vowels;
        }
        else {
           ++*consonants;
        }
    }
 }