指针与数组
文章目录
指针是一种保存变量地址的变量。
1 指针与地址
1.1 内存组织
通常的机器都有一系列连续编号或编址的存储单元,这些存储单元可以单个进行操纵,也可以以连续成组的方式操纵。通常情况下,机器的一个字节为8位。指针是能够存放一个地址的一组存储单元(通常为4字节)。
1.2 运算符
一元运算符&可用于取一个对象的地址。p = &c;
把c的地址赋值给变量p,成p为指向c的指针。&只能用于内存中的对象(变量和数组元素),不能用于表达式、常量或寄存器变量。
一元运算符*是简介寻址或间接引用运算符。当它作用于指针时,将访问指针所指向的对象。
1.3 指针声明
指针只能指向某种特定类型的对象,即每个指针都必须指向一种特定的数据类型。
数据类型 *指针名
2 指针与函数参数
C语言以传值方式将参数值传递给被调用函数,因此被调用函数不能直接修改主调函数中变量的值。
指针参数使得被调用函数能够访问和修改主调函数中对象的值。
3 指针与数组
通过数组下标所能完成的任何操作都可以通过指针来实现。用指针编写的程序比用数组下标编写的程序执行速度快。
3.1 数组声明
int a[10];
定义了一个长度为10的数组a,即由10个对象组成的集合,这10个对象存储在相邻的内存区域中。int *pa; pa = &a[0];
表示指针pa指向数组a的第0个元素。pa+1;
表示指向pa所指向的对象的下一个对象。pa = a;
数组名代表的就是该数组最开始的一个元素的地址。pa[i]
等价于*(pa+i)
。数组名不是变量,故给数组名赋值的语句是非法的。
在函数定义中,形式参数char s[]
和char *s
是等价的。
4 地址算术运算
指针可以初始化,通常对指针有意义的初始化只能是0(NULL)或者是表示地址的表达式,此地址必须是在此前已定义的具有适当类型的数据的地址。
指针与指针之间不能互相转换,但0是唯一的例外,常量0可以赋值给指针,指针也可以和常量0进行比较。常用符号常量NULL代替常量0。
某些情况下可以对指针进行比较运算,例如两个指针指向同一个数组的成员,则它们之间可以进行==、!=、<、>=等关系比较运算。
指针可以和整数进行相加或相减运算。
5 字符指针与函数
字符串常量是一个字符数组,如:“I am a string”,字符串常量以空字符 ‘\0’ 结尾。字符串常量可以通过一个指向其第一个元素的指针访问。
//将字符数组的指针赋值给ps,并未进行字符串的复制
char *ps;
ps = "it is a string";
/* 定义一个数组 */
char a[] = "now is the time";
/* 定义一个指针 */
char *pa = "now is the time";
strcat函数:
void strcat(char *s, char *t)
{
while(*s != '\0')
s++;
//循环结束后s指向字符'\0'
while(*s++ = *t++)
;
//循环结束后s指向字符'\0'
}
strcpy函数:
若使用语句s=t实现,其实质上只是拷贝了指针,并没有复制字符。
/* 将指针t指向的字符串复制到指针s指向的位置 */
void strcpy(char *s, char *t){
while(*s++ = *t++)
;
}
//表达式同'\0'比较是多余的,if(*s++ = *t++)与if((*s++ = *t++) != '\0')是等价的
strcmp函数:
/* 根据s按照字典顺序小于、等于或大于t的结果分别返回负整数、0或正整数 */
int strcmp(char *s, char *t){
for(; *s == *t; s++, t++)
if(*s == '\0')
return 0;
return *s - *t;
}
6 指针数组及指向指针的指针
7 多维数组
二维数组是一种特殊的一维数组,它的每个元素也是一个一维数组。若将二维数组作为参数传递给函数,则在函数的参数声明中必须指明数组的列数。因为函数调用时传递的是一个指针,它指向由行向量构成的一维数组。
int a[2][13];
int a[][13];
//指向具有13个整型元素的数组的指针,数组指针
int (*a)[13];
//该数组有13个指向整型的指针元素,指针数组
int *a[13];
指针数组的初始化
7.1 指针与多维数组
int a[10][20];
int *b[10];
a是真正的二维数组,它分配了200个int类型长度的存储空间,并且通过矩阵下标计算公式20*row+col
(row表示行,col表示列)计算得到a[row][col]
的位置。而b只是分配了10个指针,并且没有对她们初始化,优点在于数组每一行长度可以不同。
8 指向函数的指针
在C语言中,函数本身不是变量,但可以定义指向函数的指针。
//指向无返回值,有一个int参数的函数的指针,函数指针
void (*fun)(int);
//返回无类型指针的函数,指针函数
void *fun(int);
9 复杂声明
在C语言中,函数本身不是变量,但可以定义指向函数的指针。
//指向无返回值,有一个int参数的函数的指针,函数指针
void (*fun)(int);
//返回无类型指针的函数,指针函数
void *fun(int);