[C] 基础代码 - 全

版块1

#include <stdio.h>
#include <stdbool.h>//为了bool类型
#include <malloc.h> 
#include <stdlib.h>//包含了exit函数

//定义了一个数据类型,该数据类型的名字叫 struct Arr
//该数据类型含有三个成员

struct Arr   //它不是定义变量!!
{
int * pBase;//存储的是数组的第一个元素的地址

int len;//数组所能容纳的最大元素的个数

int cnt;//当前数组有效元素的个数

int increament;//自动增长因子
};

//面向过程的函数使用(此处是比Java更加底层的东西):

void init_arr (struct Arr * pArr, int length);//初始化

bool append_arr (struct Arr *pArr, int val);//追加

bool insert_arr (struct Arr *pArr, int pos, int val);//插入/pos(表示下标)的值从1开始 ,插在前面,即放在角标为pos-1的位置里

bool delete_arr (struct Arr *pArr, int pos, int *pVal);//用pVal来返回删除值,pos用法同上

int get ();        //返回数组元素

bool is_empty (struct Arr * pArr);

bool is_full (struct Arr * pArr);

void sort_arr (struct Arr * pArr);//排序(冒泡)

void show_arr (struct Arr * pArr);//输出

void inversion_arr (struct Arr * pArr);//倒置

//主函数

int main (void)
{
struct Arr arr;
//这里才是定义的变量 ,此时arr里面的pBase/len/cnt都是垃圾数字
//结构体变量可以相互赋值

int val;

init_arr (& arr, 6);
//通过init初始化函数来赋值arr里面的pBase/len/cnt
//这些括号传地址&,更加方便,只需要传首字节的4个地址,然后pBase指针依次+1,通过malloc来得到下一个字节
//如果直接写arr,就要传数组所有的地址

show_arr(& arr);//输出

append_arr (& arr,1);
append_arr (&arr,10);
append_arr (& arr,-3);
append_arr (& arr,88);//追加

if (delete_arr(&arr, 1, &val))
{
printf("删除成功!\ n");
printf("您删除的元素是:% d \ n", val);
}
else
{
printf ("删除失败!\ n");
}

/* append_arr (& arr,2);
append_arr(& arr,3);
append_arr (& arr,4);
append_arr (& arr,5);
insert_arr (& arr, 1, 99);//99 1 2 3 4 (pArr->cnt ++;) 5
append_arr(& arr,6);
append_arr(& arr,7);
if (append_arr(&arr,8))
{
printf ("追加成功!\ n");
}
else
{
printf("追加失败!\ n");
}
*/

show_arr (& arr); //插入完毕之后再输出

inversion_arr (& arr);
printf ("倒置之后的数组内容是:\ n");
show_arr (& arr);

sort_arr(&arr);
printf("升序排序之后的数组内容是:\ n");  show_arr (& arr);

return 0;
}

//输入

void init_arr (struct Arr * pArr, int length)
//通过地址赋值才能改变前面的arr.len;

{
(* pArr).len= 99; //arr.len= 99;

pArr->pBase= (int *)malloc (sizeof(int)*length);
//表示pArr指向的结构体变量中的pBase成员
//把第一个字节的地址赋给了pBase
//如果没有足够的内存可以分配,就会给他一个NULL

if (NULL == pArr->pBase) //NULL必须大写
{
printf("动态内存分配失败!\n");
exit (-1);//终止整个程序
}
else
{
pArr->len= length;
pArr->cnt = 0;
}

return; //return表示函数终止了
}

思路:

pArr->pBase[0]=1; cnt=1

pArr->pBase[1]=2; cnt=2

pArr->pBase[2]=3; cnt=3

pArr->pBase[cnt]=val;

++cnt;
//cnt是新放入的元素的下标

C语言/数据结构——提供类库给他人使用

//判断是否为空

bool is_empty (struct Arr * pArr)
//这里的pArr要接收结构体变量的地址
{
if (0= = pArr->cnt)
return true;
else
return false;
}

//判断是否满了

bool is_full (struct Arr * pArr)
{
if (pArr->cnt == pArr->len)
return true;
else
return false;
}

//输出 

//存储不一样,操作不一样;对于泛型,存储不一样,操作一样 

void show_arr(struct Arr * pArr)//这里的pArr已经是"struct Arr *"类型了 

{

 int i;

if( is_empty(pArr) )
//这个pArr是show_arr括号里的
{
printf("数组为空!\n");
}
else
{
for( i=0; i<pArr->cnt; ++i )
{
printf("%d \n", pArr->pBase[i]);
}
}

//数组中的元素:@1:pArr[i],

//首先,pArr不是数组名,就是个结构体变量的名字(地址),如果想要整型数组的地址,就要是int *类型的,即int *[i]

//所以,用pBase决定首元素地址 

}

//追加

bool append_arr(struct Arr *pArr, int val)

{

 if(is_full(pArr))

 return false;

 else

 pArr->pBase[pArr->cnt]=val;

 (pArr->cnt) ++;

 return true;

} 

//插入 

bool insert_arr(struct Arr *pArr, int pos, int val)

