C语言之指针

C  Linux  2023年8月26日 am8:08发布1年前 (2023)更新 城堡大人
116 0 0

前言

记录一下C语言中的指针相关知识,算是回顾之前所学吧。

正文

指针

在C语言中,内存单元的地址称为指针。

专门用来存放地址的变量,称为指针变量。

存储类型  数据类型  *  指针变量名;
int a  = 10;
# 第一种
int *p = &a;
# 第二种
int *p; //默认有个地址,不知道赋值了什么
p = &a;

NULL指针

NULL指针是一个特殊的指针变量,表示不指向任何东西。

要使一个指针变量为NULL,直接赋值给他一个零值即可。为了测试一个指针变量是否为NULL,可以将它与零值进行比较。

对一个NULL指针进行解引用操作时非法的。因此,对指针进行解引用之前,需要进程非NULL指针判断。

//初始化时就指向NULL指针,要不然是个野指针
char *p = NULL;
char str[] = "@站长";
//指向str
p = str;
//下面两种都可以判断是否p为NULL指针
if (NULL != p) {
    printf("p = %s\n", p);
}
if (p) {
    printf("p = %s\n", p);
}

指针运算

指针及时一个整数的结果是另一个指针。指针和一个整数执行算术运算时,整数会在加法运算前根据指针所指向类型的大小进行调整。

如果p指向的char的指针,那么表达式p+1就是指向下一个char,偏移1*1个字节(char占一个字节)。

如果p指向的float的指针,那么表达式p+1就是指向下一个float,偏移1*4个字节(假设float占4个字节)。

*p指针占用大小,跟什么类型指针有关系

表达式     p指向的类型的指针   *p指针占用大小    指针偏移的字节
p+1        char              1               1*1
p+1        short             2               1*2
p+1        int               4               1*4
p+1        double            8               1*8

p+2        char              1               2*1
p+2        short             2               2*2
p+2        int               4               2*4
p+2        double            8               2*8

指针和字符串

字符串在C语言中基石char类型的数组。

char *p = null;
char buffer[]= "abcdef";
# p 指向buffer,就是buffer[0]的地址
p = buffer;
  1. 给p赋值只会改变指针变量的值,不会改变指针的内容

# 指针变量+1,其实就是便宜一个char位置
# 此时p指向了buffer[1]
p=p+1;
# 或
p++;
  1. 给*p 赋值,不会改变指针变量的值,只会改变指针指向的内存块的值。

# 就是p指向buffer, 也就是buffer[0]的地址
p = buffer;
# 因此,就是buffer[0] = '0';
*p = '0';
  1. = 左边*p表示是给内存块复制, = 右边的表示取值。

# 改变p指向地址的存储值
# 等同于buffer[0] = '3';
*p = '3';

# 获取存在p中的地址中的值
# a = buffer[0]
char a = *p;

二级指针

把一个指向[指针变量]的指针变量,称为二级指针变量。

二级指针是比较常见的,至于三级或四级几乎很少见!

一般格式

存储类型  数据类型  ** 指针名;

举个例子

int a = 10;
# 一级指针
int *p;
# 二级指针
int **q;

# 存储a的地址
p= &a ;
# 存储p的地址
q= &p;

void指针

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

一般格式

void * 指针变量
int a= 10;
int *p ;
p= &a;

void * q;
q= (void * ) p;

此时q和p都指向a的地址。

指针数组

指针数组是指具有若干个相同存储类型的指针变量构成的组合。

PS: 数组在最后,说明这个是数组!

存储类型是指针。

一般格式

存储类型  数据类型 * 指针数组名 [大小]
//指针数组,类型是int * 所以叫int型指针数组
int * p[n];

[]的优先级比*高,所以p先是一个数组,在int * 组合说明是一个整型指针数组,含有n个指针类型的数组。

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

p[0] = a[0]; //等同于&a[0][0];就是获取a[0]的地址。
#如果后续没有p[1] = a[1],p[1]依旧随机的地址

数组指针

数组指针也就是行指针。存储行地址的指针就行指针变量。

PS:指针在后面,说明这个是指针!

指针是可以指向某个地址的

一般格式

存储类型  数据类型 (*行指针变量)[常量表达式]

比如

# 数组指针
int (*p)[3];

()的优先级比[]高,说明p是一个指针,指向一个整型的一为数组,这个一维数组大小为n。

