← 返回文章列表

C语言学习笔记 #5 指针!!!

C语言学习笔记#C语言学习笔记

C语言学习笔记 #5 指针!!!

发布于 2026-09-28 10:17:28

内存地址

CPU由三个部分组成

算数逻辑单元:对数据执行逻辑运算

控制单元:协调机器活动电路

寄存器组:用于临时储存数据

然而,寄存器能寄存的数据量是很小的

因此,需要内存配合cpu操作

将两个数据相加的操作:

先从内存取一个加数到寄存器中

再从内存取另一个加数到另一个寄存器中

激活算术逻辑单元的加法电路

输出到寄存器

再存放到内存中

如何表达一个数据类型?(以int为例)

列举首地址及占用储存空间大小

指针

取地址运算符&

&数据对象

获取数据对象的首地址和所需存储空间大小

int n;

int * pn = &n;  //声明了一个指针变量,用于保存变量n首地址和所需空间大小

char c;
char * pc = &c; //声明了一个指针变量,保存变量c的首地址和所需空间大小

我们把pn称作n的指针或者说pn指向n

声明指针类型变量

目标数据类型 * 变量名

指针类型的值是目标数据对象的首地址

#include <stdio.h>
int main()
{
    int n1;
    int *pn1 = &n1;
    printf("%u",pn1);
}

输出: 6291044

char类型指针通过char类型来记录所占用的字节大小为一个字节

int类型指针通过int类型来记录所占用的字节大小为四个字节

总结:指针类型是通过值来保存目标数据对象的首地址,通过类型本身来标记目标数据对象的空间大小.

使用指针

取值运算符*

*指针

根据指针中存储的首地址和空间大小找到目标数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%u\n",pn);
    printf("%d\n",*pn);

    return 0;
}

输出;

6291044

123

第一个printf打印的是n的首地址

第二个printf打印的是n的值

通过指针修改所指向的数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    char c = 'C';
    char *pc = &c;

    *pn = 123;
    *pc = 'A';
    printf("%d\n",n);
    printf("%c\n",c);
    printf("%d\n",*pn);
    printf("%c\n",*pc);

    return 0;
}

输出:

123

A

123

A

说明通过指针更改的数据生效

指针类型占用的空间大小

32位 4字节

64为 8字节

指针运算

指针类型与整型加减

指针类型+1后

将首地址向后移动了sizeof(目标数据对象)个字节

指针类型相减后,结果为两个首地址差值除以步长

指针与数组

数组元素在内存中是连续的

第一个元素的首地址就是整个数组的首地址

直接指针指向数组打印出来的地址也是首地址

#include <stdio.h>
int main()
{
    int arr[5] = {111,222,333,444,555};
    int *p = &arr[0];
    printf("%d\n",*p);
    printf("%d\n",*(p+1));  //取值运算符的优先级高于算数运算符,所以要把p+1括起来
    printf("%d\n",*(p+2));
    printf("%d\n",*(p+3));
    printf("%d\n",*(p+4));
    printf("%d\n",p);
    printf("%u\n",arr);  //直接打印数组名arr的值也是首地址
    int *p2 = arr;  //arr在表达式中会被转化为指向数组第一个元素的指针
    return 0;
}

现在,我们学会了两种访问数组元素的办法

  • 数组名[下标]

  • *(数组名+偏移量)

例如,我们要访问arr数组的第二个元素

arr[1]和*(arr+1)是完全等价的

[]被称为下标运算符,优先级高于一切运算符

A[k]表达式运算时,会将[]展开为*(A+k)

指针作为参数传递

#include <stdio.h>
void swap(int *x,int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    int a,b;
    a = 1;
    b = 2;
    printf("%d,%d\n",a,b);
    swap(&a,&b);
    printf("%d,%d\n",a,b);
    return 0;
}

void类型指针

只需要传入指针首地址,不需要存储空间大小

#include <stdio.h>
void swap(void *x,void *y,int size)
{
    char *px = (char *)x;
    char *py = (char *)y;
    char temp[128];
    for (int i = 0 ;i < size ; i++)
    {
        temp[i] = px[i];
        px[i] = py[i];
        py[i] = temp[i];
    }
}

