当前位置:首页 > 资讯 > info5 > 正文

Linux 第六课

发表于: 2016-07-18   作者:jxm_96   来源:转载   浏览:
摘要: 如何避免野指针1.当我们定义一个指针时,如果这个指针没有指向,要置空//#defineNULL(void*)0 char*p=NULL; 对指针置空,有利于提醒我们不对零地址操作,另外,当出运行出现段错误时方便检查是否对零地址操作。零地址:不可以进行复制操作,也不可以对零地址内的值进行修改。初始化为零地址(NULL),让我们形成条件反射,不能对零地址进行操作2.在使用指针之前要检查指针是否合法,如

如何避免野指针

1.当我们定义一个指针时,如果这个指针没有指向,要置空

//#define NULL (void *)0
char *p = NULL;

对指针置空,有利于提醒我们不对零地址操作,另外,当出运行出现段错误时方便检查是否对零地址操作。

零地址:不可以进行复制操作,也不可以对零地址内的值进行修改。初始化为零地址(NULL),让我们形成条件反射,不能对零地址进行操作

2.在使用指针之前要检查指针是否合法,如果为零地址,就要用malloc进行分配。

#define MAX_SIZE 100
char *ptr;
ptr = (char *)malloc(sizeof(char) * MAX_SIZE);

分配完后要检查是否分配成功

if(ptr ==NULL)
{
    printf("error!");
    exit(1);
}

malloc 函数的原型

void *malloc(size_t size);

void 是万能指针,可以接受任何类型的指针,但是不能取值。
*使用malloc之前为什么要进行强制类型转换?
因为C语言中指针的赋值一定要是相同类型指针之间的赋值。如果不是相同指针类型就会出现越界(将步长小的指针赋值给步长大的指针)或丢失(将步长大的指针赋值给步长小的指针)

3.在使用malloc分配的空间之前,要进行清空缓存或赋初值操作。

#include<string.h>
memset(ptr,0,MAX_SIZE * sizeof (char));
//bzero(ptr,MAX_SIZE * sizeof (char));

memset函数原型
函数的功能:将以s为首地址的大小为n的空间初始化为c

void *memset(void *s, int c, size_t n);
//s:要清空的空间的首地址
//c:要赋的初始值;一般为0(也可以写为'\0')
//n:要清空的空间的大小

bzero函数原型
函数功能:将以s为首地址大小为n的空间初始化为0

void bzero(void *s, size_t n);
//s:要清空的空间的首地址
//n:要清空的空间的大小

*指针不可以相加,但可以相减
指针 - 指针:两个地址之间相差的数据类型数据的个数

数组

*数组长度不要用变量名来表示,要明确指定或者定义宏
*一维数组
一维数组数组名是指针常量,保存数组首元素的地址

#include<stdio.h>

int main()
{
    int a[MAX_SIZE];
    int *p = a;
    int (*pa)[MAX_SIZE] = &a;
    //保存一维数组的数组地址的指针:一维数组指针
    int i;

    for(i = 0;i < MAX_SIZE;i++)
    {
        scanf("%d",a + i);
        //scanf("%d",&a[i]);
        //scanf("%d",p + i);
        //scanf("%d",p++);
        //scanf("%d",&p[i]);
        /*scanf("%d",a++); 错误*/
        //scanf("%d",*pa + i);
        //scanf("%d",&((*pa)[i]));
    }

    p = a;
    for(i = 0;i < MAX_SIZE;i++ )
    {
        printf("%d\n",*(a + 1));
        //printf("%d\n",a[i]);
        //printf("%d\n",*(p + i));
        //printf("%d\n",*(p++));
        //printf("%d\n",*(*pa + i));
        //printf("%d\n",(*pa)[i]);
    }
    return 0;
}

*二维数组
二维数组数组名是首个一维数组的地址
Linux 第六课_第1张图片

( ( a + i) + j);
a + i: 第i+1个一维数组的地址
*(a + i): 第i +1个一维数组首元素的地址
*(a + i) +j:第i + 1个一维数组的第j + 1个元素的地址
( (a + i) + j):第i + 1个一维数组的第j + 1个元素的值

