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]);