当前位置: 首页 > news >正文

二维数组 结构体01 day15,16

十五:二维数组

一:int *p [4]

(p+i) //i可以取0 1 2 此时的p+i相当于获得了 int[4] a[3]这个一维数组的一整个元素所在空间的地址

*(p+i) //*(p+i)—此时就相当于 是一个int[4]类型的数据

对具体元素的访问 //*(*(p+i)+ j) //等价于p[i][j]

在指向行的指针前面加一个*,就转换为指向列的指针。例如,a和a+l是指向行的指针,在它们 前面加一个*就是a和 (a+l), 它们就成为指向列的指针,分别指向 a数组 0行 0 列 的元素和 1 行0列的元素。反之,在指向列的指针前面加&,就成为指向行的指针。

例如,a和a+l是指向行的指针,在它们 前面加一个*就是a和 (a+l), 它们就成为指向列的指针,分别指向 a数组 0行 0 列 的元素和 1 行0列的元素。反之,在指向列的指针前面加&,就成为指向行的指针。

	int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};int (*p)[4] = a;int j = 0;int i = 0;for(i=0;i<3;i++){for(j=0;j<4;j++){printf("%d ",*(*(p+i)+j));}}putchar('\n');
void printfArray(int (*a)[4],int row)//函数形式
{int j = 0;int i = 0;for(i=0;i<row;i++){for(j=0;j<4;j++){printf("%d ",*(*(a+i)+j));//先访问一维,在一维的基础 j 访问二维}}putchar('\n');}
int max(int (*a)[4],int row)
{int j = 0;int i = 0;int max = *(*(a+0)+0);for(i=0;i<row;i++){for(j=0;j<4;j++){if(*(*(a+i)+j) > max){max =*(*(a+i)+j);  }}}return max;}

二:字符型二维数组

#include<stdio.h>void PrintChar(char (*s)[10],int row)
{for(int i=0;i<3;i++){printf("%s\n",*(s+i));}}int main(int argc, const char *argv[])
{char s[3][10] = {"hello","wolrd","china"};char (*p)[10] = s;PrintChar(s,3);return 0;
}
void ReversePrintfArray(char (*begin)[10],char (*end)[10])
{while(begin<end){char t[10];strcpy(t,*begin);strcpy(*begin,*end);strcpy(*end,t);++begin;--end;}
}void PrintChar(char (*s)[10],int row)
{for(int i=0;i<3;i++){printf("%s\n",*(s+i));}}
int main(int argc, const char *argv[])
{char s[3][10] = {"hello","world","china"};PrintChar(s,3);ReversePrintfArray(s,s+2);PrintChar(s,3);return 0;
}
void chosen(char (*s)[10],int row)//选择
{for(int i=0;i<row-1;++i){for(int j=i+1;j<row;++j){if(strcmp(*(s+i),*(s+j))>0){char t[10];strcpy(t,*(s+i));strcpy(*(s+i),*(s+j));strcpy(*(s+j),t);}}}
}

三:二重指针

#include<stdio.h>
#include<string.h>char * findMax(char* *p,int len)
{char* max = *p;for(int i=1;i<len;i++){if(strcmp(max , *(p+i))< 0){max = *(p+i);}}return max;
}void printStr(char* *p,int len)
{int i = 0;for(i=0;i<len;++i){printf("%s\n",*(p+i));}
}int main(int argc, const char *argv[])
{char* p[3] = {"hello","world","china"};printStr(p,3);printf("maxChar = %s\n",findMax(p,3));return 0;
}
void chosen(char* *s,int row)//选择
{for(int i=0;i<row-1;++i){for(int j=i+1;j<row;++j){if(strcmp(*(s+i),*(s+j))>0){char * t = *(s+i);*(s+i) = *(s+j);*(s+j) = t;}}}
}
void reverseChar(char* *begin,char* *end)
{while(begin<end){char *t = *begin;*begin = *end;*end = t;++begin;--end;}
}void printStr(char* *p,int len)
{int i = 0;for(i=0;i<len;++i){printf("%s\n",*(p+i));}
}int main(int argc, const char *argv[])
{char* p[3] = {"hello","world","china"};printStr(p,3);chosen(p,3);printStr(p,3);return 0;
}
char * binaryfindWord(char (*s)[10],int row,const char *str)
{char (*begin)[10] = s;char (*end)[10] = s + row - 1;char (*mid)[10] = NULL;char *ret = NULL;while(begin <=end){mid = begin + (end-begin)/2;if(strcmp(*mid,str)>0){end = mid - 1; }else if(strcmp(*mid,str)<0){begin = mid + 1;}else{ret = *mid;break;}}return ret;
}
char * binaryfindWord(char* *s,int len,char *str)
{char* *begin = s;char* *end = s + len - 1;char* *mid = NULL;char *ret = NULL;while(begin <=end){mid = begin + (end-begin)/2;if(strcmp(*mid,str)>0){end = mid - 1; }else if(strcmp(*mid,str)<0){begin = mid + 1;}else{ret = *mid;break;}}return ret;
}

四:指针指向函数

int add (int a,int b) //掉函数名,剩下就是函数类型

int (int a,int b) //代表一类函数 //返回值类型为int同时带有两个int型的形参 这么一类函数

基类型 * 变量名

int (int a,int b) * p //理解角度)就是一个指向 int (int a,int b)这种函数的一个指针变量

int (*p) (int ,int ) * //正确C语言写法

1.函数指针变量可以用来调用函数 //函数入口地址(实参)

2.**p, *不起作用

int add(int a,int b)
{return a + b;
}int main(int argc, const char *argv[])
{int (*p)(int ,int ) = add;printf("add = %p\n",add);int ret = p(1,2);printf("ret = %d\n",ret);return 0;
}
int func1(int n)
{return n;
}
int func2(int n)
{return n*n;
}int func3(int n)
{return n*n*n;
}void choiceSortP(int *a,int len,int (*pFunc)(int ))
{int i=0;int j=0;for(i=0;i<len-1;++i){for(j=i+1;j<len;++j){if(pFunc(a[i]) > pFunc(a[j])){int t = a[i];a[i] = a[j];a[j] = t;}}}
}int a[10] = {3,2,1,5,8,9,6,7,4,10};printArray(a,10);choiceSortP(a,10,func3);printArray(a,10);
int func1(int a,int b)
{return a+b;
}
int func2(int a,int b)
{return a-b;
}
int func3(int a,int b)
{return a*b;
}
int func4(int a,int b)
{return a/b;
}void processDate(int a,int b,int (*pfunc)(int ,int))
{printf("result  = %d\n",pfunc(a,b));//这里就当正常函数用就行,
}int main(int argc, const char *argv[])
{int a = 1;int b = 2;processDate(a,b,func1);processDate(a,b,func2);processDate(a,b,func3);processDate(a,b,func4);int (*p[4])(int,int) = {func1,func2,func3,func4};//main的另一种写法for(int i=0;i<4;i++){processDate(a,b,p[i]);}return 0;
}

回调函数

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

int compare(const void *a,const void *b)
{const int *p = a;const int *q = b;return *p - *q;
}int main(int argc, const char *argv[])
{int a[10] = {3,1,5,7,9,4,8,0,10,6};int len = sizeof(a)/sizeof(a[0]);qsort(a,len,sizeof(int),compare);for(int i=0;i<len;i++){printf("%d ",a[i]);}putchar('\n');return 0;
}
int compare(const void *s1,const void *s2)
{const char *p = s1;const char *q = s2;return strcmp(p,q);
}int main(int argc, const char *argv[])
{char s[5][10] = {"hello","world","china","english","america"};qsort(s,5,sizeof(char[10]),compare);for(int i=0;i<5;i++){puts(s[i]);}return 0;
}

五:malloc和free

void *malloc(size_t size);

​ 功能:申请内存 //堆区

参数:size //表示申请的空间大小单位字节 返回值:void*成功:返回申请到的内存空间的首地址

​ 失败:NULL

堆区空间的特点:1.空间大2.手动申请,手动释放

void free(void *ptr); //释放

功能:将堆区空间释放 //将之前在用的空间交还给操作系统,告诉操作系统,说这块空间不用了,可以回收

​ 参数:ptr //要求:代表堆区上的一块空间,free用之前前一定有malloc已经申请使用过的 堆区空间

void* //空类型指针, void *p //指针变量-可以接受任意类型

指针函数,意味着返回值是个地址,这个地址,不能是局部变量的地址

	int *p = malloc(sizeof(int));printf("1 p = %p\n",p);*p = 0x12345678;printf("%#x\n",*p);free(p);//此时p悬空指针p =NULL;printf("2 p = %p\n",p);printf("*p = %d\n",*p);
----------------------------------
1 p = 0x560c533a5260
0x12345678
2 p = (nil)
Segmentation fault (core dumped)
	int *p = malloc(10*sizeof(int));//将数组放进堆区for(int i=0;i<10;i++){*(p+i) = i + 1;}int sum = 0;for (int i = 0; i < 10; i++){sum +=*(p+i);}printf("sum = %d\n", sum);free(p);p =NULL;
void getmemory(char *p,int num)
{p =(char *)malloc(num);//仅修改局部变量 p
}int main()
{char *str = NULL;getmemory(str,100);//最终开辟的是全是NULL的空间,函数参数是 局部变量的拷贝,修改 p 不会影响 strstrcpy(str,"hello");//NULL是零号地址空间,无法访问,段错误puts(str);return 0;
}
void *getmemory(char **p,int num)
{*p =(char *)malloc(num);
}int main()
{char *str = NULL;getmemory(&str,100);//要想修改指针的指向,必须传递指针的地址(二级指针)://类似 swap(int *a, int *b) 需要传递 &a 和 &b 才能交换值。strcpy(str,"hello");puts(str);return 0;
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

六:多级指针

	int a = 10;int *p = &a;int **q = &p;int ***r = &q;printf("a = %d\n",a);printf("*p = %d\n",*p);printf("**q = %d\n",**q);printf("***r = %d\n",***r);

七:main函数

@argc 表示 — 命令行参数的个数
@argv 表示 — 存放着命令行字符串的指针数组

int main(int argc, const char *argv[])
{printf("argc = %d\n",argc);int i=0;for(i=0;i<argc;++i){printf("argv[%d] = =%s\n",i,argv[i]);}return 0;
}

十六:结构体

一:语法

struct 结构体名
{//各个成员变量//变量形式//结构体类型的定义
};
eg:
struct studnet
{char name[20];int socre;int sno;int sex;
}//此时我们自定义了一种数据类型---叫学生类型,类型名struct student
#include<stdio.h>struct studnet
{char name[20];int socre;int sno;int sex;
};int main()
{struct studnet s = {"tom",90,110,1};printf("name = %s\n",s.name);return 0;
}

scanf

	struct studnet s;scanf("%s",s.name);scanf("%d",&s.socre);scanf("%d",&s.sno);scanf("%d",&s.sex);
void printStuinfo(struct studnet *s)
{printf("name = %s\n",s->name);printf("socre = %d\n",s->socre);printf("sno = %d\n",s->sno);printf("sex = %d\n",s->sex);}struct studnet s;printStuinfo(&s);

相同类型的结构体变量之间可以相互赋值

     struct studnet t = s[2];	

结构体类型的形参,一般设计为指针类型,原因://指针类型传参时大小固定,

​ //如果是结构体类型变量,变量的大小取决于结构体类型的大小

二:通过指针

-> //指向结构体成员运算符

结构体类型的指针-> 结构体的成员变量

	struct studnet s;scanf("%s",s.name);scanf("%d",&s.socre);scanf("%d",&s.sno);scanf("%d",&s.sex);struct studnet *p = &s;printf("name = %s\n",p->name);printf("socre = %d\n",p->socre);printf("sno = %d\n",p->sno);printf("sex = %d\n",p->sex);

相关文章:

  • 【大模型:知识库管理】--MinerU本地部署
  • SpringBoot Starter设计:依赖管理的革命
  • 什么是数据清洗?数据清洗有哪些步骤?
  • 选择与方法专栏(9) 职场内篇: 是否要跳出舒适圈?如何处理犯错?
  • ffmpeg python rgba图片合成 4444格式mov视频,保留透明通道
  • 有趣的git
  • 【git】错误
  • 《深度学习基础与概念》task2/3
  • 使用 Java + WebSocket 实现简单实时双人协同 pk 答题
  • 设计模式精讲 Day 4:建造者模式(Builder Pattern)
  • Datawhale YOLO Master 第1次笔记
  • 提示词工程中常见协议框架应用实例
  • 开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用
  • 基于若依框架编写的选人组件(vue3 + ts 版本)
  • PostgreSQL窗口函数测试
  • Docker 安装 Oracle 11G
  • Datawhale-爬虫
  • 论文笔记:Trajectory generation: a survey on methods and techniques
  • 【数据结构】图论实战:DAG空间压缩术——42%存储优化实战解析
  • Java线程池全面解析:原理、实现与最佳实践
  • 长春企业网站建设价格/网站建设策划
  • 简单网站建设软件有哪些/接推广怎么收费
  • 网站制作推广/广告图片
  • 网站建设入什么科目/广东省人大常委会
  • 网站主页设计要点/seo网络推广有哪些
  • 用旧电脑做网站/建立网站用什么软件