C语言答疑解惑

C语言答疑解惑
C语言中有很多函数、语言特性用的不是很熟悉,特别是涉及指针的操作,总是自己认为怎样怎样,却没有真正的去使用,没有使用就没有发言权。这里结合使用VS2005探究自己疑惑之所在,以后遇到的继续补充。
一、函数的使用
(1)malloc和free:malloc和free用于动态内存的申请和释放,对应于C++中的new和delete。
void *malloc(long NumBytes):分配NumBytes个字节,并返回一个指针指向该区域。如果申请失败,返回NULL。
void free(void *FirstByte):用于释放FirstByte指向的内存区域。
程序如下:
int* p = NULL;
p = (int *)malloc(sizeof(int)*5);
memset(p,0,sizeof(int)*5);
free(p);
p = NULL;
执行p = (int *)malloc(sizeof(int)*5);语句后,p被分配内存地址和内存内容为:
0x003B2F50 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd fd
执行memset(p,0,sizeof(int)*5);后内存情况为:
0x003B2F50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fd
int类型占用四个字节,一共20个字节全部初始化为0。
执行free后,该地址内容为:
0x003B2F50 ee fe ee fe ee fe ee fe ee fe ee fe ee fe ee fe ee fe ee fe
内存地址空间被释放,但是此时p仍然指向0x003b2f50,执行p = NULL;后,p指向地址0x00000000。
(2)memset:首先明确一点,memset是字节操作函数,因此其头文件是string.h。
void *memset(void *s, int ch, unsigned n):将s开始的n个字节全部初始化为ch的ascii码值。
它是逐个字节进行操作,因此,对于char这种一个字节的数据类型,可以达到我们的初始化要求。而如果是int数据类型,则会出现不是我们预想的情况:
char arr[5];
memset(arr,0,5);

int integer[5];
memset(integer,0,5*sizeof(int));
int integer1[5];
memset(integer1,1,5*sizeof(int));
printf("%d",integer1[0]);
内存情况为:
Arr:0x0012FF4C 00 00 00 00 00
Integer:0x0012FF30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Integer1:0x0012FF14 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
Int类型占四个字节,每个字节用1进行替换,一个字节包括8bit,因此替换的内容为00000001000000010000000100000001,所以打印输出integer1[0]时输出的是这个二进制的十进制表示,也就是16843009。
(3)memcpy和strcpy
void* memcpy(void *dest, const void* src, size_t n):从src开始的内存位置拷贝n个字节到dest指向的内存位置。仍然是拷贝字节。
void *strcpy(char* dest, const char* src):拷贝的是字符串,以\0为结束标志(直到遇到\0拷贝停止,\0参与拷贝)。如果碰不到\0,trcpy一直复制,存在危险,因此建议使用strncpy(dest,src,n);
对于char类型而言,memcpy增加了拷贝个数的限制,strcpy完成整个字符串的拷贝。
二、语言特性:
(1)字符数组和字符串
char c[] = "Hello";
char *cc = "World";
int a = sizeof(c);
int b = strlen(c);
int aa = sizeof(cc);
int bb = strlen(cc);
字符数组c的数组长度为6,取值a[0]…a[5],包括\0,指针cc指向字符串的长度为5,不包括\0。
Sizeof计算类型所占用的字节数目,计算指针时等于4,但是数组首地址虽然为指针,但是仍然计算数组所占有的字节数目,例如int ax[2];sizeof(ax) = 8;strlen计算字符串长度,不包括\0。
上述程序执行结果为:a = 6; b = 5; aa = 4; bb = 5;
(2)结构体可以直接赋值吗?
struct MyNode myNode;
myNode.i = 1;
myNode.c = 'c';
struct MyNode myNode1;
myNode1 = myNode;
查看myNode1可以看到其值跟myNode相等,完成了直接赋值。但是如果结构体中有指针存在,则直接赋值编程了“浅拷贝”,使用时需要注意。
三、链表的操作
(1)创建链表
typedef struct node
{
int value;
struct node* pNext;
}Node;

Node *head = NULL;
//创建链表
bool create()
{
head = (Node*)malloc(sizeof(Node));
if(NULL == head)
{
return false;
}
head->pNext = NULL;
head->value = 0;
return true;
}
(2)增加节点:
bool add(Node* pNode)
{
Node * pHead = head;
if(pHead == NULL)
{
return false;
}
Node * before = NULL;
while(pHead != NULL)
{
before = pHead;
pHead = pHead->pNext;

}
before->pNext = pNode;
pNode->pNext = NULL;
return false;
}
(3)排序
void sort()
{
//冒泡排序
Node* pHead = head;
if(head == NULL)
{
return;
}
if(pHead->pNext == NULL)
{
return;
}

Node* pi = pHead->pNext;
Node* pj = pi->pNext;
for(;pi != NULL;pi=pi->pNext)
{
for(pj = pi->pNext;pj != NULL;pj=pj->pNext)
{
if(pj->value>pi->value)
{
int tmp = pj->value;
pj->value = pi->value;
pi->value = tmp;
}
}
}
}
(4)删除
void del(int index)
{
int len = 0;
Node *pHead = head;
if(pHead == NULL)
{
return;
}
pHead = pHead->pNext;
while(pHead!=NULL)
{
len ++;
pHead = pHead->pNext;
}

if(index>len)
{
return;
}
pHead = head->pNext;
Node *before = head;
for(int i=0;i<index;i++)
{
before = pHead;
pHead = pHead->pNext;
}
Node *after = pHead->pNext;
free(pHead);
before->pNext = after;
return;
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值