int main()
{
    int a,b;
    a = 1;
    b = 2;
    printf("%d,%d\n",a,b);
    swap(&a,&b,4);
    printf("%d,%d\n",a,b);
    return 0;
}

在这个程序中

因为void只能传入首地址,不能用来取值

所以我们强制转换为char类型(1个字节)

并使用for循环遍历数组(数组内存地址是连续排布的)(int类型有4个字节)

多级指针与指针数组

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%d\n",pn);
    printf("%d\n",&pn);
    //指针类型声明中,int * p之间对空格不严格 int*p
    int **pnn = &pn;
    printf("%d\n",pnn);
    printf("%d\n",*pnn);
    printf("%d\n",**pnn);
//指针数组
    int arr1[5] = {1,2,3,4,5};
    int arr2[5] = {6,7,8,9,10};
    int arr3[5] = {11,12,13,14,15};
    int *pToArr[3] = {arr1,arr2,arr3};
    pToArr[0] = arr1;
    pToArr[1] = arr2;
    pToArr[2] = arr3;
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 5; j++)
        {
            printf("%d ",pToArr[i][j]);
        }
        printf("\n");
    }
    return 0;
}
#include <stdio.h>
int * func()
{
    static int n = 123;  //static关键字修饰的变量在函数结束后不会被回收
    return &n;//函数结束后,函数内部的变量会被回收,如果不想被回收,需要加入关键词function static
}

int main()
{
    int *p = func();
    printf("%d\n",*p);  
    return 0;
}
#include <stdio.h>

void func(int **p1,int **p2)
{
    static int n1 = 123;
    static int n2 = 456;
    *p1 = &n1;
    *p2 = &n2;
}

int main()
{
    //NULL是一个宏定义,表示空指针常量
    int *a = NULL;
    int *b = NULL;
    func(&a,&b);
    if (a != NULL && b != NULL)
    {
        printf("%d,%d\n",*a,*b);
    }
    else
    {
        printf("指针为空\n");
    }
    return 0;
}

内存地址

CPU由三个部分组成

算数逻辑单元:对数据执行逻辑运算

控制单元:协调机器活动电路

寄存器组:用于临时储存数据

然而,寄存器能寄存的数据量是很小的

因此,需要内存配合cpu操作

将两个数据相加的操作:

先从内存取一个加数到寄存器中

再从内存取另一个加数到另一个寄存器中

激活算术逻辑单元的加法电路

输出到寄存器

再存放到内存中

如何表达一个数据类型?(以int为例)

列举首地址及占用储存空间大小

指针

取地址运算符&

&数据对象

获取数据对象的首地址和所需存储空间大小

int n;

int * pn = &n;  //声明了一个指针变量,用于保存变量n首地址和所需空间大小

char c;
char * pc = &c; //声明了一个指针变量,保存变量c的首地址和所需空间大小

我们把pn称作n的指针或者说pn指向n

声明指针类型变量

目标数据类型 * 变量名

指针类型的值是目标数据对象的首地址

#include <stdio.h>
int main()
{
    int n1;
    int *pn1 = &n1;
    printf("%u",pn1);
}

输出: 6291044

char类型指针通过char类型来记录所占用的字节大小为一个字节

int类型指针通过int类型来记录所占用的字节大小为四个字节

总结:指针类型是通过值来保存目标数据对象的首地址,通过类型本身来标记目标数据对象的空间大小.

使用指针

取值运算符*

*指针

根据指针中存储的首地址和空间大小找到目标数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%u\n",pn);
    printf("%d\n",*pn);

    return 0;
}

输出;

6291044

123

第一个printf打印的是n的首地址

第二个printf打印的是n的值

通过指针修改所指向的数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    char c = 'C';
    char *pc = &c;

    *pn = 123;
    *pc = 'A';
    printf("%d\n",n);
    printf("%c\n",c);
    printf("%d\n",*pn);
    printf("%c\n",*pc);

    return 0;
}

