C语言中字符串函数的二维数组

C语言中字符串函数的二维数组,c,pointers,multidimensional-array,implicit-conversion,c-strings,C,Pointers,Multidimensional Array,Implicit Conversion,C Strings,我正在写一个C程序,从用户输入的字符串按字母顺序排序。 我这里有两个问题 当我以这种方式从用户输入字符串时,不会发生错误 for(int i =0; i < 7; i++) { printf("Enter the name %d\n",i+1); scanf("%s",&name[i][0]); } 为什么我们要将第二个索引设置为0,第二个维度不是我们的数组可以处理的字符串的最大长度吗 我的第二个问题是 对于这种类型的数组,

我正在写一个C程序,从用户输入的字符串按字母顺序排序。 我这里有两个问题

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

for(int i =0; i < 7; i++)
{
    printf("Enter the name %d\n",i+1);
    scanf("%s",&name[i][0]);
}
为什么我们要将第二个索引设置为0,第二个维度不是我们的数组可以处理的字符串的最大长度吗

我的第二个问题是 对于这种类型的数组,字符串处理函数需要什么
&name[i][0]
&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]);
  }
}

与其他函数类似。

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

char name[7][10];
char name[7][10];
并且具有类型
char[10]
。也就是说,这个二维数组的元素是
char[10]
类型的一维数组

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

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

所以不是这个电话

scanf("%s",&name[i][0])
你可以写

scanf("%s", name[i] )
用作参数的两个表达式的类型均为
char*

这是scanf的呼吁

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

如果有一个数组声明为

char name[7][10];
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;
}
由于上述原因,这些调用的参数

    strcpy(temp, & name[i]);
    strcpy(name[i], & name[j]);
当函数需要类型为
char*
的参数时,也有不正确的类型
char(*)[10]

你需要写作

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

这不是维度,而是索引。name[i]指向name的第i个元素的字节零,这相当于name[i][0]方括号中的数字在声明数组时是维度,在使用数组时是索引。
name[i]
i
th字符串
name[i][0]
i
th字符串中的第一个字符
&name[i][0]
i
th字符串中第一个字符的地址,其值与
name[i]
相同。调用
strlwr()
(一个非标准函数-如中所示,而不是在标准C或POSIX中)将
char(*)[10]
传递给需要
char*
的函数。您需要调用
strlwr(name[i])。都是
scanf(“%s”和&name[i][0])
scanf(“%s”,名称[i])有效且等效。@代码:否;字符串处理函数采用指向字符串第一个字符的指针。所有的,好吧,所有的标准的,无论如何
strlen(名称[i])
是正确的
strchr(名称[i],'A')
是正确的,
strcmp(名称[i],名称[i+1])==0
是正确的,如果
i
不是太大(或负值)。
用作参数的两个表达式的类型都是char*
-不是真的。它们有不同的类型。@P_ujsupportswomenipland您错了。两者都有char*类型,因为在我写的时候,一个数组指示符被转换为指向其第一个元素的指针。@VladfromMoscow name[I]是指针还是第I个字符串?@AbhilekhGautam在P_uj的回答中支持波兰妇女,但它被错误地写为指针。这是一个错误的说法。它是数组类型char[10]的左值。例如,如果您编写printf(“%zu\n”,名称[i]的大小);你会得到10分的结果。但是在表达式中使用的数组指示符(很少有例外,例如在运算符sizeof中使用的数组指示符)被隐式转换为指向其第一个元素的指针。因此,P_u__J支持波兰妇女的答案是不正确的。@是的,它将是正确的。表达式指向字符串的第一个字符,其类型为char*。
    strcpy(temp, name[i]);
    strcpy(name[i], name[j]);