歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> Linux 第六課

Linux 第六課

日期:2017/3/3 11:24:40   编辑:Linux技術

如何避免野指針

1.當我們定義一個指針時,如果這個指針沒有指向,要置空
[code]//#define NULL (void *)0
char *p = NULL;

對指針置空,有利於提醒我們不對零地址操作,另外,當出運行出現段錯誤時方便檢查是否對零地址操作。

零地址:不可以進行復制操作,也不可以對零地址內的值進行修改。初始化為零地址(NULL),讓我們形成條件反射,不能對零地址進行操作

2.在使用指針之前要檢查指針是否合法,如果為零地址,就要用malloc進行分配。

[code]#define MAX_SIZE 100
char *ptr;
ptr = (char *)malloc(sizeof(char) * MAX_SIZE);
分配完後要檢查是否分配成功

[code]if(ptr ==NULL)
{
    printf("error!");
    exit(1);
}
malloc 函數的原型

[code]void *malloc(size_t size);
void 是萬能指針,可以接受任何類型的指針,但是不能取值。

*使用malloc之前為什麼要進行強制類型轉換?

因為C語言中指針的賦值一定要是相同類型指針之間的賦值。如果不是相同指針類型就會出現越界(將步長小的指針賦值給步長大的指針)或丟失(將步長大的指針賦值給步長小的指針)

3.在使用malloc分配的空間之前,要進行清空緩存或賦初值操作。

[code]#include<string.h>
memset(ptr,0,MAX_SIZE * sizeof (char));
//bzero(ptr,MAX_SIZE * sizeof (char));
memset函數原型

函數的功能:將以s為首地址的大小為n的空間初始化為c

[code]void *memset(void *s, int c, size_t n);
//s:要清空的空間的首地址
//c:要賦的初始值;一般為0(也可以寫為'\0')
//n:要清空的空間的大小
bzero函數原型

函數功能:將以s為首地址大小為n的空間初始化為0

[code]void bzero(void *s, size_t n);
//s:要清空的空間的首地址
//n:要清空的空間的大小
*指針不可以相加,但可以相減

指針 - 指針:兩個地址之間相差的數據類型數據的個數

數組

*數組長度不要用變量名來表示,要明確指定或者定義宏 *一維數組

一維數組數組名是指針常量,保存數組首元素的地址

[code]#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;
}

*二維數組

二維數組數組名是首個一維數組的地址

( ( 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個元素的值

*字符數組

[code]#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;
}
*函數傳參

傳一維數組,用元素指針

傳二維數組,用一維數組指針

傳三維數組,用二維數組指針

傳指針數組,用指針的指針

*一維數組作為形參進行傳遞時,該數組自動退化為同類型的指針

[code]//傳二維數組
void printf_src(char (*ptr)[100])
//100為步長,不可省略
{
    int i;
    for(i = 0;i <3;i++)
    {
        printf("%s\n",*(ptr + i));
        //ptr + i 即第i+ 1個一維數組的地址
    }
}
[code]//傳指針數組
//char *ptr[3];
void print_ptr(char **ptr);

[code]#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]),但不可以省略列數

Copyright © Linux教程網 All Rights Reserved