【问题标题】:Two Dimensional Array of a character and string function in CC中字符和字符串函数的二维数组
【发布时间】:2021-03-28 09:10:38
【问题描述】:

我正在编写一个 C 程序,它输入来自用户的字符串并按字母顺序对其进行排序。 我有两个问题。

当我以这种方式输入来自用户的字符串时,不会发生错误。

for(int i =0; i < 7; i++)
{
    printf("Enter the name %d\n",i+1);
    scanf("%s",&name[i][0]);
}

name[i][0] 是什么意思

    char name[7][10];

为什么我们在这里设置第二个索引为0,第二个维度不是我们的数组可以处理的最大字符串长度吗?

我的第二个问题是 对于这种类型的数组,字符串处理函数采用&amp;name[i][0]&amp;name[i] 是什么?

到目前为止我编写的代码给了我想要的输出,但是有很多警告

#include<stdio.h>
#include<string.h>

int main() {
  char name[7][10];
  for (int i = 0; i < 7; i++) {
    printf("Enter the name %d\n", i + 1);
    scanf("%s", & name[i]);
    strlwr( & name[i]);
  }
  //Sort in alphabetical order
  for (int i = 0; i < 7; i++) {
    for (int j = i + 1; j < 7; j++) {
      if (strcmp( & name[i][0], & name[j][0]) > 0) {
        char temp[10];
        strcpy(temp, & name[i]);
        strcpy(name[i], & name[j]);
        strcpy(name[j], & temp);
      }
    }
  }
  printf("The names in alphabetical order is\n");
  for (int i = 0; i < 7; i++) {
    puts(name[i]);
  }
}

警告是:

 warning: passing argument 1 of 'strlwr' from incompatible pointer type [-Wincompatible-pointer-types]
           98 |         strlwr(&name[i]);

其他功能也类似。

【问题讨论】:

  • 那不是维度,是索引。
  • name[i] 指向name的第i个元素的字节0,相当于name[i][0]
  • 方括号中的数字是声明数组时的维度,使用时是索引。
  • name[i]ith 字符串; name[i][0]ith 字符串中的第一个字符; &amp;name[i][0]ith 字符串中第一个字符的地址,与name[i] 具有相同的值。对strlwr()(一个非标准函数——在标准C 或POSIX 中不是)的调用将char (*)[10] 传递给一个需要char * 的函数。您需要致电strlwr(name[i]);scanf("%s", &amp;name[i][0]);scanf("%s", name[i]); 均有效且等效。
  • @IcanCode:不;字符串处理函数采用指向字符串第一个字符的指针。所有这些——好吧,所有标准的,无论如何。 strlen(name[i]) 是正确的; strchr(name[i], 'A') 是正确的,strcmp(name[i], name[i+1]) == 0 是正确的,如果 i 不是太大(或负数)。

标签: c pointers multidimensional-array implicit-conversion c-strings


【解决方案1】:

names[i] 是声明为数组的元素

char name[7][10];

类型为char[10]。也就是说,这个二维数组的元素是char[10] 类型的一维数组。

在表达式中使用的数组指示符(很少有例外,例如用作 sizeof 运算符的操作数)被转换为指向它们的第一个元素的指针。

因此,例如用作函数scanf 的参数的表达式names[i] 被转换为指向其第一个元素的指针。也就是这个表达式等价于&amp;names[i][0]

所以不是这个调用

scanf("%s",&name[i][0])

你可以写

scanf("%s", name[i] )

用作参数的两个表达式的类型均为char *

scanf的这个调用

scanf("%s", & name[i]);

有一个不正确类型的参数。表达式&amp;name[i] 的类型为char ( * )[10],而函数需要char * 类型的参数,尽管两个表达式的值彼此相等。

如果你有一个像这样声明的数组

char name[7][10];

然后是这些表达式的值

&name
&name[0] 
&name[0][0]

彼此相等,并产生数组占用的内存范围的第一个字节的地址。

但是表达式的类型是不同的。他们是

char ( * )[7][10]
char ( * )[10]
char *

这是一个演示程序

#include <stdio.h>

int main(void) 
{
    char name[7][10];
    
    printf( "&name       = %p\n", ( void * )&name );
    printf( "&name[0]    = %p\n", ( void * )&name[0] );
    printf( "&name[0][0] = %p\n", ( void * )&name[0][0] );

    return 0;
}

它的输出可能看起来像

&name       = 0x7ffec1d18e40
&name[0]    = 0x7ffec1d18e40
&name[0][0] = 0x7ffec1d18e40

由于上述原因,这些调用的参数

    strcpy(temp, & name[i]);
    strcpy(name[i], & name[j]);

还有不正确的类型char ( * )[10],而函数需要char *类型的参数。

你需要写

    strcpy(temp, name[i]);
    strcpy(name[i], name[j]);

【讨论】:

  • The both expressions used as arguments have the type char * - 不是事实。它们有不同的类型。
  • @P__JsupportswomeninPoland 你错了。两者都具有 char * 类型,因为在我编写数组指示符时,它被转换为指向其第一个元素的指针。
  • @VladfromMoscow name[i] 是指针还是第 i 个字符串?
  • @AbhilekhGautam 在波兰 P__J 支持女性的回答中,错误地写着它是一个指针。这是一个错误的说法。它是数组类型 char[10] 的左值。例如,如果你写 printf("%zu\n", sizeof name[i]);您将得到结果 10。但在表达式中使用的数组指示符(例如在运算符 sizeof 中使用)被隐式转换为指向其第一个元素的指针。 .所以P__J支持波兰女性的答案是不正确的。
  • @IcanCode 是的,它是正确的。表达式指向字符串的第一个字符,类型为 char *.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
  • 2016-02-22
  • 1970-01-01
相关资源
最近更新 更多