C - Language | Pointer


地址

" 地址 "是内存区中对每字节的编号(地址指向内存单元)

指针

声明变量时,会在内存中为变量分配一个" 地址 ",通过访问这个" 地址 "就可以找到对应的变量,这个变量的" 地址 "为该变量的" 指针 "

变量的" 地址 "为变量的" 指针 "

" 指针 "可以" 指向 "变量、数组、字符串、函数以及指针

访问

存取变量值的方法大致分为" 直接访问 "、" 间接访问 "两种

直接访问

" 直接访问 "是通过变量" 地址 "存取变量值的方式

间接访问

将" 变量地址 "存放在另一个变量中,先找到存放变量地址的另一个变量(通过另一个变量找到变量地址)的,为" 间接访问 "

指向

星号" * "关键字表示" 指向 "," 指向 "的行为由" 地址 "实现

变量

变量的" 地址 "是变量和" 指针 "之间连接的纽带

若变量(a)包含了变量(b)的地址,则变量(a)指向变量(b)

int a;int b;
a+b;					/*根据变量标识符与变量" 地址 "的对应关系,找到变量" a "的" 地址 ",并从其地址位向后读取4字节数据,存放到CPU的某一寄存器中;							再找到变量" b "的" 地址 ",从其地址为向后读取4字节数据,存放到CPU的另一寄存器中;最后CPU的加法中断计算出结果*/

//在" 低级语言 "、" 汇编语言 "中,都是直接通过" 地址 "来访问内存单元的

指针变量

" 指针变量 "是指向变量" 地址 "的变量(" 指针变量 "用来存放另一个变量的" 地址 ")

声明

声明指针变量的格式,包括:" 类型说明 "、指针变量声明关键字" * "、" 变量标识符 "三个部分

类型说明 *变量标识符					/*类型说明代表指向变量的数据类型,关键字" * "代表此声明变量为" 指针变量 "*/
char _a;
char *a=&_a;
char _b;
char *b;
b=&_b;					/*如果已经声明指针变量,再调用时不要带关键字" * "*/

" 指针变量声明关键字 "与" 指针运算符(取值运算符) "不同;" 指针变量声明关键字 "为" 关键字 ",而" 指针运算符(取值运算符) "是" 运算符 "

赋值

指针变量的值,只能为" 指针 "类型

使用地址运算符" & "取出地址

char a;
char *p = &a;

不允许把" 数 "赋值给指针(只能为" 指针 "类型)

调用

调用指针变量是对变量进行间接访问

*指针变量;
*a;					/使用" 指针运算符(取值运算符) "*调用指针变量所" 指向 "的值*/

自增自减

指针变量的" 自增自减 "是根据指针变量所指向地址的" 直接长度 "进行增加或减少的(地址的" 直接长度 "由" 数据类型 "决定)

int a;
int *p=&a;
p++;					/*一般有符号整数类型的" 直接长度 "为4字节,指针" p "向后移位4字节(自加)*/
p--;					/*一般有符号整数类型的" 直接长度 "为4字节,指针" p "向前移位4字节(自减)*/

数组指针

" 数组指针 "为指向数组的指针变量

在内存中,数组的标识符保存的是其在内存空间的" 首地址 ",若将数组的首地址传给指针变量,则指针变量指向对应数组

int *p,a[1];
p=a;					/*数组标识符" a "为数组的" 首地址 ",指针" p "被赋值并指向" a "数组内存空间的" 首地址 "*/
int *p,a[3];
p=a[0];					/*" a[0] "是数组" a "的首地址,即操作与" p=a; "相同*/

指针变量直接调用数组标识符时,目标数组一定要进行定义(确定数组元素个数),否则无法调用第一个数组标识符(数组标识符=数组第一个元素的地址)

调用数组元素

用指针的方式调用数组元素,需要采用" 目标数组表示符 "+" 偏移地址 "的方法,先得到数组元素地址,最后用" 取值运算符 "取出

int *p,a[5];
p=a+2;					/*对于" 地址 "使用加法运算符或减法运算符,则是进行偏移多少" 直接长度 "的字节(最终值为地址)*/
printf("%d",*p);

