指针基本用法
在C语言中,内存单元的地址称为指针,专门用来存放地址的变量,称为指针变量。
指针的作用:
- 使程序简洁、紧凑、高效;
- 有效地表示复杂的数据结构;
- 动态分配内存;
- 得到多于一个的函数返回值。
格式:
<存储类型> <数据类型> * <指针变量名> ;
指针的存储类型是指针变量本身的存储类型。
初始化:
<存储类型> <数据类型> *<指针变量名> = <地址量> ;
例如:
int x, *px = &x;
int a[20],*pa;
pa = a;//等价 pa = &a[0];

引入指针要注意程序中的px、*px 和 &px 三种表示方法的不同意义。设px为一个指针,则:
- px:指针变量, 它的内容是地址量
- *px:指针所指向的对象, 它的内容是数据
- &px:指针变量占用的存储区域的地址,是个常量

char *p = &a;
printf("a=%d\n",a);/* 打印a变量存储的值 */
printf("&a=%p\n",&a);/* 打印a变量存储空间的首地址 */
printf("p=%p\n",p);/* 打印p变量存储的值,打印地址格式用%p */
printf("&p=%p\n",&p);/* 打印p变量存储空间的首地址*/
printf("*p=%d\n",*p);/* 打印p指向的存储空间中存储的值*/
printf("a=%d,*p=%d,*&a=%d,**&p=%d\n",a,*p,*&a,**&p);/* 使用所有可以表示a数据值的打印方法 */
printf("&a=%p,p=%p\n",&a,p);/* 使用所有可以表示a存储空间首地址的打印方法 */
指针运算
| 运算符 | 计算形式 | 说明 |
|---|---|---|
| + | px+n | 指针向地址大的地方移动n个数据 |
| - | px-n | 指针向地址小的地方移动n个数据 |
| ++ | px++ 或 ++px | 指针向地址大的地方移动1个数据 |
| – | px-- 或 --px | 指针向地址小的地方移动1个数据 |
| - | px-py | 两个指针之间相隔数据元素的个数 |


指针运算关系:
- 两指针之间的关系运算表示它们指向的地址位置之间的关系。指向地址大的指针大于指向地址小的指针。
- 指针与一般整数变量之间的关系运算没有意义。但可以和零进行等于或不等于的关系运算,判断指针是否为空。

int a[] = {5, 8, 7, 6, 2, 7, 3};
int y, *p = &a[1];
y = (*--p)++;
printf(“% d ”, y);//5
printf(“% d”, a[0]);//6
指针与数组
在C语言中,数组的指针是指数组在内存中的起始地址,数组元素的地址是指数组元素在内存中的起始地址。
一维数组的数组名为一维数组的指针(起始地址) 。
例如:
int x[8];
因此,x为x数组的起始地址。
int *px = x;
x[i] = *(px+i) = *(x+i) = px[i]
- 指针变量和数组在访问数组中元素时,一定条件下其使用方法具有相同的形式,因为指针变量和数组名都是地址量;
- 但指针变量和数组的指针(或叫数组名)在本质上不同,指针变量是地址变量,而数组的指针是地址常量。
观察以下输出结果。
int i = 2;
int a[10]={1,3,5,7,9,11,13,15,17,19}, *p = &a[i];
//printf("*p++ = %p,a[i++]=%p\n", *p++, a[i++]);
//*p++ = 00000005,a[i++]=00000005
//printf("*p++ = %d,a[i]++ = %d\n", *p++, a[i]++);
//*p++ = 6,a[i]++ = 5
//printf("*p++ = %p,a[i] = %p\n", *p++, a[i]);
//*p++ = 00000005,a[i] = 00000005
printf("*p++ = %d,a[++i] = %d\n", *p++, a[++i]);
//*p++ = 5,a[++i] = 7
指针与二维数组
二维数组看作由多个一维数组组成。

二维数组名代表数组的起始地址,数组名加1,是移动一行元素。因此,二维数组名常被称为行地址。

行指针(数组指针)
存储行地址的指针变量,叫做行指针变量。形式如下:
<存储类型> <数据类型> (*<指针变量名>)[表达式] ;
例如:int a[2] [3]; int (*p)[3];
方括号中的常量表达式表示指针加1,移动几个数据。
当用行指针操作二维数组时,表达式一般写成1行的元素个数,即列数。
例子:输入数据,求出最大值及坐标。
#include <stdio.h>
int main()
{
int a[3][4];
int(*p)[4] = a;
int m = 3, n = 4;
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
scanf("%d", *(p + i) + j);
}
int pR = 0, pC = 0;
int max = (*p)[0];
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
if (*(*(p + i) + j) > max)
{
max = *(*(p + i) + j);
pR = i;
pC = j;
}
}
}
printf("max = %d :r = %d,c=%d\n", max, pR + 1, pC + 1);
return 0;
}
指针与字符串
初始化:
初始化字符指针是把内存中字符串的首地址赋予指针,并不是把该字符串复制到指针中
char str[] = “Hello World”;
char *p = str;
在C编程中,当一个字符指针指向一个字符串常量时,不能修改指针指向的对象的值
char * p = “Hello World”;
*p = ‘h’; // 错误, 字符串常量不能修改。
例子:求字符长度。
#include <stdio.h>
int main()
{
char x[] = "smalldragon";
char *y = x;
while (*y != '\0')
{
y++;
}
printf("%d", y - x);
return 0;
}
11万+





