10 指针
指针作为c语言中最重要的部分
这是用来区分c和其他语言的一个重要内容
身边很多从c转行的朋友都是对c大感头疼
前面的枚举也是涉及到了指针
面试的时候面试官问我的问题
char const *p里修饰指针p只读,只读的是p的地址还是内容
我也是直接懵了
平常学校里是不会考虑到这个问题的
不知道工作的时候会不会因为这个问题而出现bug
这几天的复习都是在菜鸟教程上逐步复习的,内容可能有很多熟悉的
但是也有一堆模糊的东西,用笔记慢慢记下来吧
每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址。
整型的指针只能存储整型变量的指针地址
10.1指针的定义声明与使用
指针就是内存地址
指针变量是用来存放地址的变量
声明方法
数据类型 *指针名;
使用的话最简单就是下面这种了
int var = 20; /* 实际变量的声明 */
int *ip; /* 指针变量的声明 */
ip = &var; /* 在指针变量中存储 var 的地址 */
printf("var 变量的地址: %p\n", &var );//直接输出var的地址,和下面的语句等价
printf("ip 变量存储的地址: %p\n", ip );//在指针变量中存储的地址 ,输出存储在ip中的avr的地址
printf("*ip 变量的值: %d\n", *ip );//使用指针访问值,输出ip的值,ip中存放的是var的地址,即取这个地址的值
10.2空指针
若声明变量时,还没有确切的值可以赋,可以先给指针变量赋一个空值NULL,
被赋了NULL的指针被称为空指针
NULL 指针是一个定义在标准库中的值为零的常量
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。
然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。
按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
可以使用if来检查这个指针是否为空指针
if(p)//p非空,则判断才成功,继续下面语句
if(!p)//p为空,则为真
10.3指针的算术运算
指针加一就是将指针移动到下一个内存位置
例如p指针是int类型的,4位,初始地址是1000
p++后就是1004
- 指针的每一次递增,它其实会指向下一个元素的存储单元。
- 指针的每一次递减,它都会指向前一个元素的存储单元。
- 指针在递增和递减时跳跃的字节数取决于指针所指向变量数据类型长度,比如 int 就是 4 个字节。
对指针进行递减运算,即把值减去其数据类型的字节数
可以使用指针代替数组,因为变量指针可以递增,而数组不能递增,数组可以看成一个指针常量。
int var[] = {10, 100, 200};
int i, *ptr;
/* 指针中的数组地址 */
ptr = var;//使用指针里的值来替代数组var
for ( i = 0; i < MAX; i++)
{
printf("存储地址:var[%d] = %p\n", i, ptr );
printf("存储值:var[%d] = %d\n", i, *ptr );
ptr++;/* 指向下一个位置 */
}
指针数组
int *ptr[MAX]; //把 ptr 声明为一个数组,由 MAX 个整数指针组成。
//ptr 中的每个元素,都是一个指向 int 值的指针。
//可以使用下面的方法来设置一个指针数组
int var[] = {10, 100, 200};//先定义一个数组
int i, *ptr[MAX];//定义一个规定大小的指针数组,值未赋
for ( i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; //将var数组里的元素的地址赋给ptr的元素
}
也可以用一个指向字符的指针数组来存储一个字符串列表
char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
传递指针给函数
C 语言可以传递指针给函数,只需要简单地声明函数参数为指针类型即可。
int abc(int *p)
能接受指针作为参数的函数,也能接受数组作为参数
演示代码挺简单的,插个眼,忘记了去菜鸟教程看
从函数返回指针
C 也可以从函数返回指针。
为了做到这点,您必须声明一个返回指针的函数,如下所示:
//另外,C 语言不支持在调用函数时返回局部变量的地址,除非定义局部变量为 static 变量。
int * myFunction()
{
.
.
.
}
10.4const变量的不同
char const *p;
const char *p;
char * const p;
const char * const a
首先,前两个等价,都是定义一个指向字符常量的指针
即*p的值是const的,不可修改的。
可以通过将p指向其他变量,修改其他变量的方法来修改p的值,只是不能直接通过p指针来修改。
如下摘抄的其他人的解释:定义一个指向字符常量的指针,这里,ptr是一个指向 char* 类型的常量,所以不能用ptr来修改所指向的内容,换句话说,*ptr的值为const,不能修改。但是ptr的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对ptr而言,这个值是常量。
第三个是定义一个指向字符的指针常数,就是const型的指针
不能修改p指针,但是可以修改这个指针指向的内容
如果需要让p不可被修改,p指向的数据也不能改,就用第四个