C指针混淆-指向字符数组的指针

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 (

这应该很简单,但指向字符数组的指针有时仍然让我摸不着头脑。gcc在第4行和第5行抱怨“下标值既不是数组也不是指针”,在第8行和第11行抱怨“一元*”的类型参数无效”。有人能解释一下这里出了什么问题吗?我更改了第4行和第5行,首先使用括号取消对指针的引用,但仍然无法得到我想要的

这应该是一个非常简单的函数:

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
周围的参数是必需的)--