C语言之指针

C和C++2023年8月26日 am8:08发布11个月前更新 3XCN.COM站长
0 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、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站文章: 部分来源于网络,仅供站长学习和参考,若侵权请留言
广告也精彩

相关文章

广告也精彩

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

暂无评论...

网站升级中

公告

近期网站升级中,可能存在一些bug。欢迎反馈 https://www.91es.com/we.html

本站域名

本站域名 : 91es.com3xcn.com。本站邮箱 : 站长邮箱 i@oorr.cn,通知邮箱we@oorr.cn ,如有更新,请看公告 。