C指针混淆-指向字符数组的指针
这应该很简单,但指向字符数组的指针有时仍然让我摸不着头脑。gcc在第4行和第5行抱怨“下标值既不是数组也不是指针”,在第8行和第11行抱怨“一元*”的类型参数无效”。有人能解释一下这里出了什么问题吗?我更改了第4行和第5行,首先使用括号取消对指针的引用,但仍然无法得到我想要的 这应该是一个非常简单的函数:C指针混淆-指向字符数组的指针,c,arrays,pointers,char,C,Arrays,Pointers,Char,这应该很简单,但指向字符数组的指针有时仍然让我摸不着头脑。gcc在第4行和第5行抱怨“下标值既不是数组也不是指针”,在第8行和第11行抱怨“一元*”的类型参数无效”。有人能解释一下这里出了什么问题吗?我更改了第4行和第5行,首先使用括号取消对指针的引用,但仍然无法得到我想要的 这应该是一个非常简单的函数: 1 void makesafestr ( const char *unsafe, const char *safe ) 2 { 3 int offset=0; 4 for (
1 void makesafestr ( const char *unsafe, const char *safe )
2 {
3 int offset=0;
4 for (; (*safe)[offset] != "\0" ; offset++) {
5 switch ((*unsafe)[offset]) {
6 case "\n":
7 case "\r":
8 *safe[offset] = "~";
9 break;
10 default:
11 *safe[offset] = *unsafe[offset];
12 }
13 offset++;
14 }
}
在
safe
和safe
前面不需要星号。它们已经是指针了。
此外,必须使用单引号而不是双引号。单引号表示字符,双引号表示螫针。在
safe
和safe
前面不需要星号。它们已经是指针了。
此外,必须使用单引号而不是双引号。单引号表示字符,双引号表示sting。在代码中,safe是指向字符的指针(而不是指向数组的指针)。所以当你说
*safe
时,这是一个普通的char
而不是(*safe)[offset]
尝试safe[offset]
。同样适用于*安全[偏移量]
,同样适用于不安全
第二个问题是比较角色的方式。“\0”是字符串文字。在代码中需要一个字符文本。简而言之,的应为:
for (; safe[offset] != '\0' ; offset++)
但是您可以重写它并使其更简单,因为\0
是0
:
for (offset=0; safe[offset]; offset++)
在您的代码中,safe
是指向字符的指针(而不是指向数组的指针)。所以当你说*safe
时,这是一个普通的char
而不是(*safe)[offset]
尝试safe[offset]
。同样适用于*安全[偏移量]
,同样适用于不安全
第二个问题是比较角色的方式。“\0”是字符串文字。在代码中需要一个字符文本。简而言之,的应为:
for (; safe[offset] != '\0' ; offset++)
但是您可以重写它并使其更简单,因为\0
是0
:
for (offset=0; safe[offset]; offset++)
字符常量需要单引号而不是双引号:'\0'、'\n'、'\r'和'~'
此外,由于标记为const
(在解决了其他答案中已经提到的间接问题之后),可能不允许对safe
进行赋值。字符常量需要单引号而不是双引号:'\0'、'\n'、'\r'和'~'
此外,可能不允许分配给安全
,因为它被标记为常量
(在修复了其他答案中已经提到的间接问题之后)。指针不安全
和安全
指向字符数组的第一项
safe[4]
将是数组中的第五项(从零开始计数),即第五个字符
所以代码应该是
void makesafestr ( const char *unsafe, char *safe ) /* Do not need const for safe, as you are
constructing it */
{
int offset=0;
for (; unsafe[offset] != 0 ; offset++) /* Do not need the " - see below. Also would have
thought you need to scan unsafe */
{
switch (unsafe[offset]) {
case '\n': /* Single quotes required as we are dealing with characters and not strings */
case '\r':
safe[offset] = '~';
break;
default:
safe[offset] = unsafe[offset];
}
offset++;
}
safe[offset] = 0; /* In C and C++ strings end with the null character */
}
注释,C和C++中的字符串(<代码>)字符串“< /代码>”是字符数组。
< P>指针<代码>不安全< /COD>和<代码>安全> /COD>指向字符数组的第一个项目。
safe[4]
将是数组中的第五项(从零开始计数),即第五个字符
所以代码应该是
void makesafestr ( const char *unsafe, char *safe ) /* Do not need const for safe, as you are
constructing it */
{
int offset=0;
for (; unsafe[offset] != 0 ; offset++) /* Do not need the " - see below. Also would have
thought you need to scan unsafe */
{
switch (unsafe[offset]) {
case '\n': /* Single quotes required as we are dealing with characters and not strings */
case '\r':
safe[offset] = '~';
break;
default:
safe[offset] = unsafe[offset];
}
offset++;
}
safe[offset] = 0; /* In C and C++ strings end with the null character */
}
注意,C和C++中的字符串()字符串“”是字符数组。
这就是为什么不需要*的原因。后缀表达式后跟方括号[]中的表达式是数组对象元素的下标指定。下标运算符[]的定义是E1[E2]与(*(E1)+(E2))相同。由于适用于二进制+运算符的转换规则,如果E1是数组对象(相当于指向数组对象初始元素的指针),E2是整数,E1[E2]指定E1的第E2个元素(从零开始计数)。哇,这很复杂。这是否意味着指针总是先取消引用,然后再添加下标?我担心编译器可能会假定它是一个指针数组,并使用“safe”加[offset]的地址,然后取消对该地址的引用。否a[i]
相当于*(a+i)
;a+i
的结果被取消引用(即在取消引用之前添加偏移量)。如果您将safe
声明为char(*safe)[
(指向char
数组的指针),那么您需要在应用下标之前取消对指针的引用(并且*safe
周围的参数是强制性的——下标的优先级高于取消引用,因此*safe[i]
将被解析为*(安全[i])
,而不是(*safe)[i]
,这会导致问题)。这就是为什么您不需要“*”的原因。后缀表达式后跟方括号[]中的表达式是数组对象元素的下标指定。下标运算符[]的定义是E1[E2]与(*(E1)+(E2))相同。由于适用于二进制+运算符的转换规则,如果E1是数组对象(相当于指向数组对象初始元素的指针),E2是整数,E1[E2]指定E1的第E2个元素(从零开始计数)。哇,这很复杂。这是否意味着指针总是先取消引用,然后再添加下标?我担心编译器可能会假定它是一个指针数组,并使用“safe”加[offset]的地址,然后取消对该地址的引用。否a[i]
相当于*(a+i)
;a+i
的结果被取消引用(即在取消引用之前添加偏移量)。如果将safe
声明为char(*safe)[
(指向char
数组的指针),则需要在应用下标之前取消对指针的引用(并且*safe
周围的参数是必需的)--