为什么我不能像对待一个在C指针数组? [英] Why can't I treat an array like a pointer in C?

查看:103
本文介绍了为什么我不能像对待一个在C指针数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到这个问题了很多SO。也许没有这么多的话......但一​​次又一次没有对数组如何从不同的指针混乱。所以,我想我会花点时间Q&安培; A几点关于这个

有关这个Q&功放的目的; A,我们要承担32位系统和下面已宣布:

 的char * PTR =你好;
焦炭ARR [10] =你好;
诠释IARR [10] = {0};

下面是那猜测的困惑我看到SO问题清单。当我看到新的,我会添加到我的Q&放的名单; A(!别人随意为好,并纠正我,如果你看到任何错误)


  1. 是不是指针和数组基本上是一回事吗?

  2. 按照起来:既 *(PTR) *(ARR) PTR [0] 改编[0] 给予同样的事情,为什么?

  3. 怎么会改编&放大器;改编是相同的值

  4. 按照起来:为什么会出现不同的值印刷改编+ 1 VS &放大器;常用3 + 1


解决方案

1)指针不是数组。数组不是指针。不要以为他们的这种方式,因为它们是不同的。结果
我怎么能证明这一点?想想他们的样子在内存中:

我们的阵列改编是10个字符长。它包含了你好,别急,这还不是全部!因为我们有一个静态声明数组比我们的消息更长的时间,我们得到了一堆空字符('\\ 0')免费奉送!另外,还要注意如何名称改编在概念上被连接到相邻的字符,(它没有指向任何东西)。

接下来考虑我们的指针会怎样看在内存中:

注意,这里我们指向一个字符数组一些地方在只读存储器。

因此​​,同时兼具改编 PTR 被初始化,以同样的方式,内容/每个位置实际上是不同的。

这就是关键点:结果 PTR 是一个变量,我们可以把它指向任何改编是一个常量,它总是引用的10个字符此块。


2) [] 是可在地址中使用的添加和尊重操作符。这意味着改编[0] 是一样的话说 *(ARR + 0)。所以,是这样做的:

 的printf(%C%C,*(ARR + 1)*(PTR + 1));

会给你E E的输出。这不是因为数组的指针,这是因为一个数组的名称改编和一个指向 PTR 都发生给你一个地址。

关键点2:的尊重运营商 * 和添加和尊重运营商 [] 不特定分别为指针和数组。这些运营商只需在地址工作。


3)我没有一个非常简单的答案...让我们忘记了我们的字符数组一秒钟,看看它这个例子说明:

  INT B: //这是整数类型
和b; //这是INT B的地址,对不对?INT C []; //这是整数数组
和C; //这将是数组的地址,对不对?

这就是pretty理解这个怎么样:

  * C; //这是阵列中的第一个元素

什么是code的这条线告诉你吗?如果我顺从 C ,然后我得到一个int。这意味着只是简单的 C 是一个地址。由于它是在阵列的开始它的阵列的地址,同时在阵列中的第一个元件的地址,因而从一个值的角度来看

 ç==和C;


4)让我去题外话一秒钟在这里......这最后一个问题是地址运算混乱的一部分。我看到SO一个问题在一个点意味着地址只是整数值......你要明白,在C类地址有型的知识。这就是说:

  IARR + 1; //我们增加1到地址,让我们感动的4个字节
ARR + 1; //我们增加1到地址,让我们感动1个字节

基本上的sizeof(INT) 4和的sizeof(char)的 1。因此,加1一个数组并不是那么简单,因为它看起来。结果

所以,现在回到正题,为什么改编+ 1 &放大器不同,常用3 + 1 ?第一种是添加 1 *的sizeof(字符) = 1的地址,第二个是增加 1 *的sizeof(ARR) = 10的地址。

这就是为什么即使他们都是只加1他们给不同的结果。

I see this question a lot on SO. Maybe not in so many words... but time and again there is confusion on how arrays are different from pointers. So I thought I would take a moment to Q&A a few points about this.

For purposes of this Q&A we're going to assume a 32-bit system and the following have been declared:

char * ptr = "hello";
char arr[10] = "hello";
int iarr[10] = {0};

Here's a list of questions that surmise the confusion I see on SO. As I see new ones I'll add to my list of Q&A (others feel free to as well, and correct me if you see any mistakes!)

  1. Isn't a pointer and an array basically the same thing?
  2. Follow up: both *(ptr) and *(arr), or ptr[0] and arr[0] give the same thing, why?
  3. How come arr and &arr is the same value?
  4. Follow up: why do I get a different value printing arr+1 vs &arr+1?

解决方案

1) Pointers are not arrays. Arrays are not pointers. Don't think of them that way because they are different.
How can I prove this? Think about what they look like in memory:

Our array arr is 10 characters long. It contains "Hello", but wait, that's not all! Because we have a statically declared array longer than our message, we get a bunch of NULL characters ('\0') thrown in for free! Also, note how the name arr is conceptually attached to the contiguous characters, (it's not pointing to anything).

Next consider how our pointer would look in memory: Note here we're pointing to a character array some place in read only memory.

So while both arr and ptr were initialized the same way, the contents/location of each is actually different.

This is the key point:
ptr is a variable, we can point it to anything, arr is a constant, it will always refer to this block of 10 characters.


2) The [] is an "add and deference" operator that can be used on an address. Meaning that arr[0] is the same as saying *(arr+0). So yes doing this:

printf("%c %c", *(arr+1), *(ptr+1));

Would give you an output of "e e". It's not because arrays are pointers, it's because the name of an array arr and a pointer ptr both happen to give you an address.

Key point to #2: The deference operator * and the add and deference operator [] are not specific to pointers and arrays respectively. These operators simply work on addresses.


3) I don't have an extremely simple answer... so let's forget our character arrays for a second and take a look at it this example for an explanation:

int b;   //this is integer type
&b;      //this is the address of the int b, right?

int c[]; //this is the array of ints
&c;      //this would be the address of the array, right?

So that's pretty understandable how about this:

*c;   //that's the first element in the array

What does that line of code tell you? If I deference c, then I get an int. That means just plain c is an address. Since it's the start of the array it's the address of the array and also the address of the first element in the array, thus from a value standpoint:

c == &c;


4) Let me go off topic for a second here... this last question is part of the confusion of address arithmetic. I saw a question on SO at one point implying that addresses are just integer values... You need to understand that in C addresses have knowledge of type. That is to say:

iarr+1; //We added 1 to the address, so we moved 4 bytes
arr+1;  //we added 1 to the address, so we moved 1 byte

Basically the sizeof(int) is 4 and the sizeof(char) is 1. So "adding 1 to an array" is not as simple as it looks.

So now, back to the question, why is arr+1 different from &arr+1? The first one is adding 1 * sizeof(char)=1 to the address, the second one is adding 1 * sizeof(arr)=10 to the address.

This is why even though they are both "only adding 1" they give different results.

这篇关于为什么我不能像对待一个在C指针数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