输出:

123

A

123

A

说明通过指针更改的数据生效

指针类型占用的空间大小

32位 4字节

64为 8字节

指针运算

指针类型与整型加减

指针类型+1后

将首地址向后移动了sizeof(目标数据对象)个字节

指针类型相减后,结果为两个首地址差值除以步长

指针与数组

数组元素在内存中是连续的

第一个元素的首地址就是整个数组的首地址

直接指针指向数组打印出来的地址也是首地址

#include <stdio.h>
int main()
{
    int arr[5] = {111,222,333,444,555};
    int *p = &arr[0];
    printf("%d\n",*p);
    printf("%d\n",*(p+1));  //取值运算符的优先级高于算数运算符,所以要把p+1括起来
    printf("%d\n",*(p+2));
    printf("%d\n",*(p+3));
    printf("%d\n",*(p+4));
    printf("%d\n",p);
    printf("%u\n",arr);  //直接打印数组名arr的值也是首地址
    int *p2 = arr;  //arr在表达式中会被转化为指向数组第一个元素的指针
    return 0;
}

现在,我们学会了两种访问数组元素的办法

  • 数组名[下标]

  • *(数组名+偏移量)

例如,我们要访问arr数组的第二个元素

arr[1]和*(arr+1)是完全等价的

[]被称为下标运算符,优先级高于一切运算符

A[k]表达式运算时,会将[]展开为*(A+k)

指针作为参数传递

#include <stdio.h>
void swap(int *x,int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    int a,b;
    a = 1;
    b = 2;
    printf("%d,%d\n",a,b);
    swap(&a,&b);
    printf("%d,%d\n",a,b);
    return 0;
}

void类型指针

只需要传入指针首地址,不需要存储空间大小

#include <stdio.h>
void swap(void *x,void *y,int size)
{
    char *px = (char *)x;
    char *py = (char *)y;
    char temp[128];
    for (int i = 0 ;i < size ; i++)
    {
        temp[i] = px[i];
        px[i] = py[i];
        py[i] = temp[i];
    }
}

int main()
{
    int a,b;
    a = 1;
    b = 2;
    printf("%d,%d\n",a,b);
    swap(&a,&b,4);
    printf("%d,%d\n",a,b);
    return 0;
}

在这个程序中

因为void只能传入首地址,不能用来取值

所以我们强制转换为char类型(1个字节)

并使用for循环遍历数组(数组内存地址是连续排布的)(int类型有4个字节)

内存地址

CPU由三个部分组成

算数逻辑单元:对数据执行逻辑运算

控制单元:协调机器活动电路

寄存器组:用于临时储存数据

然而,寄存器能寄存的数据量是很小的

因此,需要内存配合cpu操作

将两个数据相加的操作:

先从内存取一个加数到寄存器中

再从内存取另一个加数到另一个寄存器中

激活算术逻辑单元的加法电路

输出到寄存器

再存放到内存中

如何表达一个数据类型?(以int为例)

列举首地址及占用储存空间大小

指针

取地址运算符&

&数据对象

获取数据对象的首地址和所需存储空间大小

int n;

int * pn = &n;  //声明了一个指针变量,用于保存变量n首地址和所需空间大小

char c;
char * pc = &c; //声明了一个指针变量,保存变量c的首地址和所需空间大小

我们把pn称作n的指针或者说pn指向n

声明指针类型变量

目标数据类型 * 变量名

指针类型的值是目标数据对象的首地址

#include <stdio.h>
int main()
{
    int n1;
    int *pn1 = &n1;
    printf("%u",pn1);
}

输出: 6291044

char类型指针通过char类型来记录所占用的字节大小为一个字节

int类型指针通过int类型来记录所占用的字节大小为四个字节

总结:指针类型是通过值来保存目标数据对象的首地址,通过类型本身来标记目标数据对象的空间大小.

使用指针

取值运算符*

*指针

根据指针中存储的首地址和空间大小找到目标数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%u\n",pn);
    printf("%d\n",*pn);

    return 0;
}

