作为指针的参数未正确递增
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。
对于初学者来说,如果变量 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 != '[=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;
}
}
}
我有一个函数可以计算字符串中元音和辅音的数量:
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。
对于初学者来说,如果变量 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 != '[=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;
}
}
}