C语言指针知识点(嵌入式底层基础)

举报
刘斯淇 发表于 2022/05/18 00:19:24 2022/05/18
【摘要】 指针的重要性: 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧:


一、先说说指针的概念

要知道指针的概念,要先了解变量在内存中如何存储的。在存储时,内存被分为一块一块的。每一块都有一个特有的编号。而这个编号可以暂时理解为指针,指针的介绍其实和每个门店的门牌号一样,每次依次取出!

二. 举几个:简单的例子!指针的基本模样!(只有认识基本的模样你才能进行到本质)

(1)char*ptr;  

(2)int*(*ptr)[4];  

指针格式:基本类 *指针变量名.

这里得提一提这里的“基类型”,意为指针变量所指的变量的类型,不是指针变量的类型.

int *p2 (定义P2为整形变量的指针变量)
char *p3(定义P3为指向字符型变量的指针变量)
int(*ptr)[3];//指针的类型是int(*)[3]
int*(*ptr)[4];//指针的类型是int*(*)[4]

(想必找出指针类型应该挺简单的把!)但是一定要认知看这个指针的格式,后续对于学习C语言指针是非常重要的!

指针的值----或者叫指针所指向的内存区或地址
指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32 位程序里,所有类型的指针的值都是一个32 位整数,因为32 位程序里内存地址全都是32 位长。指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为si zeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX 为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的!

三.指针的赋值(有三种方式)

  • 1.通过取地址运算符(&)来获取地址(相当于取门牌)
  • 2.直接拿出门牌号开进行运算也行!
  • 你可以想象为把一个变量的地址赋值给指针变量!
  • #include<stdio.h>
    int main(){
     int a=5,*p *q;
    p=&a; 

      2.通过指指针变量获取地址值

使用赋值运算,把一个指针变量中的地址赋值给另一个指针变量,同时让两个指针变量都走像了同一个地址!但是这里要注意一个易错的点:赋值号两边指针变量的基类型必须相同!

      3.给指针变量赋值’空值‘

提一提NULL一般使用它需要带一个stdio.h的头文件!(其实也不那么重要)

NULL=*P;

四.指针和指针进行加减

两个指针不能进行加法运算,这是非法操作,因为进行加法后,得到的结果指向一个不知所向的地方,而且毫无意义。两个指针可以进行减法操作,但必须类型相同,一般用在数组方面,不多说了。

五.指针与数组

  1. 数组指针:是一个指针,该指针专门用来指向数组
  2. 指针数组:是一个数组
    int *p5[5] //指针数组
    int (*p1)[5];//数组指针
  3. 函数指针:是一个指针,用来存放函数的地址
  4. //指针变量:指向有一个int类型返回值,有两个int类型参数的函数指针变量
    int f(int left,int right)
    {
    	return 0;
    }
    int (*pf)(int left,int right);//函数指针变量

六.指针数组

这里会提到一个优先级的问题(后续有优先级的补充)还是直接上图片把!

优先级的重要性(你得明白是他是先和那个符号结合)

例如:int *p[30]; 

其中[]的优先级最高,表示它是一个数组。首先申请了一个空间为【10】的数组,然后数组里面存的是指向int类型的指针,p指向的是这个指针数组首地址的内存空间;

char *str[3]={  
    "Hello,thisisasample!",  
    "Hi,goodmorning.",  
    "Helloworld"  
};  
char s[80];  
strcpy(s,str[0]); 
strcpy(s,str[1]); 
strcpy(s,str[2]);   

上例中,str 是一个三单元的数组,该数组的每个单元都是一个指针,这些指针各指向一个字符串。把指针数组名str 当作一个指针的话,它指向数组的第0 号单元,它的类型是char **,它指向的类型是char *。
*str 也是一个指针,它的类型是char *,它所指向的类型是char,它指向的地址是字符串"Hello,thisisasample!"的第一个字符的地址,即'H'的地址。注意:字符串相当于是一个数组,在内存中以数组的形式储存,只不过字符串是一个数组常量,内容不可改变,且只能是右值.如果看成指针的话,他即是常量指针,也是指针常量.
str+1 也是一个指针,它指向数组的第1 号单元,它的类型是char**,它指向的类型是char*。
*(str+1)也是一个指针,它的类型是char*,它所指向的类型是char,它指向"Hi,goodmorning."的第一个字符'H'

七.数组指针也是需要初始化的!

(1)但是定义数组指针初始化时可以使用已经定义的数组的数组名来初始化数组的指针变量

(2)可以通过赋值初始化。将数组的首地址赋值给数组的指针变量

这里得说一说指针比较容易犯的错误:1.定义了指针变量,还没有指向任何变量就开始使用!

指针与二维数组!
指针可以指向一维数组,同时也可以指向二维数组。二维数组的指针是二维数组的地址(首地址)二维数组的指针变量就是存放二维数组地址的变量!(同样的使用下标访问,也可以使用指针访问,也可以使用下标与指针组合表示访问,

存放格式如下:

S+i:元素为数组的一位数组的第i个元素地址,即为*(s+i)=s[i];

即二维数组任何一个元素s[i][j]的地址都可以表示:

&s[i][j]=s[i]+[j]+j=*(s=i)+j

同时也可以为*(*(s+i)=j)

八.指针和函数的关系


可以把一个指针声明成为一个指向函数的指针。

int fun1(char *,int);
int (*pfun1)(char *,int);
pfun1=fun1;
int a=(*pfun1)("abcdefg",7);

//通过函数指针调用函数。
可以把指针作为函数的形参。在函数调用语句中,可以用指针表达式来作为实参。

#include<stdio.h>
int app(int *p){
	int str[]="qweasdzxc";
	int sum;
	sum=app(int *p);
}
int fun(int *p){
	int num=0;
	int i,j;
	for(i=0;i<9;i++){
		num+=*p;
		
	}
	return num;
}

后续我会再次说明指针的重要性文章!!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。