输出;

6291044

123

第一个printf打印的是n的首地址

第二个printf打印的是n的值

通过指针修改所指向的数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    char c = 'C';
    char *pc = &c;

    *pn = 123;
    *pc = 'A';
    printf("%d\n",n);
    printf("%c\n",c);
    printf("%d\n",*pn);
    printf("%c\n",*pc);

    return 0;
}

输出:

123

A

123

A

说明通过指针更改的数据生效

指针类型占用的空间大小

32位 4字节

64为 8字节

指针运算

指针类型与整型加减

指针类型+1后

将首地址向后移动了sizeof(目标数据对象)个字节

指针类型相减后,结果为两个首地址差值除以步长

指针与数组

数组元素在内存中是连续的

第一个元素的首地址就是整个数组的首地址

直接指针指向数组打印出来的地址也是首地址

#include <stdio.h>
int main()
{
    int arr[5] = {111,222,333,444,555};
    int *p = &arr[0];
    printf("%d\n",*p);
    printf("%d\n",*(p+1));  //取值运算符的优先级高于算数运算符,所以要把p+1括起来
    printf("%d\n",*(p+2));
    printf("%d\n",*(p+3));
    printf("%d\n",*(p+4));
    printf("%d\n",p);
    printf("%u\n",arr);  //直接打印数组名arr的值也是首地址
    int *p2 = arr;  //arr在表达式中会被转化为指向数组第一个元素的指针
    return 0;
}

现在,我们学会了两种访问数组元素的办法

  • 数组名[下标]

  • *(数组名+偏移量)

例如,我们要访问arr数组的第二个元素

arr[1]和*(arr+1)是完全等价的

[]被称为下标运算符,优先级高于一切运算符

A[k]表达式运算时,会将[]展开为*(A+k)

指针作为参数传递

#include <stdio.h>
void swap(int *x,int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    int a,b;
    a = 1;
    b = 2;
    printf("%d,%d\n",a,b);
    swap(&a,&b);
    printf("%d,%d\n",a,b);
    return 0;
}

内存地址

CPU由三个部分组成

算数逻辑单元:对数据执行逻辑运算

控制单元:协调机器活动电路

寄存器组:用于临时储存数据

然而,寄存器能寄存的数据量是很小的

因此,需要内存配合cpu操作

将两个数据相加的操作:

先从内存取一个加数到寄存器中

再从内存取另一个加数到另一个寄存器中

激活算术逻辑单元的加法电路

输出到寄存器

再存放到内存中

如何表达一个数据类型?(以int为例)

列举首地址及占用储存空间大小

指针

取地址运算符&

&数据对象

获取数据对象的首地址和所需存储空间大小

int n;

int * pn = &n;  //声明了一个指针变量,用于保存变量n首地址和所需空间大小

char c;
char * pc = &c; //声明了一个指针变量,保存变量c的首地址和所需空间大小

我们把pn称作n的指针或者说pn指向n

声明指针类型变量

目标数据类型 * 变量名

指针类型的值是目标数据对象的首地址

#include <stdio.h>
int main()
{
    int n1;
    int *pn1 = &n1;
    printf("%u",pn1);
}

输出: 6291044

char类型指针通过char类型来记录所占用的字节大小为一个字节

int类型指针通过int类型来记录所占用的字节大小为四个字节

总结:指针类型是通过值来保存目标数据对象的首地址,通过类型本身来标记目标数据对象的空间大小.

使用指针

取值运算符*

*指针

根据指针中存储的首地址和空间大小找到目标数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%u\n",pn);
    printf("%d\n",*pn);

    return 0;
}

输出;

6291044

123

第一个printf打印的是n的首地址

第二个printf打印的是n的值

通过指针修改所指向的数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    char c = 'C';
    char *pc = &c;

    *pn = 123;
    *pc = 'A';
    printf("%d\n",n);
    printf("%c\n",c);
    printf("%d\n",*pn);
    printf("%c\n",*pc);

    return 0;
}

输出:

