指针才是C的精髓

《朱老师物联网大讲堂》学习笔记

学习地址:www.zhulaoshi.org


(1).
指针的实质就是变量,全称“指针变量”,


为什么需要指针?
为了实现间接访问,汇编中的寻址方式就是体现,本质就是CPU的寻址方式中的间接寻址,
CPU的间接寻址是CPU设计时决定的,这就决定了汇编语言必须能够实现间接寻址,又决定了汇编之上的C语言也必须实现间接寻址,
像C#,java看似没有指针,其实也有,是语言本身帮我们封装了,


指针使用3步:
1.定义指针,int a; int *p;
2.绑定指针,p = &a;
3.解引用,*p = 55;


(2).
*在指针相关时,有两种用法,
第一种用法:在定义时候,
int *p; //此时*和前面的int结合,表明p是int *类型,
int *p1,p2; //只说一句话,p2是不是指针,是int型变量,
int *p3,*p4; //p3和p4都是int *类型,
第二种用法:
*p = 4; //表示p指向的变量本身,


&取地址符,


左值与右值,
变量做左值时候代表对应内存空间,
做右值时代表这个空间中所存储的值,


(3).
野指针就是指针指向的位置是随机的,


避免野指针,
1. int *p = NULL;
2. if( NULL != p ){ 解引用p }
3. 使用完后 p = NULL;
4. 若再次使用,先将其绑定到一个可用的地址空间,
总结:不使用的时候,保证其为NULL,使用的时候再绑定一个值,




NULL到底是怎么定义的?
#ifdef _cplusclus
#define NULL 0
#else
#define NULL (void *)0
#endif


(4).
const用来修饰变量,表示这个变量是常量,
1. const int *p;
2. int const *p;
3. int * const p;
4. const int * const p;
区别就是一个是p本身,一个是p指向的变量,const在p最旁边,代表p本身是常量,其它情况都代表p指向变量是常量,


const修饰的变量真的不能改吗?
其实不然,通过指针就可以实现更改(我们这里是gcc环境),


(5).
数组也是变量,变量本身是一个地址,而地址是一个点,变量类型决定这个地址的延续长度,
数组变量就是一次分配多个变量,而且它们的地址彼此相连,因此很适合用指针来操作,


int a[10]; 这是下面讨论情况的前提,
a,
做右值时等同于&a[0],是首元素首地址,从值得角度来看,a和&a是一样过的,
做左值时代表整个数组,
a[0],
无,
&a,
不能做左值,&a是一个常量,
做右值时候,代表整个数组的首地址,与a值一样,但意义不同!
&a[0],
无,

(6).
前提int a[10]; int *p;
a[3]和*(a+3)一样,a在此做右值,代表地址,类型是int,所以+3,就不言而喻了,
p = a; //你真的理解它的意思吗?*p = a[0];这样可以帮助理解,可原来那样还是有些想不通,


int a[5]; //在这里&a的类型是int (*)[5]类型,a是int *类型,


指针本身存储的是地址,因此对它的加减是针对地址类型而言的,比如int *类型的+1代表+4,


(7).
不同的数据类型存取格式是不同的,有的类型比如int和short是兼容的,有可能出错,


int *p;
//p是int *类型,占4个字节,
//*p是int类型,


(8).
sizeof是一个运算符,作用是返回变量或者数据类型占用的内存字节数,
32位系统指针变量都是4个字节,sizeof(字符串)要算上\0,strlen(字符串)不算上\0,


函数传参,传数组时,其实是指针,


#define dpchar char * //用宏只是单纯的替换
typedef char * tpchar //用typedef相当于自定义了一种新的类型,
注意这两种方式, 
dpchar p1,p2; //展开后char *p1,p2;即char *p1,char p2;
tpchar p3,p4; //等价于char *p3,char *p4;




(9).
函数传参,
传递数组时,其实传得是首元素首地址,因此不包含数组元素个数的信息,
传递结构体时,和传值调用很像,应该说就是,不懂就来看看这里的视频,结构体很大时,这样效率低,可以用传指针的方式来实现,


注意传值调用与传址调用的区别,


(10).
函数名实质是一个指针常量,
传参多时,用结构体打包,然后传结构体指针,


字符串定义成指针的类型,这个字符串放在代码段,不可修改,定义成数组可以修改,


void test(const int *p); 
const修饰,强调不可更改,


函数的返回值作为程序执行的结果,
int test(int a,int *p)
{
temp = a*5;
if( temp > 10 )
{
return -1
}
else
{
*p = temp;

}
return 0;
}
a作为输入型参数,p是输出型参数,这里a是普通变量,p是指针变量,而且最好在a前用const修饰,


你可能感兴趣的:(C语言)