C语言基础掌握之day4

指针

&:求址符。
*:求值符。
&i:表示变量i的内存地址。
*p:表示指针变量指向内存的值。
*p=100:表示把100赋值给指针p指向的内存空间。
指针只能存放地址。
int *p=NULL是允许的,表示指向地址为0的内存区域,该区域是不能操作的。我们称这样的指针为空指针,意味着该指针不指向任何变量。
野指针:没有赋初值,也称之为悬空指针。野指针很难控制的,因为你不知道它会指向哪个地址空间,所以要初始化。赋NUll也可以,这样就成了空指针。
用户进程之间不能互相访问对方的内存空间。
内核进程之间的内存是可以互相自由的访问。
void *p:表示无类型指针。可以接受任何类型数据的地址,也可以将自己赋给任何数据类型的指针(在C语言中可以,在C++中是非法的,必须要转类型)。同时void也意味着读取的长度不确定。无法读取一个数据。

指针与数组

数组名代表数组的首地址。
地址用8位十六进制数表示(8/2=4),因为指针是存放别人的地址,所以指针的大小应该是四个字节。
无论是int 类型的指针,还是char类型的指针,它们都在内存中占4个字节,类型只是决定了它们指向的数据类型和读取的长度。
&数组名表示数组的首地址,同数组名一样。
指针的运算并不是拿地址进行运算,而是指针在内存中的移动。
一个内存单元,存放两位16进制数的数据,也就是一个字节,也就是说内存单元存储数据的最小单位是字节。
小端对齐:低地址放低位,高地址放高位。

指针变量p++表示向后移动一个类型长度的内存,*p++表示先取值后移动。

在C语言中,数组名是一个常量(地址),值是不可以改变的。如array++这样是不可以的。允许通过运算赋值给变量,如指针变量p=array+1表示指针p指向了数组的第二个元素。 
指针p[i]这样是允许的,等价于array[i]。

指针数组

如char *s[10];表示数组里面的元素是指针。所以sizeof(s)=40;

数组指针

如 char (*s)[10];表示指向数组的指针,同时也意味着*s充当数组名。

二级指针(指向指针的指针)

在程序我们用到的指针对多是三级指针。

指针变量作为函数的参数

可以利用指针指向实参变量地址的特点,改变实参变量的值。

一维数组作为函数的参数

当数组作为函数的参数时,C语言将数组名解释为指针,所以sizeof(数组名)就会等于4个字节。当数组名作为函数参数传递给被调用函数时,被调用函数是不知道数组有多少元素。
相当于传递是一个地址,那么就可以通过地址来修改实参的值。

二维数组与指针

array表示二维数组名,那么*array就表示二维数组的首地址,这与一维数组有本质的区别。
array表示二维数组名,那么array+1表示的是第一行、第零列的元素。那么array[0]+1表示第零行、第一列的元素。可以这么理解:二维数组是由多行的一位数组组成,那么它的组成单位就是一维数组,所以以二维数组名为代表的地址,长度就是一个一维数组,移动也只能以一维数组为单位地移动。那么一维数组是由元素组成,以一维数组名为代表的地址,长度就是一个元素大小,移动也只能移动以一个元素为单位地移动。
假如有一个二维数组array[3][4],那么我们用指针*p=array[3][4],*(p+1)只能一个个的遍历。我们要想一行一行的遍历,可以定义一个数组指针(*p)[4],(数组指针的定义:指向数组的指针)这样就可以表示数组类型的指针,以4个元素为一个长度单位,*p可以表示数组名,同时也代表该地址的首地址。那么要想利用这样的数组指针遍历二维数组,就可以这样写*(*(p+i)+j),+i是代表向后移动一个行,+j是代表向后移动一个元素,也就是等价于array[i][j]。
二维数组可以看成一维数组的集合,所以可以定义一个数组指针表示指向数组的指针。

C语言基础掌握之day4_第1张图片


常量指针

const char *p;//定义一个指向常量的指针,通过指向常量的指针,可以限制指针修改一个变量的值。常量指针是值不能改变

指针*p可以分为两部分看,第一部分:p表示指针变量,存放的是地址。第二部分*p表示的变量存放地址的值。

指针常量

char *const p;//定义一个指针是常量,一旦初始化,就不能再指向别的地址,这个就是常量的意义所在。
指针常量也称常指针。指针常量是地址不能改变。

const 关键字保护数组内容

如果将一个数组作为函数的形参传递,那么数组内容可以在被调用函数内部修改,有时候不希望这样的事情发生,所以要对形参采用const参数。
如:func(const int array[])


指针作为函数的返回值

如:char *func()

指向函数的指针

指针可以指向变量、数组、也可以指向函数。
一个函数在编译的时候会分配一个入口地址,这个入口地址就是函数的指针,函数名称就代表函数的入口地址。
指向函数的指针的定义:void(*p)(int );表示定义了一个指向了一个有一个int类型的参数,返回值是void类型的函数的指针。
指向函数的指针赋值:p=func3;表示让p指向func3函数的入口地址,可以通过该指针来调用这个函数。

函数指针可以作为另外一个函数的参数

函数指针也就是指向函数的指针。
函数指针可以作为另外一个函数的参数来调用所指的函数。该过程称为回调函数,这是C语言特别高级的应用。
单线程:程序只能顺序执行。
多线程:程序并发执行。



C语言基础掌握之day4_第2张图片

字符串指针

char *p="hello world";含义是指针p指向了字符串常量,常量区的内容是不能被修改的。如果要改变常量的值就是非法操作,程序就会报错。常量只读。

汉字的ASCII值是负数。

指针数组作为main函数的形参

如:int main(int argc, char *argv[]):第一个参数就是告诉程序,第二个参数有多少个元素。
指针数组表示数组元素是指针的数组。char *argv[]相当于char **argv,那么char **argv表示指向char指针的指针。

你可能感兴趣的:(C语言基础掌握之day4)