123

A

123

A

说明通过指针更改的数据生效

指针类型占用的空间大小

32位 4字节

64为 8字节

指针运算

指针类型与整型加减

指针类型+1后

将首地址向后移动了sizeof(目标数据对象)个字节

指针类型相减后,结果为两个首地址差值除以步长

指针与数组

数组元素在内存中是连续的

第一个元素的首地址就是整个数组的首地址

直接指针指向数组打印出来的地址也是首地址

#include <stdio.h>
int main()
{
    int arr[5] = {111,222,333,444,555};
    int *p = &arr[0];
    printf("%d\n",*p);
    printf("%d\n",*(p+1));  //取值运算符的优先级高于算数运算符,所以要把p+1括起来
    printf("%d\n",*(p+2));
    printf("%d\n",*(p+3));
    printf("%d\n",*(p+4));
    printf("%d\n",p);
    printf("%u\n",arr);  //直接打印数组名arr的值也是首地址
    int *p2 = arr;  //arr在表达式中会被转化为指向数组第一个元素的指针
    return 0;
}

现在,我们学会了两种访问数组元素的办法

  • 数组名[下标]

  • *(数组名+偏移量)

例如,我们要访问arr数组的第二个元素

arr[1]和*(arr+1)是完全等价的

内存地址

CPU由三个部分组成

算数逻辑单元:对数据执行逻辑运算

控制单元:协调机器活动电路

寄存器组:用于临时储存数据

然而,寄存器能寄存的数据量是很小的

因此,需要内存配合cpu操作

将两个数据相加的操作:

先从内存取一个加数到寄存器中

再从内存取另一个加数到另一个寄存器中

激活算术逻辑单元的加法电路

输出到寄存器

再存放到内存中

如何表达一个数据类型?(以int为例)

列举首地址及占用储存空间大小

指针

取地址运算符&

&数据对象

获取数据对象的首地址和所需存储空间大小

int n;

int * pn = &n;  //声明了一个指针变量,用于保存变量n首地址和所需空间大小

char c;
char * pc = &c; //声明了一个指针变量,保存变量c的首地址和所需空间大小

我们把pn称作n的指针或者说pn指向n

声明指针类型变量

目标数据类型 * 变量名

指针类型的值是目标数据对象的首地址

#include <stdio.h>
int main()
{
    int n1;
    int *pn1 = &n1;
    printf("%u",pn1);
}

输出: 6291044

char类型指针通过char类型来记录所占用的字节大小为一个字节

int类型指针通过int类型来记录所占用的字节大小为四个字节

总结:指针类型是通过值来保存目标数据对象的首地址,通过类型本身来标记目标数据对象的空间大小.

使用指针

取值运算符*

*指针

根据指针中存储的首地址和空间大小找到目标数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%u\n",pn);
    printf("%d\n",*pn);

    return 0;
}

输出;

6291044

123

第一个printf打印的是n的首地址

第二个printf打印的是n的值

通过指针修改所指向的数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    char c = 'C';
    char *pc = &c;

    *pn = 123;
    *pc = 'A';
    printf("%d\n",n);
    printf("%c\n",c);
    printf("%d\n",*pn);
    printf("%c\n",*pc);

    return 0;
}

输出:

123

A

123

A

说明通过指针更改的数据生效

指针类型占用的空间大小

32位 4字节

64为 8字节

指针运算

指针类型与整型加减

指针类型+1后

将首地址向后移动了sizeof(目标数据对象)个字节

指针类型相减后,结果为两个首地址差值除以步长

指针与数组

数组元素在内存中是连续的

第一个元素的首地址就是整个数组的首地址

直接指针指向数组打印出来的地址也是首地址

#include <stdio.h>
int main()
{
    int arr[5] = {111,222,333,444,555};
    int *p = &arr[0];
    printf("%d\n",*p);
    printf("%d\n",*(p+1));  //取值运算符的优先级高于算数运算符,所以要把p+1括起来
    printf("%d\n",*(p+2));
    printf("%d\n",*(p+3));
    printf("%d\n",*(p+4));
    printf("%d\n",p);
    printf("%u\n",arr);  //直接打印数组名arr的值也是首地址
    int *p2 = arr;  //arr在表达式中会被转化为指向数组第一个元素的指针
    return 0;
}