# 有3行2列的二维数组
int a[3][2]= {{1,2},{3,4},{5, 6}};
# 数组指针
int (*p)[2];

p = a;

指针函数

指针函数是一个函数的返回值为地址的函数。

PS: 函数在后面,说明这个是函数!

返回类型为指针。

一般格式

数据类型 * 函数名(形参){
    语句:
}
char name[] = "@站长";

# 返回char类型的指针(就是地址嘛)
char* getName() {
	return name;
}

函数指针

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

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

PS:指针在后面,说明这个是指针!

指针是可以指向某个地址的

一般格式

数据类型 (* 函数指针名称) (参数说明表);

规则

  1. 数据类型 : 是函指针所指向的函数返回值类型

  2. 参数说明表 : 与函数指针缩指向的形参说明表保持一致`

# 定义
int (*fun_sum)(int x, int y);

int sum(int x, int y){
	return x+y;
}

# 指向sum
# 可看成给sum函数找新代理名为fun_sum
fun_sum = sum;

const指针

#第一种
int const *p;

# 第二种
int * const p;

# 第三种
int const * const p;
第一种

const修饰的是 *p,也就是,你可以修改p的指向地址,但不能修改p所指向地址的值。

int a = 10;
int b = 200;
int const *p = &a;

# 正确
p = &b;
# 错误,不可以修改p指向地址的值
*p = 300;
第二种

const修饰的是p,也就是,你可以修改p所指向地址中的值,但不可以修改p的指向地址。

int a = 10;
int b = 200;
int * const p = &a;

# 错误,不可以修改p的指向
p = &b;
# 正确,可以修改p指向地址的值
*p = 300;
第三中

有两个const修饰,也就是,你不可修改所指向的指向,也不可以修改指向地址中的值。

真正的常量!

int a = 10;
int b = 200;
int const * const p = &a;

# 错误
p = &b;
# 错误
*p = 300;

参考文章

  1. C语言之指针数组和数组指针

  2. C语言之指针函数和函数指针

 历史上的今天

  1. 2019: 歌德:野蔷薇(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

[摘]Android图片加载框架之Glide和Picasso的区别

前言Glide和Picasso在实际中很常用,也容易忘记各个的优缺点。此文整理很全,因此摘抄于此,方便自己查阅。本文摘抄《Android图片加载框架之(Glide和Picasso的区别,Glide的简单使用)》)。正文Glide,一个被google所推荐的图片加载库,常见的还有Picas...

舒婷:人心的法则

为一朵花而死去是值得的冷漠的车轮粗暴的靴底使春天的彩虹在所有眸子里黯然失色既不能阻挡又无处诉说那么,为抗议而死去是值得的 为一句话而沉默是值得的远胜于大潮雪崩似地跌落这句话被嘴唇紧紧封锁汲取一生全部诚实与勇气这句话,不能说那么,为不背叛而沉默是值得的...

白寅:致中文系

你必须是静悄悄地在全校最古旧的一幢楼里在别人发飞信的时候用笔一个字一个字地写明信片你必须是揣着馒头夹榨菜在别人逛步行街的时候坐在阴凉的山北看整整一天的红杜鹃你一定要在草坪上开班会却在教室里化装跳舞你一定要在咖啡馆里争论乾坤阴阳却在中央广场上伫立走神你肯定在走进大学校门...

Android MediaButton监听再次记录

前言再次记录一下Android 中MediaButton的注册,注销代码片段,以及遇到的问题,记录于此,方便自己查阅和回顾。正文一般会出现监听了,但是没收到。下面记录一下自己处理的方式。隐藏内容!付费阅读后才能查看!¥4 ¥5多个隐藏块只需支付一次付费阅读参考文章老文章了,但还是这里重...

Can not perform this action after onSaveInstanceState

java.lang.IllegalStateException异常 Line 151151: 06-14 19:15:46.601 1804 1804 E Media: java.lang.IllegalStateException: Can not perform this action ...

获取Android设备的分辨率各种方式

前言有时候需要查看Android设备的分辨率,由于不同的Android版本,使用的方式存不同,因此这里记录一下常用的方式。总结下面三种方式都可以,但个人还是热衷于使用adb,只要连接上设备就可以获取。如果不是Android 4.2.2 环境 我就用:adb shell wm size...