美文网首页
指针、函数、预处理器

指针、函数、预处理器

作者: 面向星辰大海的程序员 | 来源:发表于2020-04-10 23:50 被阅读0次

    指针

    指针是一个变量,其值为地址,声明或不再使用后都要将其置为0(类似java释放对象后置为NULL)。

    野指针

    产生原因->

    (定义时未初始化)不初始化会随机指向随机区域,因为任何指针变量(除了static修饰的指针变量)在定义的时候是不会默认固定值的,他的默认值是随机的。

    (释放时未被置NULL(悬空指针))使用molloc开辟内存空间时,要检查返回值是否为NULL,如为NULL则开辟失败,如不为NULL则指针指向的时开辟内存空间的首地址。指针指向的内存空间在用free()或delet(delet是一个操作符)释放后如果没有置null或赋其他值也会成为野指针。

    (指向栈内存的指针)栈内存在函数执行完毕之后会释放

    危害->

    指针指向一个随机地址,不受程序控制。如指向已经被删除的对象或指向一块没有访问权限的内存。指针再次被使用时,导致程序异常。

    如何规避->

    初始化时置为NULL,指针使用完时一定要释放并置为NULL,良好的编程习惯

    指针声明

    int *p=NULL;比较好看的写法

    int* p=NULL;个人认为这个写法比较好理解

    int * p=NULL; 也可以这么写不会报错

    int* a,b;这么写没有初始化,必须初始化

    指针使用

    int i=10;声明一个int类型的变量i赋值为10;

    int* p=NULL;声明一个int类型指针p初始化NULL;

    p=&i;使用取地址符&将i的地址赋值给指针p;(十六进制打印printf("%#x\n",&i),printf("%#x\n",p)得出结果是一样的)

    解引用:解析并返回内存地址中的值 

    int i2=*p;(printf("%d\n", i2);的结果为10)

    *p=100;(printf("%d\n", i);的结果为100,因为p是指向i的地址*p=100相当于往i的地址的内存保存100)

    指针运算

    int i1[] = {11,22,33,44,55};  // 声明一个int类型数组 (java中可以写成 int[] i1={})

    int* p1 = i1;//数组名就是数组在内存中的首地址,数组是内存连续存储的 解引用*数组名会得到第一个元素,i1==&i1;i1+1!=&i1+1

    for (size_t i =0; i <5; ++i) {

    printf("%d\n", *p1++);// (++优先级高,p1++之后取值,地址改变之后取值)输出 11,22,33,44,55  地址++

    printf("%d\n", ++*p1);//++*不成立,++(*p1)(个人理解)输出 12 13 14 15 16 值++

    }

    数组指针与指针数组

    int (*array3)[2] = &array;//数组指针 与int *p=&i;一样,指针p是存着i的地址,指针array3存着array的地址,一个是int数组类型指针,一个是int类型指针

    int* array2[2] = {11,22};//指针数组,array2数组被赋值{11,22}但是array2中第一个元素是一个指向11的指针,第二个是指向22的指针,数组中的元素类型是int类型的指针,所以叫指针数组

    int array2[2]={11,22};int数组,元素值就是int类型的11和22

    二维数组指针  int aa[2][3] = {{11, 22, 33},{44, 55, 66}};或 int aa[2][3] = {11, 22, 33, 44, 55, 66};int (*arr1)[3] = &aa;arr1取值*(*arr1+0),*(*arr1+1),也可以arr1[x][y]下标的方法取值。

    指针常量与常量指针

    从左往右读    const再*之前就是常量指针,反之指针常量,常量指针可修改指向,不可修改指向的值,指针常量可修改指向的值,不可修改指向

    多级指针

    指向指针的指针,一个指针包含另一个指向值的指针的地址。

    指针占用空间

    指针地址在64位计算机中sizeof(p)=8,32位sizeof(p)=4

    函数

    与java的方法没有区别,都是一组执行一个任务的语句,也都有函数头函数体构成。函数需声明在使用之前。传值调用不会影响实参,引用调用可以修改实参。

    可变参数

    函数指针

    函数指针是指向函数的指针变量

    写法:函数返回值(*函数指针变量)(函数的参数) ——》void(*p)(int)

    预处理器

    预处理器不是编译器,但是他是编译过程中一个单独的步骤,预处理器是一个文本替换工具,所有的预处理其都是以井号(#)开头

    常用的预处理器

    宏就是文本替换,#define A 1,宏一般使用大写区分,在代码中使用A就会被替换成1。

    宏函数#define test(a, b) a>b?a:b

    #define apend(arg,arg2) arg ## arg2   ##拼接符

    宏定义一行不够使用  \  延续符也叫宏换行符

    可变宏:#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"NDK", __VA_ARGS__);

    #define MULTI(x,y) x*y这有个坑 printf("%d\n", MULTI(2, 2));输出4  printf("%d\n", MULTI(1+1, 2)); =》1+1*2=3

    相关文章

      网友评论

          本文标题:指针、函数、预处理器

          本文链接:https://www.haomeiwen.com/subject/ezzomctx.html