C语言基础-第六课正规网赌平台-指针,c语言指针

C语言基础-第六课-指针,c语言指针

指针

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

1   指针

指针与数组

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

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

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

1.1   指针

指针数组

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

1.1.1   指针的概念

指针变量也是一个变量

指针存放的内容是一个地址,该地址指向一块内存空间

数组指针

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

1.1.2   指针变量的定义

可以定义一个指向一个变量的指针变量。

int *p;//表示定义一个指针变量。

*p;//代表指针所指内存的实际数据

切记,指针变量只能存放地址,不能将一个int型变量直接赋值给一个指针。

int *p = 100;

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

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

1.1.3   &取地址运算符

&可以取得一个变量在内存当中的地址

指针变量作为函数的参数

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

1.1.4   无类型指针

定义一个指针变量,但不指定它指向具体哪种数据类型。可以通过强制转化将void
*转化为其他类型指针,也可以用(void
*)将其他类型指针强制转化为void类型指针。

void *p

一维数组作为函数的参数

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

1.1.5   NULL

NULL在C语言中的定义为(void *)0

二维数组与指针

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]。
二维数组可以看成一维数组的集合,所以可以定义一个数组指针表示指向数组的指针。

正规网赌平台 1

1.1.6   空指针与野指针

指向NULL的指针叫空指针,没有具体指向任何变量地址的指针叫野指针

 正规网赌平台 2

常量指针

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

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

1.1.7   指针的兼容性

指针之间赋值比普通数据类型赋值检查更为严格,例如:不可以把一个double
*赋值给int *

原则上一定是相同类型的指针指向相同类型的变量地址,不能用一种类型的指针指向另一种类型的变量正规网赌平台 3

指针常量

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

1.1.8   指向常量的指针与指针常量

const char *p;//定义一个指向常量的指针

char *const p;//定义一个指针常量,一旦初始化之后其内容不可改变

const 关键字保护数组内容

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

1.1.9   指针与数组的关系

一个变量有地址,一个数组包含若干个元素,每个元素在内存中都有地址。

int a[10];

int *p = a;

比较p和&a[0]的地址是否相同

指针作为函数的返回值

如:char *func()

1.1.10   指针运算

指针运算不是简单的整数加减法,而是指针指向的数据类型在内存中占用字节数做为倍数的运算。

Char *p;

P++;移动了sizeof(char)这么多的字节数

Int *p1;

P1++移动了sizeof(int)这么多的字节数

 

赋值:int *p = &a;

求值:int I = *p;

取指针地址 int **pp = &p;

将一个整数加(减)给指针:p + 3; p – 3;

增加(减少)指针值 p++,p–

求差值 ,p1 – p2,通常用于同一个数组内求两个元素之间的距离

比较 p1 == p2,通常用来比较两个指针是否指向同一个位置。

指向函数的指针

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

1.1.11   通过指针使用数组元素

p + 1代表&a[1],也可以直接使用p[1]表示a[5]

p + 5 代表&a[5]

p++

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

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

正规网赌平台 4

1.1.12   指针数组

int *p[5];

字符串指针

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

汉字的ASCII值是负数。

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

指针就是一个变量,既然是变量就也存在内存地址,所以可以定义一个指向指针的指针。

    int i = 10;

    int *p1 = &i;

    int **p2 = &p1;

    printf(“%d\n”, **p2);

以此类推可以定义3级甚至多级指针。C语言允许定义多级指针,但是指针级数过多会增加代码的复杂性,考试的时候可能会考多级指针,但实际编程的时候最多用到3级,但3级指针也不常用,一级和二级指针是大量使用。

正规网赌平台 5

正规网赌平台 6

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

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

相关文章