首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

京柏之路

链表的基本操作及链表自身逆序。

/*---- chain operate from Data Structure ---*/

#include

#include

#include

typedef int DataType;

typedef struct Node

{

DataType data;

struct Node *next;

}SLNode;

//---- initiate

void ListInitiate(SLNode **head)

{

if( (*head=(SLNode *)malloc(sizeof(SLNode)))==NULL ) exit(1);

else printf("OK\n");

(*head)->next=NULL;

}

//---- length cal

int ListLength(SLNode *head)

{

SLNode *p=head;

int size=0;

while(p->next!=NULL){

p=p->next;

size++;

}

return size;

}

//----insert a node

int ListInsert(SLNode *head,int i,DataType x)

{

SLNode *p,*q;

int j;

p=head;

j=-1;

while( (p->next!=NULL) && (j

p=p->next;

j++;

}

if(j!=(i-1)) {

printf("Position error\n");

return 0;

}

if((q=(SLNode *)malloc(sizeof(SLNode)))==NULL)

exit(1);

q->data=x;

q->next=p->next;

p->next=q;

return 1;

}

//----delete a node

int ListDelete(SLNode *head,int i,DataType *x)

{

SLNode *p,*s;

int j;

p=head;

j=-1;

while((p->next!=NULL) && (p->next->next!=NULL) && (j

p=p->next;

j++;

}

if(j!=i-1){

printf("Position error\n");

return 0;

}

s=p->next;

*x=s->data;

p->next=p->next->next;

free(s);

return 1;

}

//----- data get

int ListGet(SLNode *head,int i,DataType *x)

{

SLNode *p;

int j;

p=head;

j=-1;

while((p->next!=NULL)&&(j

p=p->next;

j++;

}

if(j!=i) {

printf("Position error\n");

return 0;

}

*x=p->data;

return 1;

}

//----Destroy a chain

void Destroy(SLNode **head)

{

SLNode *p,*p1;

p=*head;

while(p!=NULL) {

p1=p;

p=p->next;

free(p1);

}

*head=NULL;

}

//-----converse a chain

void converse(SLNode *head)

{

SLNode *p,*q;

p=head->next;

head->next=NULL;

while(p!=NULL) {

q=p;

p=p->next;

q->next=head->next;

head->next=q;

}

}

//---- composite operation

int main(void)

{

SLNode *head;

int i,x;

ListInitiate(&head);

for(i=0;i

if(ListInsert(head,i,i)==0){

printf("Error\n");

return 1;

}

}

if(ListDelete(head,0,&x)==0) // chain,position,data address

{

printf("Error\n");

return 1;

}

if(ListInsert(head,0,100)==0) {

printf("Error\n");

return 1;

}

converse(head);

for(i=0;i

if(ListGet(head,i,&x)==0) // chain,position,data address

{

printf("Error\n");

return 1;

}

else printf("%d ",x);

}

printf("\n");

Destroy(&head);

return 0;

}

12

void GetMemory(char *p)

{

p = (char *)malloc(100);

}

void Test(void)

{

char *str = NULL;

GetMemory(str);

strcpy(str, "hello world");

printf(str);

}

形参的内存分配不能实质给实参,函数执行完会销毁。程序会崩溃

GetMemory并不能传递动态内存,

Test函数中的 str一直都是 NULL

()

char *GetMemory(void)

{

char p[] = "hello world";

return p;

}

void Test(void)

{

char *str = NULL;

str = GetMemory();

printf(str);

}

内容未知

可能是乱码

因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知

void GetMemory2(char **p, int num)

{

*p = (char *)malloc(num);

}

void Test(void)

{

char *str = NULL;

GetMemory(&str, 100);

strcpy(str, "hello");

printf(str);

}

内存泄漏

输出hello

void Test(void)

{

char *str = (char *) malloc(100);

strcpy(str, “hello”);

free(str);

if(str != NULL)

{

strcpy(str, “world”);

printf(str);

}

}

篡改动态内存区的内容,后果难以预料,非常危险。

因为free(str);之后,str成为野指针,

if(str != NULL)语句不起作用

13

int strcmpa (const char *str1,const char *str2)

{

int len = 0;

assert((str1 != '\0') && (str2 != '\0'));

while(*str1 && *str2 && (*str1==*str2))

{

str1++;

str2++;

}

return *str1-*str2;

}

char *strcpy(char *strDest, const char *strScr)

{

char *address=strDest;

assert((strDest != NULL) && (strScr != NULL));

while(*strScr) //是while(*strScr != ’\0’)的简化形式;

{

*strDest++ = *strScr++;

}

*strDest = '\0'; //当strScr字符串长度小于原strDest字符串长度

return address; //时,如果没有改语句,就会出错了。

}

14

#include"string.h"

main()

{

char*src="hello,world";

char* dest=NULL;

int len=strlen(src);

dest=(char*)malloc(len);

char* d=dest;

char* s=src[len];

while(len--!=0)

d++=s--;

printf("%s",dest);

return 0;

}

int main()

{

char* src = "hello,world";

int len = strlen(src);

char* dest = (char*)malloc(len+1);//要为分配一个空间    char* d = dest;

char* s = &src[len-1]; //指向最后一个字符

while( len-- != 0 )

*d++=*s--;

*d = 0; //尾部要加’\0’

printf("%sn",dest);

free(dest); // 使用完,应当释放空间,以免造成内存汇泄露

dest = NULL;   //防止产生野指针

return 0;

}

15

用宏定义写出swap(x,y)

答#define swap(x, y)

x = x + y;

y = x - y;

x = x - y;

16

全局变量和局部变量在内存中是否有区别?如果有,是什么区别?

全局变量储存在静态数据库,局部变量在堆栈。动态申请的数据放在堆区。

静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。

栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。

17

(1)什么是预编译,何时需要预编译:

答案:

1、总是使用不经常改动的大型代码体。

2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

18

要对绝对地址0x100000赋值,我们可以用(unsigned int*)0x100000 = 1234;那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?

答案:*((void (*)( ))0x100000 ) ( );首先要将0x100000强制转换成函数指针,即: (void (*)())0x100000然后再调用它: *((void (*)())0x100000)();用typedef可以看得更直观些: typedef void(*)() voidFuncPtr; *((voidFuncPtr)0x100000)();

19

data ---> 可寻址片内ram

bdata ---> 可位寻址的片内ram

idata ---> 可寻址片内ram,允许访问全部内部ram

pdata ---> 分页寻址片外ram (MOVX @R0) (256 BYTE/页)

xdata ---> 可寻址片外ram (64k 地址范围FFFFH)

code ---> 程序存储区 (64k 地址范围),对应MOVC @DPTR

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180316G1VGAK00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券