C语⾔基础-NULL和0的区别及结构体初始化问题
序⾔
继续总结C语⾔中的⼀些细枝末节的知识点,厘清不熟悉的地⽅。
本⽂主要内容:
C语⾔中0和NULL的区别
结构体初始化取值问题
1. C语⾔中0和NULL的区别
0作为⼀个整数,是⼀个数值,可以是整型int,字符型char,长整型long等等。
0作为⼀个指针,是⼀个空指针常量。(i.e. 指针内容全为0,0x00000000),常见的 0、‘\0’、0L、3 - 3、0 * 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] 结构体指针元素 - 未分配空间
现有结构体
sizeof 指针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);
return0;
}
输出
-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,使⽤直接赋值将结构体指针初始化为空指针】2017.08.27
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论