C语言学习-指针

  计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用4个字节,float 占用8个字节,char 占用1个字节。为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。

指针的定义和使用

指针和指针变量

指针(Pointer)就是内存的地址,C语言允许用一个变量来存放指针,这种变量称为指针变量。指针变量可以存放基本类型数据的地址,也可以存放数组、函数以及其他指针变量的地址。

定义指针变量与定义普通变量非常类似,不过要在变量名前面加星号*,格式为:

datatype * name;

*表示这是一个指针变量,datatype表示该指针变量所指向的数据的类型 。例如:

int a = 100;
int *p_a = &a;

在定义指针变量 p_a 的同时对它进行初始化,并将变量 a 的地址赋予它,此时 p_a 就指向了 a。值得注意的是,p_a 需要的一个地址,a 前面必须要加取地址符&,否则是不对的。

现在p_a代表的是a的地址,那么*p_a也就是a的值,例如:

*p_a = 200;

这样做就把a的值赋成了200。

指针使用热身

int i = 20;
int k = 10;
int * p = &k;
int * o;
int * a;
p = &i; //把指针变量p从指向k变成指向i
//o = p;
printf("*p = %d\n", *p); //输出*p也就是i的值
printf("o = %x\n", o); //输出*o的内存地址,如果不分配内存地址,自动为cccccccc,又因为里面的值是垃圾值,所以不能被读写,运行后程序会报错
printf("a = %x\n", a); //输出*a的内存地址
printf("k = %d\n", k);
return 0;

指针使用实例——2个数字互换

# include <stdio.h>

void swap(int * a, int * b)
{
    int c;
    c = *a;
    *a = *b;
    *b = c;
}

int main(void)
{
    int i = 3;
    int j = 5;
    char ch = 'ab';

    swap(&i, &j);

    printf("i = %d\nj = %d\n", i, j);
    printf("ch = %c\n", ch);

    return 0;
}

指针和数组的关系

在c语言中,数组名就是数组第0个元素的地址,例如:

int arr[3] = {1,2,3};
int * p = arr;

这里*p的值为1,为什么arr前不要取地址符&呢,因为arr就是数组里第0个元素的地址。

数组的内存分配是连续的,所以第0个元素的地址加1就是第一个元素的地址,例如*(p+1)就等价于p[1]。

*(p+1) == p[1]; //true

指针变量占几个字节

在c语言中,可以用sizeof()函数来查看变量占用的内存空间,例如:

int i = 5;
double d = 1.1;
char ch = 'a';

int * p_i = &i;
double * p_d = &d;
char * p_ch = &ch;

sizeof(i); //4
sizeof(d); //8
sizeof(ch); //1
sizeof(p_i); //4
sizeof(p_d); //4
sizeof(p_ch); //4

可以看到指针变量永远只占4个字节。

malloc动态内存分配

传统的数组长度是固定的,也就是静态的,这就有了很大的局限性,所以就出现了动态内存分配,他可以使用户来决定数组的长度,malloc函数就是用来动态分配内存的函数。

静态变量被存放于栈中,而动态变量存放于堆中,栈的特点是先进后出,堆的特点是先进先出。

int len = 4;
int * pArr = (int *)malloc(len * sizeof(int)); //等价于pArr[4]

这里要注意,由于malloc函数返回的值是void 类型,所以需要强制转换成int 类型,否则会报错。

多级指针

指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int 、double 、char * 等。

如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针,例如:

int a =100;
int *p1 = &a;
int **p2 = &p1;

指针变量也是一种变量,也会占用存储空间,也可以使用&获取它的地址。C语言不限制指针的级数,每增加一级指针,在定义指针变量时就得增加一个星号。p1 是一级指针,指向普通类型的数据,定义时有一个星号;p2 是二级指针,指向一级指针 p1,定义时有两个*。

如果我们希望再定义一个三级指针 p3,让它指向 p2,那么可以这样写:

int ***p3 = &p2;

四级指针也是类似的道理:

int ****p4 = &p3;
坚持原创技术分享,您的支持将鼓励我继续创作!