Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 指针数组和指向数组的指针之间的区别?_C_Pointers_Pointer To Pointer - Fatal编程技术网

C 指针数组和指向数组的指针之间的区别?

C 指针数组和指向数组的指针之间的区别?,c,pointers,pointer-to-pointer,C,Pointers,Pointer To Pointer,除了string可以指向任何大小的字符串和string1Ptr只能指向大小为4的字符串(否则指针运算会出错)之外,我看不出它们之间有什么区别 比如说, char string1[3][4]={"koo","kid","kav"}; //This is a 2D array char * string[3]={"koo","kid","kav"}; //This is an array of 3 pointers pointing to 1D array as strings are st

除了
string
可以指向任何大小的字符串和
string1Ptr
只能指向大小为4的字符串(否则指针运算会出错)之外,我看不出它们之间有什么区别

比如说,

 char string1[3][4]={"koo","kid","kav"}; //This is a 2D array

 char  * string[3]={"koo","kid","kav"}; //This is an array of 3 pointers pointing to 1D array as strings are stored as arrays in memory
 char (*string1Ptr)[4]=string1; //This is a pointer to a 1D array of 4 characters

//I want to know differences between string1Ptr(pointer to array mentioned in question) and string(array of pointers mentioned in question). I only typed string1 here to give string1Ptr an address to strings
char string1[3][4]={"koo","kid","kav"}; //This is a 2D array

char  * string[3]={"koo","kid","kav"}; //This is an array of 3 pointers pointing to 1D array as strings are stored as arrays in memory
char (*string1Ptr)[4]=string1; //This is a pointer to a 1D array of 4 characters
它们似乎都执行相同的指针算法。(我假设
string
string1Ptr
的原因几乎相似,除了我上面提到的差异)

那么string和string1Ptr之间有什么区别呢?有什么理由用一个代替另一个吗

附言:我是新手,所以请对我放松点。
另外,我检查了一下,它似乎没有回答我的问题。

字符串1和
string
之间的区别与以下两者之间的区别相同:

   printf("%s\n", string1[2]);   // All print the same thing, ie, the word "kav"
   printf("%s\n", string1Ptr[2]);
   printf("%s\n", string[2]);
s1
是一个4个字符的可写数组,
s2
是一个指向字符串文本的指针,该字符串文本不可写。看

因此,在您的示例中,可以执行
string1[0][0]='f'
string1[0]
更改为
“foo”
,但
string[0][0]='f'导致未定义的行为

此外,由于
string
是指针数组,因此可以重新分配这些指针,例如
string[0]=“abc”。您无法分配给
string1[0]
,因为元素是数组,而不是指针,正如您无法重新分配
s1

string1Ptr
工作的原因是
string1
是一个二维字符数组,保证是连续的
string1Ptr
是一个指向4个字符数组的指针,当您对它进行索引时,您将按该字符数递增,这将使您进入
string1
数组的下一行

除此之外,
string
还可以指向任何大小和长度的字符串
string1Ptr
只能指向大小为4的字符串(否则 指针运算会出错),我不知道它们之间有什么区别 他们

它们是绝对的、根本的不同,但是C会不厌其烦地向您隐藏它们之间的区别

string
是一个数组。它标识存储其元素的连续内存块。在本例中,这些元素碰巧属于
char*
类型,但这是一个相对次要的细节。我们可以把它比作一座包含多个房间的房子——这些房间实际上是房子的一部分,存在于房子的物理边界之内。我可以随心所欲地装饰房间,但它们始终是那所房子的房间

string1Ptr
是一个指针。它标识一个内存块,其内容描述如何访问另一个不同的内存块,其中有一个由4个字符组成的数组。在我们的房地产类比中,这就像一张纸,上面写着“42C街,主卧”。使用这些信息,你可以找到房间,并根据自己的喜好重新装修,就像在其他情况下一样。但是你也可以用不同房间的定位器来代替纸张,可能是在不同的房子里,或者是随机的文本,或者你甚至可以烧掉整个信封,而不会影响C街上的房间

string1
本身就是一个数组数组。它标识存储其元素的连续内存块。这些元素中的每一个本身都是一个由4个
char
s组成的数组,顺便说一句,它恰好是
string1Ptr
可以指向的对象类型

比如说,

 char string1[3][4]={"koo","kid","kav"}; //This is a 2D array

 char  * string[3]={"koo","kid","kav"}; //This is an array of 3 pointers pointing to 1D array as strings are stored as arrays in memory
 char (*string1Ptr)[4]=string1; //This is a pointer to a 1D array of 4 characters

//I want to know differences between string1Ptr(pointer to array mentioned in question) and string(array of pointers mentioned in question). I only typed string1 here to give string1Ptr an address to strings
char string1[3][4]={"koo","kid","kav"}; //This is a 2D array

char  * string[3]={"koo","kid","kav"}; //This is an array of 3 pointers pointing to 1D array as strings are stored as arrays in memory
char (*string1Ptr)[4]=string1; //This is a pointer to a 1D array of 4 characters
它们似乎都执行相同的指针运算 假设
string
string1Ptr
除了 差异(如上所述)

。。。这就是C隐藏区别的地方。关于C数组需要了解的一个基本情况是,在几乎所有的表达式中,*数组类型的值都会自动静默地转换为指针[指向数组的第一个元素]。这有时被称为指针“衰减”。因此,索引运算符是指针上的运算符,而不是数组上的运算符,在您的三个示例中,它确实具有类似的行为。实际上,
string1
衰减到的指针类型与
string1Ptr
的类型相同,这就是为什么允许对后者进行初始化

但您应该了解,在这三种情况下,操作的逻辑顺序并不相同。首先,考虑

这里,
string1Ptr
是一个指针,索引运算符直接适用于该指针。结果相当于
*(string1Ptr+2)
,其类型为
char[4]
。作为数组类型的值,转换为指向第一个元素的指针(结果是
char*

现在考虑

string1
是一个数组,因此首先将其转换为指向其第一个元素的指针,从而生成类型为
char(*)[4]
的值。这与
string1Ptr1
的类型相同,并且如上所述,相应地进行评估

但这一个有点不同:

这里,
string
是一个指针,因此索引操作直接应用于它。结果相当于
*(string+2)
,其类型为
char*
。不执行自动转换

有什么理由用一个代替另一个吗

许多,在两个方向上,取决于您当时的特殊需要。一般来说,指针更灵活,尤其是在使用动态分配的内存时需要指针。但他们也受到了这些问题的困扰

  • 指针可能在范围内,但不指向任何对象,并且
  • 声明指针不会创建任何指向它的内容。而且
  • 即使在程序执行过程中指针一次指向某个对象,并且其值不是sub
    printf("%s\n", string1Ptr[2]);
    
    printf("%s\n", string1[2]);
    
    printf("%s\n", string[2]);