{

 int i;

 if(is_full(pArr))

    return false;

 if(pos<1 || pos>pArr->cnt+1)//插入必须前面一个位置有元素存在! 

       return false;

 for(i=pArr->cnt-1; i>=pos-1; --i)//倒着移动 

 {

  pArr->pBase[i+1]=pArr->pBase[i]; //全往后移一位 

 }

 pArr->pBase[pos-1]=val;

 pArr->cnt ++;//有效个数加1 

 return true;

}

//删除 

bool delete_arr(struct Arr *pArr, int pos, int *pVal)

{

 if(is_empty(pArr))

 return false;

 if(pos<1 || pos>pArr->cnt)

 return false;

 int i;

 *pVal=pArr->pBase[pos-1];//必须先赋值,不然下一步这项就没了 

 for(i=pos; i<pArr->cnt; ++i)

 {

  pArr->pBase[i-1]=pArr->pBase[i]; 

 }

 (pArr->cnt)--;

 return true;   

}

//倒置 

void inversion_arr(struct Arr *pArr)

{

 int i=0;

 int j=pArr->cnt-1;

 int t;

 while(i<j){

  t=pArr->pBase[i];

  pArr->pBase[i]=pArr->pBase[j];

  pArr->pBase[j]=t;

++i;

--j;

 } 

 return;

}

//排序(冒泡)

void sort_arr(struct Arr *pArr)

{

 int i,j;

 int t;

 for(i=0; i<pArr->cnt; ++i)

 {

  for(j=i+1; j<pArr->cnt; ++j)

  {

   if(pArr->pBase[i]>pArr->pBase[j])

    {

     t=pArr->pBase[i];

          pArr->pBase[i]=pArr->pBase[j];

          pArr->pBase[j]=t;

    }

  }

 }

}

板块2

引例 :

# include <stdio.h>

int main()
{
int i=10;

i=f();

//当调用f的时候,会为j分配空间,调用完之后,j的空间就没有了,但是这种情况只针对局部变量

printf("i=%d\n", i);

return 0;
}

int f()
{
int j=20;

return j;
}

从上面的引例,我们给出一道例题如下:

以下程序中,能够通过调用函数fun,使main函数中的指针变量p指向一个合法的整型单元的是: C

A)main()

  {  int *p;

     fun(p);

     ...

   }

   int fun(int *p)

   {  int s;

      p=&s;

}
11这个就根本没有正确指向整型单元!!

B)main()

  {  int *p;  //p是int *类型

     fun(&p);  //&p是int **类型;把&p(p的地址)发送给下面的q,它们类型一样

     ...

   }

   int fun(int **q)

   {  int s;

      *q=&s;  //所以*q=*(&p)=**p,把s的地址发送给q指向的p

   }

//但是B是错误的因为执行完毕调用fun函数之后,再向下执行“...”里面的语句,fun函数里面的局部变量s的空间就  了

//那么“main函数中的指针变量p指向一个合法的整型单元”也就没有了

C)#include <stdio.h>

main()

  {  int *p;

     fun(&p);

     ...

   }

   int fun(int **q)   //把p的地址发送给q -> int **q=&p; -> int *q=p;

   {  *q=(int *)malloc(4);   //int *q=p;  -> p指向了4个字节

   }

//同时,函数fun执行完毕之后,这4个字节没有消失!!因为它还没有free

//C正确

10跨函数使用内存的详解及示例— —通过动态来实现

实例:

A aa = new A(); <=> A *pa = (A *)malloc(sizeof(A))

/*

   2020/7/30/10:00——跨函数使用内存 

*/ 

# include <stdio.h>
# include <malloc.h>
struct Student

{

 int sid;

 int age;

};

struct Student * CreateStudent(void);

void ShpwStudent(struct Student *);

int main(void)

{

 struct Student *ps;

 ps=CreateStudent();//把p的值赋给ps,使得ps指向分配的内存 

 ShowStudent(ps);

 return 0;

}

void ShowStudent (struct Student *pst)

{

 printf("%d %d\n", pst->sid, pst->age);

} 

struct Student * CreateStudent(void)

{

 struct Student *p=(struct Student *)malloc(sizeof(struct Student));

 p->sid=88;

 p->age=99;

 return p;

}

Arraylist和LinkList的区别?


板块3

# include <stdio.h>
# include <stdlib.h>   //malloc使用前提

int main()
{

  //静态 

  int a[5]={4, 10, 2, 8, 6}; 

  //动态 

  //在程序运行中,根据不同用户的需求,构造出不同的数组,而且可以释放它 

  int len;

printf("请输入i需要分配的数组长度,len:");

 scanf("%d", &len);

 int * pArr=(int *)malloc(sizeof(int)*len); //pArr等价于上面的a,可以把pArr当数组用啦 

 //malloc函数只能返回第一个字节的地址;

 //因为不论是int还是double类型,都会返回第一个字节的地址,

 //仅仅依据这个无法倒退得到它是什么类型,所以它是无意义地址-干地址

 //所以要强制转换(int *)来告诉编译系统,我们需要的地址到底是什么类型 

//  *pArr = 4;//类似于a[0]=4; 

//  pArr[1]=10;//类似于a[1]=10;

// printf("%d %d\n", *pArr, pArr[1]); 

  int i;

 for( i=0; i<len; ++i)

  scanf("%d", &pArr[i]);//输入 

  for(i=0; i<len; ++i)

  printf("%d\n", *(pArr + i));//输出 

  free(pArr);

  return 0;

  }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值