现在,我们学会了两种访问数组元素的办法

  • 数组名[下标]

  • *(数组名+偏移量)

例如,我们要访问arr数组的第二个元素

内存地址

CPU由三个部分组成

算数逻辑单元:对数据执行逻辑运算

控制单元:协调机器活动电路

寄存器组:用于临时储存数据

然而,寄存器能寄存的数据量是很小的

因此,需要内存配合cpu操作

将两个数据相加的操作:

先从内存取一个加数到寄存器中

再从内存取另一个加数到另一个寄存器中

激活算术逻辑单元的加法电路

输出到寄存器

再存放到内存中

如何表达一个数据类型?(以int为例)

列举首地址及占用储存空间大小

指针

取地址运算符&

&数据对象

获取数据对象的首地址和所需存储空间大小

int n;

int * pn = &n;  //声明了一个指针变量,用于保存变量n首地址和所需空间大小

char c;
char * pc = &c; //声明了一个指针变量,保存变量c的首地址和所需空间大小

我们把pn称作n的指针或者说pn指向n

声明指针类型变量

目标数据类型 * 变量名

指针类型的值是目标数据对象的首地址

#include <stdio.h>
int main()
{
    int n1;
    int *pn1 = &n1;
    printf("%u",pn1);
}

输出: 6291044

char类型指针通过char类型来记录所占用的字节大小为一个字节

int类型指针通过int类型来记录所占用的字节大小为四个字节

总结:指针类型是通过值来保存目标数据对象的首地址,通过类型本身来标记目标数据对象的空间大小.

使用指针

取值运算符*

*指针

根据指针中存储的首地址和空间大小找到目标数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%u\n",pn);
    printf("%d\n",*pn);

    return 0;
}

输出;

6291044

123

第一个printf打印的是n的首地址

第二个printf打印的是n的值

通过指针修改所指向的数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    char c = 'C';
    char *pc = &c;

    *pn = 123;
    *pc = 'A';
    printf("%d\n",n);
    printf("%c\n",c);
    printf("%d\n",*pn);
    printf("%c\n",*pc);

    return 0;
}

输出:

123

A

123

A

说明通过指针更改的数据生效

指针类型占用的空间大小

32位 4字节

64为 8字节

指针运算

指针类型与整型加减

指针类型+1后

将首地址向后移动了sizeof(目标数据对象)个字节

指针类型相减后,结果为两个首地址差值除以步长

指针与数组

数组元素在内存中是连续的

第一个元素的首地址就是整个数组的首地址

直接指针指向数组打印出来的地址也是首地址

#include <stdio.h>
int main()
{
    int arr[5] = {111,222,333,444,555};
    int *p = &arr[0];
    printf("%d\n",*p);
    printf("%d\n",*(p+1));  //取值运算符的优先级高于算数运算符,所以要把p+1括起来
    printf("%d\n",*(p+2));
    printf("%d\n",*(p+3));
    printf("%d\n",*(p+4));
    printf("%d\n",p);
    printf("%u\n",arr);  //直接打印数组名arr的值也是首地址
    int *p2 = arr;  //arr在表达式中会被转化为指向数组第一个元素的指针
    return 0;
}

内存地址

CPU由三个部分组成

算数逻辑单元:对数据执行逻辑运算

控制单元:协调机器活动电路

寄存器组:用于临时储存数据

然而,寄存器能寄存的数据量是很小的

因此,需要内存配合cpu操作

将两个数据相加的操作:

先从内存取一个加数到寄存器中

再从内存取另一个加数到另一个寄存器中

激活算术逻辑单元的加法电路

输出到寄存器

再存放到内存中

如何表达一个数据类型?(以int为例)

列举首地址及占用储存空间大小

指针

取地址运算符&

&数据对象