*三维数组
三位数组的数组名表示首个二维数组的地址
( ( * (a + i) + j ) + k);
a + i 第i+1个二维数组的地址
*(a + i) 第i + 1个二维数组的首个一维数组的地址
*(a + i) +j 第i + 1个二维数组的第j + 1个一维数组的地址
* ( * (a + i) + j) 第i + 1个二维数组的第j + 1个一维数组的首元素的地址
* ( * (a + i) + j ) + k 第i + 1个二维数组的第j + 1个一维数组的第k + 1个元素的地址
* ( * ( * (a + i) + j ) + k) 第i + 1个二维数组的第j + 1个一维数组的第k + 1个元素的值

*字符数组

#include<stdio.h>

int main()
{
    char src[3][100];
    char (*p_src)[3][100];
    p_src = &src;//*p_src = src;
    int i;
    for(i = 0;i < 3;i++)
    {
        scanf("%s",src[i]);
        //scanf("%s",*(src + i));
        //scanf("%s",(*p_src)[i]);
    }

    for(i = 0;i < 3;i++)
    {
        printf("src = %s\n",src[i]);
        //printf("src = %s\n",*(src + i));
        //printf("src = %s\n",(*p_src)[i]);
    }
    return 0;
}

*函数传参
传一维数组,用元素指针
传二维数组,用一维数组指针
传三维数组,用二维数组指针
传指针数组,用指针的指针

*一维数组作为形参进行传递时,该数组自动退化为同类型的指针

//传二维数组
void printf_src(char (*ptr)[100])
//100为步长,不可省略
{
    int i;
    for(i = 0;i <3;i++)
    {
        printf("%s\n",*(ptr + i));
        //ptr + i 即第i+ 1个一维数组的地址
    }
}
//传指针数组
//char *ptr[3];
void print_ptr(char **ptr);
#include<stdio.h>

int main()
{
    char *ptr[3] = {"hello1","hello2","hello3"};
    //赋值时每个字符串常量的首元素的地址作为字符串的地址,保存在ptr[i]中,且字符串常量保存在数据段的rodata段,不可以被修改
    char src[3][100] =         {"hello1","hello2","hello3"};
    //在占空间中开辟300大小的空间用来存储三个一维数组,此时里面的值可以被修改
    int i;

    //*(ptr[0]) = 'L';运行时报段错误
    *(src[0]) = 'L';正确

    for(i = 0;i < 3;i++)
    {
        printf("%s\n",ptr[i]);
    }

    return 0;
}
  • int a[2][2] = {1,2,3,4};
    //书写时可以省略行数(a[][2]),但不可以省略列数

Linux 第六课

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
读书是一个由厚读薄,再由薄读厚的过程。孟宁的《Linux内核分析》在课上把繁杂庞大的Linux内核抽像
伪代码(伪代码是用来记住算法的) 代码 View Code #include <iostream> #include <vector&g
■ 集合类 集合框架中的接口 Collection:集合层次中的根接口,JDK没有提供这个接口直接的实现类。
学习texture map纹理映射(贴图)有很多好处。比方说您想让一颗导弹飞过屏幕。根据前几课的知识,我
今天要讲的是OpenGL光照的基本知识。虽然内容显得有点多,但条理还算比较清晰,理解起来应该没有困
二 物化视图 物化视图:执行sql并保留结果,直接放在数据文件中,不放在内存中方便重用【空间换时间
三 外部表 官方文档:Administrator’s Guide -> 15 Managing Tables -> Managing External T
1序言:   1.初学者经过学习前面的Makefile知识,信心满满,内心觉得应该要好好学习不单掌握语言
面向对象首先要先了解什么是面向对象? 面向对象:就是不断的和对象打交道。 早期解决问题,都是面
1.课程大纲 本课时首先会介绍索引的概念,然后会详细介绍索引的类型,将重点介绍单字段索引、复合索
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号