原文
http://blog.csdn.net/sdspp/archive/2006/02/27/611611.aspx
指针是c语言的精髓,理解它对于学习c语言至关重要。
1.指针和地址
指针是能够存放一个地址的一组存储单元。是一种保存变量地址的变量。
如 int x=1,y=2,z[10];
int *ip; /* ip是指向int类型的指针 */
ip = &x; /* ip 指向 x */
y = *ip; /* y 的值现在是1 */
*ip = 0; /* x的值现在是0*/
ip = &z[0]; /* ip指向z[0] */
其中一元运算符&可用于取一个对象的地址。地质运算符&只能应用于内存中的对象,即变量和数组元素。他不能作用于表达式,常量或register类型的变量。
一元运算符* 是间接寻址或间接引用运算符。当他作用于指针时,将访问指针所指向的对象。
y = *ip + 1;
*ip += 1;
++*ip;
(*ip)++;
这几条语句是等价的。其中(*ip)++中的括号是必需的。如果是*ip++,该表达式将是对ip进行加一运算,而不是对ip指向的对象进行加一运算。这是因为,类似于*和++这样的一元运算符遵循从右制左的结合顺序。
理解这点非常重要,它可以帮我们写出很简洁的程序。
void strcpy(char *s, char *t)
{
while(*s++ = *t++)
;
}
再如:
int strcmp(char *s, char *t)
{
while(*s++ == *t++)
if(*s =='\0')
return 0;
return *s-*t;
}
再如:
*p++ = val; /* 将val压入栈 */
val = *--p /* 将栈顶元素弹出到val中 */
这里涉及到一个问题,就是优先级的问题。*,++,--,具有相同的优先级,按照从右到左的顺序结合。按照这个原则上叙的就不难理解。究竟是对地址改变,还是对地址所引用的值变换。
再如,命令行操作经常遇到的:argv[0]保存命令好的第一个单词,通常是命令。(*argv)[0]同*argv[0]就完全不一样。因为[ ]的优先级要比*的高,所以(*++argv)[0]可以看作是**++argv,是命令的第一个字母。而*++argv[0]就相当于增加argv[0]指针。可以借此来遍历命令行之后的参数的内容。
2.指针和数组
在c语言中,指针和数组的关系十分密切。通过数组下标能完成的任何操作都可以通过指针来实现。一般来说,用指针写的程序比用数组下标写的程序执行速度快一些,但另一方面,用指针实现的程序理解起来稍微困难一些。
int a[10];
int *pa;
pa = &a[0]; /* 指针pa指向数组a的第0个元素,也就是说,pa的值为数组a[0]的地址。*/
因为数组名所代表的就是该数组最开始的一个元素的地址。
所以 pa=&a[0];等价于:pa = a;
a[i] 等价于:*(a+i); /* a[i]在c语言内部表示为*(a+i) */
&a[i] 等价于:a+i;
pa[i] 等价于:pa+i;
但是,我们必须记住,数组名和指针之间有一个不同之处。指针是一个变量,因此,在c语言中,语句pa=a和pa++都是合法的。但数组名不是变量,因此,类似于a=pa和a++形式的语句是非法的。
3.地址运算
有效的指针运算包括相同类型指针之间(也可以是两个指针之一是void*类型的情况)的赋值运算;指针同整数之间的加法或减法运算;指向相同数组中元素的两个指针间的减法或比较运算;将指针赋值为0或者指针与0之间的比较运算。其他所有形式的指针运算都是非法的。
4.字符指针
字符串常量是一个字符数组。在字符串的内部表示中,字符数组以空字符'\0'结尾。所以,程序可以通过检查空字符找到字符数组的结尾。
下面这两个定义有很大差别:
char amessage[] = "now is the time"; /* 定义一个数组 */
char *pmessage = "now is the time"; /* 定义一个指针 */
amessage是一个仅仅足以存放初始化字符串以及空字符'\0'的一维数组。数组中的单个字符可以进行修改,但amessage始终指向同一个存储位置。另一方面,pmessage 是一个指针,其初值指向一个字符串常量,之后他可以被修改为指向其他地址,但如果试图修改字符串的内容,结果是没有定义的。
5. 指针数组
其实也不能理解。
char *lineptr[MAXLINE];
他表示lineptr是一个具有MAXLINE个元素的一维数组,其中数组的每个元素是一个指向字符类型对象的指针。也就是说,lineptr[i]是一个字符指针,而*lineptr[i]是该指针指向的第i个文本行的首字符。
所以lineptr本身就是一个数组名,只不过它保存的是一些指针。存储的内容不同而已。
再如:
int a[10][20];
int *b[10];
对a来说,是分配了200个int型的空间。
而对b来说,该定义仅仅分配了10个指针,并且没有初始化他们。他们的初始化必须显式进行。
其中[]的优先级高于*的优先级。
所以,int *b[10]; 同int (*b)[10];是完全不一样的。
对于int *b[10]; b是一个数组名,数组内有10个整型指针。
对于int (*b)[10],意味着b是一个指针,他指向具有10个整型元素的一维数组。
int b[2][10]; int b[][10]; int (*b)[10] ;等价的。
一般来说,除数组的第一维(下标)可以不指定大小,其余各维都必须明确指定大小。
分享到:
相关推荐
### 深度帮助理解指针 #### 一、C语言中的指针声明与特性 在C语言中,指针是一种特殊的数据类型,它存储的是内存地址而不是具体数据。掌握指针的使用对于深入理解程序运行机制至关重要。下面通过几个具体的例子来...
### 指针深入理解:解析与应用 在计算机编程领域,尤其是C和C++语言中,指针是一个核心概念,它提供了对内存地址的直接访问能力,是实现...深入理解指针的特性和正确使用指针,是成为一名高效、安全的程序员的关键。
### 彻底理解指针,指针数组和数组指针,指针函数和函数指针 #### 一、基础知识 在计算机编程中,指针是一个非常重要的概念,尤其是在C/C++这样的语言中更是如此。简单来说,指针是一种变量,但它存储的不是普通的...
### 深入理解指针 #### 一、引言 指针是计算机编程中一个非常重要的概念,尤其是在C和C++这样的低级语言中。本文将深入探讨指针的基本概念及其应用,帮助读者更好地理解和掌握指针。文章首先解释了指针的基本定义...
### 理解指针(C) 在C语言中,指针是一个强大的概念,它能够直接操作内存地址,实现高效的数据处理与管理。本文将深入探讨C语言中的指针概念,解析不同类型的指针以及它们的用法,帮助读者更好地理解和运用指针。 ...
要深入理解指针,需要掌握四个方面:指针的类型、指针所指向的类型、指针的值以及指针本身所占据的内存区。 #### 指针的类型 指针的类型指的是指针本身的数据类型,它定义了指针可以指向什么类型的数据。确定指针...
了解这一点之后,我们才能更好地理解指针和地址的概念。 #### 内存与地址 在计算机科学中,内存被视为一系列连续的存储单元。每个存储单元都有一个唯一的标识符——地址。这个地址用来唯一确定内存中的每一个字节...
[C语言] 指针的详解与应用-理论结合实践,真正理解指针!
本程序旨在帮助C++初学者深入理解指针的工作原理、用途以及如何安全有效地使用它们。 首先,我们要明白指针的本质。指针是一个变量,它存储的是另一个变量的地址,即内存中的位置。在C++中,通过声明指针变量并使用...
深入理解指针在C语言中的应用.pdf
理解指针的本质和使用方法对于编写高质量的C语言代码至关重要。下面我们将详细探讨指针的四个关键方面:指针的类型、指针所指向的类型、指针的值和指针本身所占据的内存区。 1. **指针的类型**:指针的类型定义了它...
对照https://wenku.baidu.com/view/2c55a61d227916888486d794.html 分析理解
### 彻底理解C语言中的指针与地址 在深入探讨C语言中指针与地址的概念之前,我们先明确一个基本的事实:计算机编程的核心在于管理内存。无论是简单的数据类型还是复杂的结构体,所有的一切最终都会转化为内存中的...
透彻理解指针:int a[3] = {2,5,8}; int* p = a; 把数组名赋值给指针表示将数组的首元素的地址赋予此指针。
即从右向左读取指针声明,帮助理解指针的类型和指向的对象。 #### 复杂指针声明的合法性 并非所有的指针声明都是合法的。例如,某些复杂的多重指针声明可能会导致编译错误。编写时需确保遵循C语言规范。 通过深入...
然而,想要全面理解指针,除了要对C语言有熟练的掌握外,还要有计算机硬件以及操作系统等方方面面的基本知识。所以我想通过一篇文章来尽可能的讲解指针,以对得起这个文章的标题吧。可以帮大家正确理解C语言中的常量...
理解指针涉及到四个主要方面:指针的类型、指针所指向的类型、指针的值(或称为指针所指向的内存区)以及指针本身所占据的内存区。 首先,指针的类型指的是指针变量自身的类型,这决定了指针变量可以存储哪种类型的...
深入理解C语言指针,详细讲解各种指针的运用及示例运用,准确,易懂。
首先,理解指针首先需要认识到计算机内存是如何组织的。计算机中的内存可以类比为一间巨大的、排满一个个小格子的库房,每一个格子可以存储一个字节的数据。每个格子都有一个唯一的地址编号,这就像我们的门牌号一样...
指针经典指针经典指针经典指针经典