获取数据对象的首地址和所需存储空间大小

int n;

int * pn = &n;  //声明了一个指针变量,用于保存变量n首地址和所需空间大小

char c;
char * pc = &c; //声明了一个指针变量,保存变量c的首地址和所需空间大小

我们把pn称作n的指针或者说pn指向n

声明指针类型变量

目标数据类型 * 变量名

指针类型的值是目标数据对象的首地址

#include <stdio.h>
int main()
{
    int n1;
    int *pn1 = &n1;
    printf("%u",pn1);
}

输出: 6291044

char类型指针通过char类型来记录所占用的字节大小为一个字节

int类型指针通过int类型来记录所占用的字节大小为四个字节

总结:指针类型是通过值来保存目标数据对象的首地址,通过类型本身来标记目标数据对象的空间大小.

使用指针

取值运算符*

*指针

根据指针中存储的首地址和空间大小找到目标数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%u\n",pn);
    printf("%d\n",*pn);

    return 0;
}

输出;

6291044

123

第一个printf打印的是n的首地址

第二个printf打印的是n的值

通过指针修改所指向的数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    char c = 'C';
    char *pc = &c;

    *pn = 123;
    *pc = 'A';
    printf("%d\n",n);
    printf("%c\n",c);
    printf("%d\n",*pn);
    printf("%c\n",*pc);

    return 0;
}

输出:

123

A

123

A

说明通过指针更改的数据生效

指针类型占用的空间大小

32位 4字节

64为 8字节

指针运算

指针类型与整型加减

指针类型+1后

将首地址向后移动了sizeof(目标数据对象)个字节

指针类型相减后,结果为两个首地址差值除以步长

指针与数组

内存地址

CPU由三个部分组成

算数逻辑单元:对数据执行逻辑运算

控制单元:协调机器活动电路

寄存器组:用于临时储存数据

然而,寄存器能寄存的数据量是很小的

因此,需要内存配合cpu操作

将两个数据相加的操作:

先从内存取一个加数到寄存器中

再从内存取另一个加数到另一个寄存器中

激活算术逻辑单元的加法电路

输出到寄存器

再存放到内存中

如何表达一个数据类型?(以int为例)

列举首地址及占用储存空间大小

指针

取地址运算符&

&数据对象

获取数据对象的首地址和所需存储空间大小

int n;

int * pn = &n;  //声明了一个指针变量,用于保存变量n首地址和所需空间大小

char c;
char * pc = &c; //声明了一个指针变量,保存变量c的首地址和所需空间大小

我们把pn称作n的指针或者说pn指向n

声明指针类型变量

目标数据类型 * 变量名

指针类型的值是目标数据对象的首地址

#include <stdio.h>
int main()
{
    int n1;
    int *pn1 = &n1;
    printf("%u",pn1);
}

输出: 6291044

char类型指针通过char类型来记录所占用的字节大小为一个字节

int类型指针通过int类型来记录所占用的字节大小为四个字节

总结:指针类型是通过值来保存目标数据对象的首地址,通过类型本身来标记目标数据对象的空间大小.

使用指针

取值运算符*

*指针

根据指针中存储的首地址和空间大小找到目标数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    printf("%u\n",pn);
    printf("%d\n",*pn);

    return 0;
}

输出;

6291044

123

第一个printf打印的是n的首地址

第二个printf打印的是n的值

通过指针修改所指向的数据对象

#include <stdio.h>
int main()
{
    int n = 123;
    int *pn = &n;
    char c = 'C';
    char *pc = &c;

    *pn = 123;
    *pc = 'A';
    printf("%d\n",n);
    printf("%c\n",c);
    printf("%d\n",*pn);
    printf("%c\n",*pc);

    return 0;
}

输出:

123

A

123

A

说明通过指针更改的数据生效

指针类型占用的空间大小

32位 4字节

64为 8字节

指针运算

指针类型与整型加减

指针类型+1后

将首地址向后移动了sizeof(目标数据对象)个字节

指针类型相减后,结果为两个首地址差值除以步长

指针与数组