C语言-note002

1. 数组指针

        char* arr3[6];

        char* (*p3)[6] = &arr3;

                p3指向一个数组arr3

                arr3有6个元素

                每个元素的类型是char*

2. 函数指针

        指向函数的指针

        存放的是函数的地址

int test(const char* str) { }

int (*pf) (const char*) = test

        pf指向test函数

        test函数的参数是const char*

        test函数的返回类型是int

3. (* (void (*) () ) 0) ()

          强制类型转换

        (void (*) ()) 是函数指针

        (void (*) ()) 是0的强制类型转换【(类型):强制类型转换】

          把0强制类型转换成函数指针类型

          放的是函数地址(0作为地址处的函数)

4. void (* signal (int, void (*) (int) ) (int);

        signal是函数名

        (int, void (*) (int)是函数指针类型

        void (*         ) (int)也是函数指针类型,说明signal函数返回的也是一个函数指针类型

以上代码是一次函数声明,声明的signal函数的参数signal (int, void (*) (int)

        第一个参数类型是int

        第二个参数类型是函数指针

        参数是int,返回类型是int

        signal函数的返回类型是一个函数指针

简化

        typedef void (* pf_t) (int);        //把void (*) (int)类型重命名为pf_t

        void (* signal (int, void (*) (int) ) (int);

                可以简化成:

        pf_t signal (int,pf_t) ;

一、笔试

1.指针是什么

        指针的本质是地址

        口头上的指针一般指指针变量

                指针变量就是一个变量而已,就是一块内存空间,用来存放地址

        要学习指针,必须知道内存

                内存——内存的单元(1 byte)——编号——地址——指针

                编号、地址、指针是同一个东西

        两个操作符

                &:取地址

                *:解引用

        int* pa = &a;        //pa是指针变量

        *pa = 20;        //通过pa找到a,并修改a的值为20

2.指针类型的意义(决定2件事)

2-1 决定了+1/-1操作跳过几个字节(步长)

2-2 决定了解引用操作时的权限,访问几个字节

        int*:访问4个字节

        double*:访问8个字节

3.指针的运算

3-1 +-整数

3-2 指针 - 指针

3-3 指针的关系运算

...

4.指针数组

        本质是数组

        存放指针的数组

        数组中存放的是指针(地址)

3个int*类型的变量

        int* pa;

        int* pb;

        int* pc;

把这3个int*类型的变量存放到数组中

        int* arr[3] = {pa,pb,pc};        //3个变量的类型是int*

5.数组名是什么

        5-1 数组名大部分情况下表示首元素地址

                有2个列外,表示整个数组

                5-1-1 sizeof(数组名)

                        表示整个数组

                        计算的是整个数组的大小,单位时字节

                5-1-2 &数组名

                        表示整个数组

                        取出的是整个数组的地址

        5-2 &数组名:取出的是数组的地址

                数组指针

                        int a = 0;

                        int* pa = &a;//pa是整型指针

                       

                        char ch = ‘w';

                        char* pc = &ch;//pc是字符指针

                

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

                        int(*parr)[10] = &arr;//parr是数组指针

                                *:告诉是指针

                                [10]:10个元素

                                int:每个元素是int类型

                

                函数指针

                      

                        int Add(int x,int y)

                        {

                                return x+y;

                        }

                        int (*pf (int x,int y)) = &Add;//函数的地址存放到函数指针变量中

                        printf(“%d\n”,&Add);

                        int sum = (*pf)(2,3);//解引用

                函数指针实现回调函数

                        回调函数:通过函数指针调用的函数就是回调函数

        函数指针数组

                  存放函数指针的数组

                  int (*pfArr[4] )(int,int)

                        pfArr[4] :数组,可以放4个元素

                        int(*)(int,int):数组元素类型

int a[ ] = {1,2,3,4};

        sizeof(a);        //sizeof(数组名),表示整个数组

        sizeof(a + 0);        //a不是单独放在sizeof内部,也没有取地址,所以a就是首元素地址,

                                        a+0还是首元素地址;   

                                         a<==>&a[0]        ,   a + 0<==>&a[0]+ 0

        sizieof(*a);a--首元素地址,*a--首元素

                                *a就是对首元素地址的解引用,找到的就是首元素

                                a<==>&a[0],  *a<==>*&a[0]

                                *和&抵消

        sizeof(a+1);        //第二个元素地址 4/8字节

        sizeof(a[1])        // 第二个元素地址

        

        sizeof(&a);        //&取的是数组的地址 4/8字节

        sizeof(*&a);        //&a取出数组的地址

                                             *&a对地址解引用,拿到a

                                                sizeof(*&a)<==>sizeof(数组名)

        sizeof(&a+1);        //跳过一个数组的地址(一个数组【int a[ ] = {1,2,3,4};】的地址:4个整型元素),还是地址,4/8字节

        sizeof(&a[0]);        //第一个元素地址

        sizeof(&a[0]+1);        //第一个元素地址+1<==>第二个元素地址<==>&a[1]

字符数组

char arr[ ] = {'a','b','c','d','e','f'};

        sizeof(arr);        //sizeof(数组名),整个数组大小

        sizeof(arr+0)        //首元素地址+0,还是首元素地址

        sizeof(*arr);        //首元素地址解引用,拿到首元素arr[0]

        sizeof(arr[1])        //第二个元素地址

        sizeof(&arr)        //&arr是数组的地址

        sizeof(&arr+1)        //取地址+1,跳过整个地址

        sizeof(&arr[0] + 1)        //第二个元素地址

char arr[ ] = {'a','b','c','d','e','f'};

        strlen(arr);        //随机值

        strlen(arr + 0);        //随机值

        strlen(*arr);        //首元素地址解引用,拿到首元素

                                        //野指针,报错

        strlen(arr[1]);        //野指针

        strlen(&arr)        //随机值

        strlen(&arr + 1)        //随机值-6

        strlen(&arr[0]+ 1)        //随机值-1

sizeof

        操作符

        只关注占用内存空间大小,不关注内存中存放的是什么

strlen

        库函数

        只针对字符串

        求字符串长度,关注的是字符串中‘\0’

        计算'\0'之前的字符个数

char arr[ ] = "abcdef";

        sizeof(arr);        //7;        隐藏了一个\0,所以是7个元素

        sizeof(arr+0)        //首元素地址+0,还是首元素地址

        sizeof(*arr)        //首元素地址解引用,拿到a

        sizeof(arr[1])        //第2个元素

        sizeof(&arr)        //取出整个数组地址

        sizeof(&arr+1)        //取地址+1

        sizeof(&arr[0]+1)        //首元素地址+1

char arr[ ] = "abcdef";

        strlen(arr)        //字符串长度

        strlen(arr+0        //首元素地址+0,还是首元素地址

        strlen(&arr)        //取出整个数组地址

        strlen(&arr + 1)        //随机值

        strlen(&arr[0] + 1)        //5;元素地址+1

char* p = "abcdef";

        sizeof(p);        //指向字符a,4/8

        sizeof(p+1)        //4/8

        sizeof(*p)        //1

        sizeof(p[0])        //

        sizeof(&p)        //

        sizeof(&p + 1)        //

        sizeof(&p[0]+1)        //

        strlen(p);        //6

        strlen(p+1)        //跳过1个字符,b的后面开始数;5

        strlen(*p)        //error

       strlen(p[0])        //error

        strlen(&p)        //随机值

        strlen(&p + 1)        //随机值

        strlen(&p[0]+1)        //

int a[3][4] = {0};

        sizeof(a);        //3*4*4;        3行4列*4字节

        sizeof(a[0][0]);        //

        sizeof(a[0]);        // 数组名[下标]:访问该行元素,列j的取值0——3;a[0]是第一行

        sizeof(a[0]+1)        //a[0]第一行第一个元素1地址;a[0]+1----第一行第二个元素地址

        sizeof(*(a[0]+1))        //第一行第二个元素

        sizeof(a+1)         //a表示首元素地址(二维数组的首元素地址是第一行地址);a+1是第二行地址

        sizeof(*(a+1))        // 对第二行的地址解引用,拿到第二行

        sizeof(&a[0]+1)        //&a[0]:对第一行取地址,拿到第一行的地址;&a[0]+1拿到第二行的地址

        sizeof(*(&a[0] +1))        //对第二行地址解引用,拿到第二行数据

        sizeof(*a)        //a表示第一行的地址;*a对第一行地址解引用,拿到第一行的数据

        sizeof(a[3])        //访问任意一行

p[4][2] ——>*(*(p-+4)+2)

        

                        

        

        

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值