C语言基础-NULL和0的区别及结构体初始化问题

序言

继续总结C语言中的一些细枝末节的知识点,厘清不熟悉的地方。

本文主要内容:

  • C语言中0和NULL的区别

  • 结构体初始化取值问题


1. C语言中0和NULL的区别


  • 0作为一个整数,是一个数值,可以是整型int,字符型char,长整型long等等。


  • 0作为一个指针,是一个空指针常量。(i.e. 指针内容全为0,0x00000000),常见的 0‘\0’0L3 - 30 * 17等都是空指针常量。

    • ’\0’字符串结束符,用在字符串的末尾,不是指针,也不是普通的数值

  • 什么是空指针:指针通过空指针常量赋值之后就是一个空指针,不指向任何实际的对象或者函数。


  • 什么是NULL:在C语言 stdio.h / stddef.h中有如下定义

    • NULL是一个标准规定的宏定义,用来表示空指针常量
    
    #define  NULL  ((void *)0)
    


  • NULL和0

    • 在C语言中,可以说NULL就是0,两者是完全等价的。只不过NULL用在指针和对象,0多用于数值。

    • NULL的值(i.e. NULL指向了内存中的什么地方):

      • 取决于系统的实现,对于大多数系统(某些系统中NULL和0的值不同)来说,一般指向0地址,即空指针的内部全用0来表示,64位机下0x00000000。

      • 指针初始化为NULL,指向一个无意义地址,实际上是指向了0x00000000。


2. 结构体初始化

(1) 结构体元素通过以下方式初始化后每一个元素的取值为多少?

  • [1] 结构体指针元素 - 未分配空间

现有结构体

structure node
{
    int data;
    struct node* next;
};

则通过下列方式初始化之后

struct node* newNode = NULL;

每个元素的取值为多少?

答:

  1. 在程序中,node结构体的代码段,如果不主动分配空间,编译器不会为其分配空间的
  2. 这样,当声明了newNode结构体之后,newNode = NULL只表示该指针指向NULL,不指向内存中的任意地址,不涉及其中具体取值。


  • [2] 结构体指针元素 - 分配空间

初始化方式1:

struct node* newNode;

newNode = (struct node *)malloc(sizeof(struct node));

memset(newNode, 0, sizeof(struct node));

每个元素的取值为多少?

分配空间之后进行如上的memset()初始化,表示

newNode -> data = 0;
newNode -> next = 0 或者说 NULL;

对于大多数系统,使用memset()来得到空指针和 *pointer = NULL 方式是等价的,但有的系统memset(p, 0, sizeof(p))时会在pointer中存着“非零空指针”。所以可用如下方式初始化

初始化方式2:

struct node* newNode;

newNode = (struct node *)malloc(sizeof(struct node));

newNode -> data = 0;
newNode -> next = NULL;

结论:

  • 指针初始化时,采用 pointer = NULL 和 pointer = 0 都是可以的。

  • 在C语言中,采用 memset() 和 元素分别赋值初始化 都是可以的,没有区别。


3. NULL和0的区别以及结构体指针初始化验证示例

  • 代码(C)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct test
{
    int data;
    struct test *next;
    int data1;
    struct test *prev;
};

int main()
{
    //有符号和无符号数
    int a = 1;
    char b = (0 - 1);
    unsigned char c = (0 - 1);
    printf("%d\n", b);
    printf("%u\n", c);

    //NULL和0的比较
    int *p1 = NULL, *p2 = 0, *p3 = &a;
    int *p4 = (int *)malloc(sizeof(int));
    memset(p4, 0, sizeof(int));

    //结构体初始化
    struct test *p5 = (struct test *)malloc(sizeof(struct test));
    memset(p5, 0, sizeof(struct test));
    struct test *p6 = (struct test *)malloc(sizeof(struct test));
    p6->data = 0;
    p6->next = NULL;

    printf("%d\n", sizeof(struct test));
    printf("%d\n", p5->data);
    printf("%d\n", p6->data);

    printf("0x%p 0x%p 0x%p 0x%p 0x%p 0x%p\n", p1, p2, p3, p4, p5->next, p6->next);
    return 0;
}
  • 输出
-1 【有符号数,0 - 1为 -1】
255 【无符号数8bit数,0 - 1为 11111111 = 255】
24 【第一个struct test *next以int data为准对齐,第二个struct test *prev以double data1对齐,整个结构体大小为最大元素double data1大小整数倍】
0 【用memset()初始化为0】
0 【直接赋值初始化为0】
0x00000000 【*p1 = NULL,其值为0x00000000,即NULL的地址为0x00000000】
0x00000000 【*p2 = 0,其值也为0x00000000,即0的地址为0x00000000】
0x0028FF00 【*p3 = &a,即变量a的地址为0x0028FF00】
0x00031080 【*p4 = 结构体地址,程序每次执行都会变】
0x00000000 【p5 -> next,使用memset()将结构体指针初始化为空指针】
0x00000000 【p6 -> next,使用直接赋值将结构体指针初始化为空指针】



http://www.cnblogs.com/youxin/archive/2012/03/27/2420023.html

2017.08.27

  • 25
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值