C语言指针
2021-05-06 04:30
标签:类型 综合 字符 结合 错误 复制 接受 int mes 先来定义如下的二维数组: 首先,对于一个数组而言,数组名就是该数组的首地址。 首地址:一段存储空间中的第一个存储单元的地址 所以对于这个二维数组 输出如下: 可以看到,每 输出如下: 可以看到,每 所以 输出如下: 输出如下: 由于 亦即 综合上面的分析,对于二维数组 类型 (*指针名)[N]; //N元素个数 指针数组最主要的用途是处理字符串。在 C 语言中,一个字符串常量代表返回该字符串首字符的地址,即指向该字符串首字符的指针常量,而指针数组的每个元素均是指针变量,故可以把若干字符串常量作为字符指针数组的每个元素。通过操作指针数组的元素间接访问各个元素对应的字符串。 结构指针是指向结构的指针,使用 C语言的所有参数均是以“传值调用”的方式进行传递的,这意味着函数将获得参数值的一份拷贝。这样,函数可以放心修改这个拷贝值,而不必担心会修改调用程序实际传递给它的参数。 传值调用:实参为要处理的数据,函数调用时,把要处理数据(实参)的一个副本复制到对应形参变量中,函数中对形参的所有操作均是对原实参数据副本的操作,无法影响原实参数据。且当要处理的数据量较大时,复制和传输实参的副本可能浪费较多的空间和时间。 传址调用:顾名思义,实参为要处理数据的地址,形参为能够接受地址值的“地址箱”即指针变量。函数调用时,仅是把该地址传递给对应的形参变量,在函数体内,可通过该地址(形参变量的值)间接地访问要处理的数据,由于并没有复制要处理数据的副本,故此种方式可以大大节省程序执行的时间和空间。 传值调用的好处是是被调函数不会改变调用函数传过来的值,可以放心修改。但是有时候需要被调函数回传一个值给调用函数,这样的话,传值调用就无法做到。为了解决这个问题,可以使用传指针调用。指针参数使得被调函数能够访问和修改主调函数中对象的值。 有时函数调用结束后,需要函数返回给调用者某个地址即指针类型,以便于后续操作,这种函数返回类型为指针类型的函数,通常称为指针函数。在处理字符串中常见。 函数像其他变量一样,在内存中也占用一块连续的空 间,把该空间的起始地址称为函数指针。而函数名就是该空间的首地址,故函数名是常量指针。可把函数指针保存到函数指针变量中。 返回类型(*指针变量名)(函数参数表); 定义如下函数 在给函数指针变量赋值时,函数名前面的取地址操作符 & 可以省略。因为在编译时,C 语言编译器会隐含完成把函数名转换成对应指针形式的操作,故加 & 只是为了显式说明编译器隐含执行该转换操作。 当函数指针变量p2被初始化,指向f1之后,调用f1(),有以下几种方式 下面的程序,是一个应用函数指针的例子。 C语言指针 标签:类型 综合 字符 结合 错误 复制 接受 int mes 原文地址:https://www.cnblogs.com/oasisyang/p/13190215.html指针的运算
p1
, p2
相减时,p2-p1
就是从p1
到 p2
,不包含p2
的元素个数,结果的类型是ptrdiff_t
#include
指针与数组(数组指针)
int a[3][4] =
{
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};
a的意义
a[3][4]
,数组名a
指向的就是第一个数组,用如下代码可以进行验证: printf("a=%p\n", a);
printf("a+1=%p\n", a + 1);
printf("a+2=%p\n", a + 2);
a=000000C63835F628
a+1=000000C63835F638
a+2=000000C63835F648
+1
地址递增16
。a
是数组名,是该数组的首地址,
指向该数组的第一个存储单元(一个一维数组),a类型为 int(*)[4]
所以a+1
会跳到第二个数组,地址加上16B
*a的意义
printf("*a=%p\n", *a);
printf("*a+1=%p\n", *a + 1);
printf("*(a+1)=%p\n", *(a + 1));
*a=000000C63835F628
*a+1=000000C63835F62C
*(a+1)=000000C63835F638
+1
地址递增4
。*a
指向以一个一维数组的首地址即
*a==a[0]==&a[0][0]
*a+1
,地址会偏移4B
,即指向下一个数据,
*a
类型为int*
*(a+1)
,地址会偏移16B
,即指向下一个一维数组的首地址。&a的意义
printf("&a=%p\n", &a);
printf("&a+1=%p\n", &a + 1);
printf("&(a+1)=ERORR\n");
&a=000000C63835F628
&a+1=000000C63835F658
&(a+1)=ERORR
&a
指向整个二维数组,是取这个二维数组的地址。
&a
类型为 int(*)[3][4]
&a+1
地址偏移了48B
,跳过了整个二维数组&a[0]的意义
printf("&a[0]=%p\n", &a[0]);
printf("&a[0]+1=%p\n", &a[0] + 1);
printf("&a[0]+1=%p\n", &a[0]);
printf("&(a[0]+1)=ERORR\n");
&a[0]=000000C63835F628
&a[0]+1=000000C63835F638
&a[0]+1=000000C63835F628
&(a[0]+1)=ERORR
&a[0]
指向第一个数组,是取第一个数组的地址
&a[0]类型为 int(*)[4]
&a[0]+1
地址偏移了16B,跳过了第一个一维数组a[0]的意义
printf("a[0]=%p\n", a[0]);
printf("a[0]+1=%p\n", a[0] + 1);
printf("&a[0][0]%p\n", &a[0][0]);
a[0]
是第一个数组的数组名,是第一个数组的首地址,即a[0]
指向指向第一个存储单元a[0][0]
a[0]
类型为 int*
a[0]+1
,指向了第二个存储单元,地址偏移了4B
&a[0][0]
,是指向a[0][0]
的指针,
&a[0][0]
类型为 int*
指针数组
int *p[10]
[]
的优先级比 *
高,故 p
先与 []
结合,成为一个数组 p[]
;再由 int *
指明这是一个 int
的指针。数组的第 i
个元素是 *p[i]
,而 p[i]
是一个指针。数组指针
int (*p)[10]
()
的优先级最高,所以 p
是一个指针,指向一个 int
类型的一维数组,这个一维数组的长度是 10
,这也是指针 p
的步长。也就是说,执行 p+1
时,p 要跨过10
个 int
型数据的长度。数组指针与二维数组联系密切,可以用数组指针来指向一个二维数组,如下:#include
访问数组中的元素
1. 下标法
printf("a[i][j]\n");
printf("a[i][j]\n");
for (int i = 0; i
2. 指针法
printf("1:*(a[i]+j)\n");
for (int i = 0; i
printf("2:*(*(a+i)+j)\n");
for (int i = 0; i
a[i][j]==*&a[i][j]==*(a[i]+j)==*(*(a+i)+j)
a[3][4]
有如下结论:
表达式
数据类型
指向
a==&a[0]
int(*)[4]
均指向第一个一维数组
a[0]==&a[0][0]
int*
均指向第一个一维数组的第一个单元
&a
int(*)[3][4]
指向整个二维数组
*(a+i)=a[i]=&a[i][0]
int*
指向数组i的第一个存储单
运算
意义
a+1
a
指向第一个一维数组,所以a+1
地址偏移4x4=16B
*a+1
*a
指向第一个数组的第一个单元,所以*a+1
地址偏移4B
*(a+1)
a+1
指向下一个数组,*a==a[0]---->*(a+1)==a[1]
所以a+1地址偏4x4=16B
&a+1
&a
指向整个二维数组,所以&a+1
地址偏移4x4x3=48B
&(a+1)
数组名
a
是指针常量,不能更改了,此种写法错误
&a[0]+1
&a[0]
指向第一个数组,&a[0]+1---->&a[1]
,指向下一个数组,所以地址偏移4x4=16B
&(a[0]+1)
此种写法错误
a[0]+1
a[0]
指向第一个数组的首地址a[0][0]
,所以a[0]+1
指向下一个数据a[0][1]
,地址移4B
数组指针
数组指针是指向含 N 个元素的一维数组的指针。由于二维数组每一行均是一维数组,故通常使用指向一维数组的指针指向二维数组的每一行。
[]
运算的优先级高于*
,int *p[N]
为指针数组,每个元素类型为 int*
#include
指针数组
#include
注意:
*a==a[0]==&a[0][0]
*(a[i]+j)
==*(*(a+i)+j)
结构指针
->
操作符来访问结构指针的成员。#include
指针与函数
指针作为函数的参数
#include
指向函数的指针
指针做函数返回值 类型*函数名(形参)
#include
指向函数的指针————函数指针
定义中,括号不能省略。int *p1(int,int)//声明了函数原型,函数名为p1,含有俩int参数,返回值int*
int (*p2)(int,int)//定义了一个函数指针变量p2,p2指向任意含有俩int参数,返回值为整型的函数
int f1(int a,int b)
{
//...
}
p2=f1//p2=&f1;
int res;
res=f1(a,b);
res=p1(a,b);
res=(*p1)(a,b)
#include
上一篇:用JSON 传输byte数组