如何解决作为指针的参数未正确递增
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);
它返回:
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。
对于初学者而言,如果变量vowels
和consonants
在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 != '\0'; ++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;
也不正确。
如果您使用的是通过调用size
获得的变量strlen
,则必须编写
*consonants= size -*vowels;
请注意,如果传递的字符串包含空格或标点符号,则该函数将无法正常工作。
因此,至少通过以下方式在函数内声明循环会更正确
#include <ctype.h>
//...
for ( ; *str != '\0'; ++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;
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。