11.物联网学习之C语言指针,数组指针,指针数组,函数指针,指针函数

本文介绍了C语言中的指针概念,包括指针作为地址,指针运算的规则,以及指针与数组的关系。特别强调了指针和数组地址的区别,指针可以修改,而数组名是常量。还讨论了多级指针、指针数组、函数指针以及void指针的用法,并提到了const修饰符在指针中的应用。最后,文章通过main函数参数和指针函数的例子,展示了指针在实际编程中的运用。
摘要由CSDN通过智能技术生成

指针

  1. 如何知道数组大小

int a[] = { 1,2,3,4,5 };

char s[] = {'a','b','c','d','e'};

int n, m;

n = sizeof(a) / sizeof(int);

m = sizeof(s) / sizeof(char);

  1. 指针概念(什么是指针?)

简洁说法:指针是地址

详细说明:在C语言中,内存单元的地址称为指针,专门用来存放地址的变量,称为指针变量

  1. 指针运算

指针运算是以指针变量所存放的地址量作为运算量而进行的运算

指针运算的实质就是地址的计算

指针运算的种类是有限的,它只能进行赋值运算、算术运算和关系运算

  1. 指针运算

注意:(1)指针p++,--p;(2)数组a[10],a++错误

原因:p为指针地址,是变量可以改变,a是数组地址,是常量,不可以改变

  1. 指针与数组

char str={“Hello World”};

4.1<指针变量>char* p=str; //可修改,原因如下

------------错误--const char*不能初始化char*----------------------------------------------------------

4.2<数组的指针> char* p=“Hello World”; //不可修改,原因如下

注意:(1)char* p=“Hello World”;在新版已经不可用,必须const char* p=“Hello World”;防止字符串常量被修改.

(2)printf(“%s”,*p);错误,%s输出的是地址,应该是printf(“%s”,p);

两者区别:

1.(同)<指针变量>和<数组的指针/数组名>在访问数组中元素时,一定条件下其使用方法具有相同的形式,因为指针变量和数组名都是地址量

2.(区)<指针变量>和<数组的指针(或叫数组名)>在本质上不同,指针变量是地址变量,而数组的指针是地址常量,而地址常量不能修改,因为在静态储存区,所以数组的指针char* p=“Hello World”;不能修改字符,只能重新指向其他字符串

静态存储区:不能修改,且在程序运行时不会失效

处在静态存储区的变量:(1)全局变量(2)static静态变量(3)字符串常量(char* p=“Hello World”;)

5.一级指针遍历二级数组

int a[4][3] = { {1,2,3},{2,3,4},{3,4,5},{4,5,6} };

int* p=a[0];

printf("%d %d\n", *(p + 1), a[0][1]);

注意:

(1)二级数组地址连续,a[0]与p都是同型地址,即加一地址一样(a[0]+1与p+1地址一样),所以可以赋值运算.

(2)a与p不是同型地址,即(pinrtf("%p"),a+1);(pinrtf("%p"),a+1);不一样,a+1地址加3个地址 单位,p+1加1个地址单位),所以不可赋值.

(3)1个地址单位在32位中是4字节,在64位为8字节.

5.1 printf("%d %d\n", a[0][0], a[1][0]);

printf("%d %d\n", *a[0], (*a+1)[0]);

两者等价,a[0]可以用*a直接替代

  1. 数组指针(行指针)

简言之:指向数组的指针,使用后等价数组

int a[2][3];  int (*p)[3];p=a;

之后就可以p替代a,例如p[0][0]替代a[0][0]

行指针(数组指针)存储行地址的指针变量,叫做行指针变量。

注意:数组指针int (*p)[3];相当于数组

6.指针数组

简言之: 若干指针变量构成集合

详细: 指由若干个具有相同存储类型和数据类型的指针变量构成的集合

Int * p[2],a[2][3];

p[0]=a[0];p[1]=a[1];

这样p[0]指针指向a[0],p[1]指针指向a[1]

7.多级指针

7.1多级指针基本用法

Int a=10;

Int* p=&a;

Int* * pp=&p;

7.2多级指针与指针数组结合

Int a[]={3,6,9};

Int* p[2]={&a[0],&a[1]};

Int* *q=p;//等价int* *q=&p[0]

这样就组成了多级指针

**q  *p[0]  a[0]相互等价

**(q+1)  *p[1]  a[1]相互等价

7.3多级指针与字符串的结合

char *s={“apple”,”pear”};

char **p=s;//p=&s[0];

  1. void指针

void指针是一种不确定数据类型的指针变量,它可以通过强制类型转换让该变量指向任何数据类型的变量

int* m=10;

double n=3..14;

void *p,*q;

p=(void *)&m;//也可以不强制转换 p=&m;即可

printf(“%d %d\n”,m,*(int *)p);

q=(void *)&n;

printf(“%.2f %.2f\n”,n,*(double*)p);

注意:

  1. 在输出的时候需要强制转换

原因:int占4字节,double占8字节,void类型不知道要找4地址还是8地址,所以转换

  1. void指针,在没有强制类型转换之前,不能进行任何指针的算术运算

不强制转换时不能运算处理,即q++,q+1;操作不可

原因:void类型指针不知道指向哪里了,随机

8.1void遍历数组

int a[]={1,2,3,4,5};

void * p;

for(int i;i<n;i++){

printf(“%d”,*((int*)p+1));

}

注意:先强制类型转换,再加偏移量i,加*变指针

  1. const变量

int m=10;

const int *p=&m;

(*p)++;-->error: const修饰后,变量变为常量,不能修改

int * const q;

q=&m;-->error:const在中间,指针不能修改指向

解决: int* const q=&m;直接一开始就指向m;

<结论>:const修饰谁,谁不能修改

const int *p=&m;//修饰*p,*p不能改

int * const q;//修饰q,q不能改

const int* const rn=&m;//const修饰*rn,修饰rn,所以不能修改*rn,rn

10.main函数参数的讲解

<运行时输入>  ./a.out 192.168.1.7 6000

int main(int argc,const char* argv[]){

printf(“argc=%d”,argc);

<输出>argc=3 原因:我输入三个参数(./a.out,ip地址,6000)

for(int i=0;i<argc;i++){

printf(“%s\n”,argv[i]);

<输出>我输出的三个参数(./a.out,ip地址,6000)

}

return 0;

}

  1. 指针函数

简言之:函数的返回值为地址量的函数

#include <stdio.h>

#include <string.h>

char *  mystring( )  {

 char str[20];

 strcpy(str, “Hello”);

 return str;

}

int  main(void)

{

 printf(“%s\n”, mystring());

     return 0;

}

//错误点

(1)mystring()函数的char str[20];在函数结束失效,内容清除,所以接收不到

(2)解决方式:1.str[20]改成全局变量2.static变量的地址3.字符串常量地址(char* str=”hello”)4.堆地址(malloc申请地址)

  1. 函数指针

简言之:指向函数的指针

函数指针用来存放函数的地址,这个地址是一个函数的入口地址

函数名代表了函数的入口地址

int add(int a, int b) {

return a + b;

}

int main() {

int (*p)(int, int);//函数指针

p = add;

printf("%d", (*p)(6, 10));

return 0;

}

12.1函数指针数组

函数指针数组是一个保存若干个函数名的数组

int add(int a, int b) {

return a + b;

}

int sub(int a, int b) {

return a - b;

}

int main() {

int (*p[2])(int, int);

p[0] = add;

p[1] = sub;

printf("%d", (*p[0])(6, 10));

printf("%d", (*p[1])(6, 10));

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值