调用二维数组元素与调用一维数组元素方法相同(存储空间中皆为一行数据)

int num[5][3]={
{1,2,3},
{1,2,3},
{1,2,3},
{1,2,3},
{1,2,3}
};
int *p1,*p2,*p3;
p1=&num[0][0];
p2=num+9;
p3=num;
for(int i1=0;i1<5;i1++)
{
	for(int i2;i2<3;i2++)
	{
		printf("%d\n",*p3++);
	}
}
printf("%d\n%d",*p1,*(p2+2));

字符串指针

调用字符可以是指针的方式

char *string="biboli";					/*声明字符型指针变量" string "并赋初值字符串常量(将字符串的第一个字符的" 地址 "存放到指针变量中)*/
printf("%s",string);
char *string;
string="biboli";
printf("%s",string);

char *string;
#define _string "biboli"
int count=strlen(_string);
string=_string;
for(int i=0;i<count;i++)
{
	printf("\n%c",*string++);
}

指针数组

数组元素皆为指针类型(指针变量)的数组,为" 指针数组 "

类型名 *指针数组标识符[数组长度]
char *string[]=
{
"biboli",
"king",
"weijunjie"
};
for(int i=0;i<3;i++){printf("%s\n",string[i]);}

" 字符串指针数组 "可以直接存储字符串

二层指针

" 二层指针 "变量,一种指向指针的指针变量,又叫" 指针的指针 "

" 二层指针 "变量的声明定义结构包括:" 终值数据类型标识符 **二层指针变量标识符"

终值数据类型标识符**二层指针标识符;
int **p;					/*根据结合性,等同于" int *(*p); ";声明定义指针变量" p "," p "指向另一个指针变量,最终指针变量所指向的值为" 基本有符							号整型变量 "*/

如果需要不同情况调用多个不同的指针变量,就用" 二层指针变量 "

char *string[3][3]=
{
	{"biboli","1","king"},
	{"king","2","weijunjig"},
	{"weijunjie","3","biboli"}
};
for(int x=0;x<3;x++)
{
	for(int i=0;i<3;i++){printf("%s\n",string[x][i]);}
}
char **p[3],*s1[7],*s2[7],*s3[8];
char s1={'b','i','b','o','l','i','\n'};
char s2={'k','i','n','g','w','e','\n'};
char s3={'i','j','u','n','j','i','e','\n'};
p={s1,s2,s3};
do
{
	printf(*p++);
}
while(33);

指针函数

返回指针的函数简称为" 指针函数 "

函数在编译时会被分配1个入口地址,这个函数入口地址,就是函数的" 指针 "

可用一个指针变量指向函数,然后通过该指针变量调用此函数

声明定义指针函数的表达式结构,包括:" 函数返回值类型 *函数标识符(形式参数列表); "

返回值类型 *函数标识符(形式参数列表);
int *fun(int x,int y);					/*调用" fun "指针函数能得到一个指向整型数据的指针(返回的指针指向整型变量)*/

指针形参

指针型变量也可以作为函数参数

指针类型变量也可以作函数返回值

指针也可以指向函数

main指针形参

运行C程序时,源文件中的主函数main作为程序的入口函数,在命令行状态运行C程序时,主函数main以及其实际参数,是一并传递的

命令名 参数 参数2 参数3 ... 参数n
D:\software\test.c biboli king wjj					/*命令行中的命令名就是可执行文件的文件名*/

指针数组" argc "记录了命令行中命令与参数的个数,指针数组的大小由参数值决定

main(int argc,char *argv[])					/*参数字符串长度不定,参数字符串长度不统一,参数字符串数目任意*/

函数指针

指针可以指向函数,函数在编译时会被分配一个入口地址,函数入口地址就被称为函数的指针

数据类型 (*指针标识符)(形式参数列表);
int a(int,int);{print("biboli");return b;}
int (*p)(int,int);
p=a;					/*函数指针的" 返回类型 "、" 形式参数列表 ",要与被指向函数保持一致(否则指向失败)*/

将指向函数的指针可以作为函数的参数

int a(int a,int b,int (*p)());
posted @ 2021-05-11 16:41  biboli  阅读(91)  评论(0编辑  收藏  举报