一本介绍C指针的书--指针的类型及数组2.2
2012-08-04 00:00
295 查看
Earlier when discussing the term "lvalue" I cited K&R-2 where it stated:
"An object is a named region of storage; an lvalue is an expression
referring to an object".
This raises an interesting problem. Since my_array is a named region of storage, why is
my_array in the above assignment statement not an lvalue? To resolve this problem,
some refer to my_array as an "unmodifiable lvalue".
Modify the example program above by changing
ptr = &my_array[0];
to
ptr = my_array;
and run it again to verify the results are identical.
Now, let's delve a little further into the difference between the names ptr and my_array
as used above. Some writers will refer to an array's name as a constant pointer. What do
we mean by that? Well, to understand the term "constant" in this sense, let's go back to
our definition of the term "variable". When we declare a variable we set aside a spot in
memory to hold the value of the appropriate type. Once that is done the name of the
variable can be interpreted in one of two ways. When used on the left side of the
assignment operator, the compiler interprets it as the memory location to which to move
that value resulting from evaluation of the right side of the assignment operator. But,
when used on the right side of the assignment operator, the name of a variable is
interpreted to mean the contents stored at that memory address set aside to hold the value
of that variable.
With that in mind, let's now consider the simplest of constants, as in:
int i, k;
i = 2;
Here, while i is a variable and then occupies space in the data portion of memory, 2 is a
constant and, as such, instead of setting aside memory in the data segment, it is imbedded
directly in the code segment of memory. That is, while writing something like k = i; tells
the compiler to create code which at run time will look at memory location &i to
determine the value to be moved to k, code created by i = 2; simply puts the 2 in the code
and there is no referencing of the data segment. That is, both k and i are objects, but 2 is
not an object.
Similarly, in the above, since my_array is a constant, once the compiler establishes
where the array itself is to be stored, it "knows" the address of my_array[0] and on
seeing:
ptr = my_array;
it simply uses this address as a constant in the code segment and there is no referencing
of the data segment beyond that.
This might be a good place explain further the use of the (void *) expression used in
Program 1.1 of Chapter 1. As we have seen we can have pointers of various types. So far
we have discussed pointers to integers and pointers to characters. In coming chapters we
will be learning about pointers to structures and even pointer to pointers.
Also we have learned that on different systems the size of a pointer can vary. As it turns
out it is also possible that the size of a pointer can vary depending on the data type of the
object to which it points. Thus, as with integers where you can run into trouble
attempting to assign a long integer to a variable of type short integer, you can run into
trouble attempting to assign the values of pointers of various types to pointer variables of
other types.
To minimize this problem, C provides for a pointer of type void. We can declare such a
pointer by writing:
void *vptr;
A void pointer is sort of a generic pointer. For example, while C will not permit the
comparison of a pointer to type integer with a pointer to type character, for example,
either of these can be compared to a void pointer. Of course, as with other variables, casts
can be used to convert from one type of pointer to another under the proper
circumstances. In Program 1.1. of Chapter 1 I cast the pointers to integers into void
pointers to make them compatible with the %p conversion specification. In later chapters
other casts will be made for reasons defined therein.
Well, that's a lot of technical stuff to digest and I don't expect a beginner to understand all
of it on first reading. With time and experimentation you will want to come back and re-read the first 2 chapters. But for now, let's move on to the relationship between pointers,
character arrays, and strings.
"An object is a named region of storage; an lvalue is an expression
referring to an object".
This raises an interesting problem. Since my_array is a named region of storage, why is
my_array in the above assignment statement not an lvalue? To resolve this problem,
some refer to my_array as an "unmodifiable lvalue".
Modify the example program above by changing
ptr = &my_array[0];
to
ptr = my_array;
and run it again to verify the results are identical.
Now, let's delve a little further into the difference between the names ptr and my_array
as used above. Some writers will refer to an array's name as a constant pointer. What do
we mean by that? Well, to understand the term "constant" in this sense, let's go back to
our definition of the term "variable". When we declare a variable we set aside a spot in
memory to hold the value of the appropriate type. Once that is done the name of the
variable can be interpreted in one of two ways. When used on the left side of the
assignment operator, the compiler interprets it as the memory location to which to move
that value resulting from evaluation of the right side of the assignment operator. But,
when used on the right side of the assignment operator, the name of a variable is
interpreted to mean the contents stored at that memory address set aside to hold the value
of that variable.
With that in mind, let's now consider the simplest of constants, as in:
int i, k;
i = 2;
Here, while i is a variable and then occupies space in the data portion of memory, 2 is a
constant and, as such, instead of setting aside memory in the data segment, it is imbedded
directly in the code segment of memory. That is, while writing something like k = i; tells
the compiler to create code which at run time will look at memory location &i to
determine the value to be moved to k, code created by i = 2; simply puts the 2 in the code
and there is no referencing of the data segment. That is, both k and i are objects, but 2 is
not an object.
Similarly, in the above, since my_array is a constant, once the compiler establishes
where the array itself is to be stored, it "knows" the address of my_array[0] and on
seeing:
ptr = my_array;
it simply uses this address as a constant in the code segment and there is no referencing
of the data segment beyond that.
This might be a good place explain further the use of the (void *) expression used in
Program 1.1 of Chapter 1. As we have seen we can have pointers of various types. So far
we have discussed pointers to integers and pointers to characters. In coming chapters we
will be learning about pointers to structures and even pointer to pointers.
Also we have learned that on different systems the size of a pointer can vary. As it turns
out it is also possible that the size of a pointer can vary depending on the data type of the
object to which it points. Thus, as with integers where you can run into trouble
attempting to assign a long integer to a variable of type short integer, you can run into
trouble attempting to assign the values of pointers of various types to pointer variables of
other types.
To minimize this problem, C provides for a pointer of type void. We can declare such a
pointer by writing:
void *vptr;
A void pointer is sort of a generic pointer. For example, while C will not permit the
comparison of a pointer to type integer with a pointer to type character, for example,
either of these can be compared to a void pointer. Of course, as with other variables, casts
can be used to convert from one type of pointer to another under the proper
circumstances. In Program 1.1. of Chapter 1 I cast the pointers to integers into void
pointers to make them compatible with the %p conversion specification. In later chapters
other casts will be made for reasons defined therein.
Well, that's a lot of technical stuff to digest and I don't expect a beginner to understand all
of it on first reading. With time and experimentation you will want to come back and re-read the first 2 chapters. But for now, let's move on to the relationship between pointers,
character arrays, and strings.
相关文章推荐
- 一本介绍C指针的书--指针的类型及数组2.1
- 一本介绍C指针的书--字符串和字符串数组6.3
- 一本介绍C指针的书--字符串和字符串数组6.2
- 一本介绍C指针的书--字符串和字符串数组6.1
- 关于字符串类型与字符数组(指针)
- 一本介绍C指针的书--指针和字符串3.2
- 《C++primer》标准库类型 数组和指针
- more effective c++ 第一章读书笔记: 指针,引用,c++类型转换,多态数组,默认构造函数
- 从零开始学C++之从C到C++(二):引用、数组引用与指针引用、内联函数inline、四种类型转换运算符
- 【OC加强】枚举介绍、数组的排序、对象的排序、如何利用block排序以及一些数据类型知识
- C语言学习6 :指针的定义,指针类型要合法,指针要初始化,指针做函数参数,数组和指针的通用性,指针+1所代表的空间,void * 指针,交换函数中的指针,数组和字符型指针区别,字符型指针的应用,使用指针完成字符操作函数
- 复习小记----第3、4、5章 数组、指针、标准库类型、表达式
- 程序设计基石与实践系列之类型提升、内存分配,数组转指针、打桩和矢量变换
- C++学习(二):标准库类型、数组、指针
- PowerShell中的强类型数组介绍
- 一本介绍C指针的书--指针和字符串3.1
- C语言之数组专题:数组指针、指针数组、数组做函数参数退化、数组名、数组类型
- 一维数组,二维数组,三维数组,数组与指针,结构体数组,通过改变指针类型改变访问数组的方式
- 数组的地址是什么?是指向该数组类型的指针。
- sizeof()函数求类型所占字节大小-指针,数组