一本介绍C指针的书--指针的类型及数组2.1
2012-08-04 00:00
369 查看
Okay, let's move on. Let us consider why we need to identify the type of variable that a
pointer points to, as in:
int *ptr;
One reason for doing this is so that later, once ptr "points to" something, if we write:
*ptr = 2;
the compiler will know how many bytes to copy into that memory location pointed to by
ptr. If ptr was declared as pointing to an integer, 2 bytes would be copied, if a long, 4
bytes would be copied. Similarly for floats and doubles the appropriate number will be
copied. But, defining the type that the pointer points to permits a number of other
interesting ways a compiler can interpret code. For example, consider a block in memory
consisting if ten integers in a row. That is, 20 bytes of memory are set aside to hold 10
integers.
Now, let's say we point our integer pointer ptr at the first of these integers. Furthermore
lets say that integer is located at memory location 100 (decimal). What happens when we
write:
ptr + 1;
Because the compiler "knows" this is a pointer (i.e. its value is an address) and that it
points to an integer (its current address, 100, is the address of an integer), it adds 2 to ptr
instead of 1, so the pointer "points to" the next integer, at memory location 102.
Similarly, were the ptr declared as a pointer to a long, it would add 4 to it instead of 1.
The same goes for other data types such as floats, doubles, or even user defined data
types such as structures. This is obviously not the same kind of "addition" that we
normally think of. In C it is referred to as addition using "pointer arithmetic", a term
which we will come back to later.
Similarly, since ++ptr and ptr++ are both equivalent to ptr + 1 (though the point in the
program when ptr is incremented may be different), incrementing a pointer using the
unary ++ operator, either pre- or post-, increments the address it stores by the amount
sizeof(type) where "type" is the type of the object pointed to. (i.e. 2 for an integer, 4 for a
long, etc.).
Since a block of 10 integers located contiguously in memory is, by definition, an array of
integers, this brings up an interesting relationship between arrays and pointers.
Consider the following:
int my_array[] = {1,23,17,4,-5,100};
Here we have an array containing 6 integers. We refer to each of these integers by means
of a subscript to my_array, i.e. using my_array[0] through my_array[5]. But, we could
alternatively access them via a pointer as follows:
int *ptr;
ptr = &my_array[0]; /* point our pointer at the first integer in our array */
And then we could print out our array either using the array notation or by dereferencing
our pointer. The following code illustrates this:
----------- Program 2.1 -----------------------------------
/* Program 2.1 from PTRTUT10.HTM 6/13/97 */
#include <stdio.h>
int my_array[] = {1,23,17,4,-5,100};
int *ptr;
int main(void)
{
int i;
ptr = &my_array[0]; /* point our pointer to the first
element of the array */
printf("\n\n");
for (i = 0; i < 6; i++)
{
printf("my_array[%d] = %d ",i,my_array[i]); /*<-- A */
printf("ptr + %d = %d\n",i, *(ptr + i)); /*<-- B */
}
return 0;
}
Compile and run the above program and carefully note lines A and B and that the
program prints out the same values in either case. Also observe how we dereferenced our
pointer in line B, i.e. we first added i to it and then dereferenced the new pointer. Change
line B to read:
printf("ptr + %d = %d\n",i, *ptr++);
and run it again... then change it to:
printf("ptr + %d = %d\n",i, *(++ptr));
and try once more. Each time try and predict the outcome and carefully look at the actual
outcome.
In C, the standard states that wherever we might use &var_name[0] we can replace that
with var_name, thus in our code where we wrote:
ptr = &my_array[0];
we can write:
ptr = my_array;
to achieve the same result.
This leads many texts to state that the name of an array is a pointer. I prefer to mentally
think "the name of the array is the address of first element in the array". Many beginners
(including myself when I was learning) have a tendency to become confused by thinking
of it as a pointer. For example, while we can write
ptr = my_array;
we cannot write
my_array = ptr;
The reason is that while ptr is a variable, my_array is a constant. That is, the location at
which the first element of my_array will be stored cannot be changed once my_array[]
has been declared.
pointer points to, as in:
int *ptr;
One reason for doing this is so that later, once ptr "points to" something, if we write:
*ptr = 2;
the compiler will know how many bytes to copy into that memory location pointed to by
ptr. If ptr was declared as pointing to an integer, 2 bytes would be copied, if a long, 4
bytes would be copied. Similarly for floats and doubles the appropriate number will be
copied. But, defining the type that the pointer points to permits a number of other
interesting ways a compiler can interpret code. For example, consider a block in memory
consisting if ten integers in a row. That is, 20 bytes of memory are set aside to hold 10
integers.
Now, let's say we point our integer pointer ptr at the first of these integers. Furthermore
lets say that integer is located at memory location 100 (decimal). What happens when we
write:
ptr + 1;
Because the compiler "knows" this is a pointer (i.e. its value is an address) and that it
points to an integer (its current address, 100, is the address of an integer), it adds 2 to ptr
instead of 1, so the pointer "points to" the next integer, at memory location 102.
Similarly, were the ptr declared as a pointer to a long, it would add 4 to it instead of 1.
The same goes for other data types such as floats, doubles, or even user defined data
types such as structures. This is obviously not the same kind of "addition" that we
normally think of. In C it is referred to as addition using "pointer arithmetic", a term
which we will come back to later.
Similarly, since ++ptr and ptr++ are both equivalent to ptr + 1 (though the point in the
program when ptr is incremented may be different), incrementing a pointer using the
unary ++ operator, either pre- or post-, increments the address it stores by the amount
sizeof(type) where "type" is the type of the object pointed to. (i.e. 2 for an integer, 4 for a
long, etc.).
Since a block of 10 integers located contiguously in memory is, by definition, an array of
integers, this brings up an interesting relationship between arrays and pointers.
Consider the following:
int my_array[] = {1,23,17,4,-5,100};
Here we have an array containing 6 integers. We refer to each of these integers by means
of a subscript to my_array, i.e. using my_array[0] through my_array[5]. But, we could
alternatively access them via a pointer as follows:
int *ptr;
ptr = &my_array[0]; /* point our pointer at the first integer in our array */
And then we could print out our array either using the array notation or by dereferencing
our pointer. The following code illustrates this:
----------- Program 2.1 -----------------------------------
/* Program 2.1 from PTRTUT10.HTM 6/13/97 */
#include <stdio.h>
int my_array[] = {1,23,17,4,-5,100};
int *ptr;
int main(void)
{
int i;
ptr = &my_array[0]; /* point our pointer to the first
element of the array */
printf("\n\n");
for (i = 0; i < 6; i++)
{
printf("my_array[%d] = %d ",i,my_array[i]); /*<-- A */
printf("ptr + %d = %d\n",i, *(ptr + i)); /*<-- B */
}
return 0;
}
Compile and run the above program and carefully note lines A and B and that the
program prints out the same values in either case. Also observe how we dereferenced our
pointer in line B, i.e. we first added i to it and then dereferenced the new pointer. Change
line B to read:
printf("ptr + %d = %d\n",i, *ptr++);
and run it again... then change it to:
printf("ptr + %d = %d\n",i, *(++ptr));
and try once more. Each time try and predict the outcome and carefully look at the actual
outcome.
In C, the standard states that wherever we might use &var_name[0] we can replace that
with var_name, thus in our code where we wrote:
ptr = &my_array[0];
we can write:
ptr = my_array;
to achieve the same result.
This leads many texts to state that the name of an array is a pointer. I prefer to mentally
think "the name of the array is the address of first element in the array". Many beginners
(including myself when I was learning) have a tendency to become confused by thinking
of it as a pointer. For example, while we can write
ptr = my_array;
we cannot write
my_array = ptr;
The reason is that while ptr is a variable, my_array is a constant. That is, the location at
which the first element of my_array will be stored cannot be changed once my_array[]
has been declared.
相关文章推荐
- 一本介绍C指针的书--指针的类型及数组2.2
- 一本介绍C指针的书--字符串和字符串数组6.3
- 一本介绍C指针的书--字符串和字符串数组6.2
- 一本介绍C指针的书--字符串和字符串数组6.1
- java并发编程(十二)----(JUC原子类)数组类型介绍
- 从sizeof(数组名)/sizeof(数组类型) 简单说说 数组名字 和 指针
- c中的数组名的指针类型解析
- C/C++下void*类型指针介绍
- C语言学习8:malloc返回的void*类型指针不可以做更改,free双重释放,二维数组的初始化和打印,a和a[0]和a[0][0]的区别,数组指针(*p)[3],指针数组*a[10],动态内存分配版约瑟夫环,动态分配版去空格和逗号处理,二级指针与二维数组互用
- C#中获取数组指针再将其转换成IntPtr类型
- C++的数组、结构体、指针三种复合类型知识点小总结
- 《C++primer》标准库类型 数组和指针
- 数组指针、函数指针和尾置返回类型
- delphi 数组类型与数组指针的巧妙利用
- 100 数组和指针绝不等价,数组是另外一种类型
- 【C语言提高33】数组指针类型定义
- 学点 C 语言(21): 数据类型 - 数组与指针
- c/c++ 字符数组、字符指针和字符串类型总结帖
- 详细介绍C/C++数组名与指针区别
- 详细介绍C/C++数组名与指针区别