1. 如何用c语言数据结构的格式实现简单的算术表达式求值程序
用栈把中缀表达式(输入的式子)按优先级转为后缀表达式(逆波兰式,即运算符在前,操作数在后),再利用栈变计算边保存结果用于下一步计算,最后算出式子的答案
以下代码输入一个式子(以
=
作为输入结束标志),输出结果,负数如-3用0-3表示,支持高位运算
#include
<stdio.h>
#include
<stdlib.h>
#include
<math.h>
#include
<malloc.h>
#define
OK
1
#define
ERROR
-1
typedef
char
SElemType;
typedef
char
Status;
#define
STACK_INIT_SIZE
100000
#define
STACKINCREMENT
2
struct
SqStack
{
SElemType
*base;
SElemType
*top;
int
stacksize;
};
struct
SqStack1
{
int
*base;
int
*top;
int
stacksize;
};
SqStack
OPTR;
SqStack1
OPND;
char
Precede(char
c1,char
c2)
{
if(c1=='+'
||
c1=='-')
{
if(c2=='+'
||
c2=='-'
||
c2==')'
||
c2=='=')
return
'>';
else
return
'<';
}
else
if(c1=='*'
||
c1=='/')
{
if(c2=='(')
return
'<';
else
return
'>';
}
else
if(c1=='(')
{
if(c2==')')
return
'=';
else
return
'<';
}
else
if(c1==')')
return
'>';
else
if(c1=='=')
{
if(c2=='=')
return
'=';
else
return
'<';
}
else
return
'\0';
}
int
In(char
c)
{
if(c=='+'
||
c=='-'
||
c=='*'
||
c=='/'
||
c=='('
||
c==')'
||
c=='=')
return
1;
else
return
0;
}
int
Operrate(int
m,char
b,int
n)
{
switch(b)
{
case
'+':return
m+n;
case
'-':return
m-n;
case
'*':return
m*n;
case
'/':return
m/n;
}
return
0;
}
//操作数
int
InitStack1(SqStack1
&S)
{
S.base=(int
*)malloc(STACK_INIT_SIZE*sizeof(int));
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return
OK;
}
int
Push1(SqStack1
&S,int
e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(int
*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));
S.top=S.base+S.stacksize;
S.stacksize=S.stacksize+STACKINCREMENT;
}
*S.top++=e;
return
OK;
}
int
Pop1(SqStack1
&S,int
&e)
{
if(S.top==S.base)
return
ERROR;
e=*
--S.top;
return
OK;
}
int
GetTop1(SqStack1
S)
{
if(S.top==S.base)
return
ERROR;
return
*(S.top-1);
}
//算符
int
InitStack(SqStack
&S)
{
S.base=(SElemType
*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return
OK;
}
int
Push(SqStack
&S,SElemType
e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType
*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
S.top=S.base+S.stacksize;
S.stacksize=S.stacksize+STACKINCREMENT;
}
*S.top++=e;
return
OK;
}
int
Pop(SqStack
&S,SElemType
&e)
{
if(S.top==S.base)
return
ERROR;
e=*
--S.top;
return
OK;
}
Status
GetTop(SqStack
S)
{
if(S.top==S.base)
return
ERROR;
return
*(S.top-1);
}
int
Calculate()
{
char
c,theta,p;
int
a,b,i=0,ans,x;
InitStack(OPTR);
Push(OPTR,'=');
InitStack1(OPND);
c=getchar();
while(c!='='
||
GetTop(OPTR)!='=')
{
if(!In(c)
&&
c>='0'
&&
c<='9')
{
Push1(OPND,c-'0');
c=getchar();
while(c>='0'
&&
c<='9')
{
Pop1(OPND,x);
Push1(OPND,x*10+c-'0');
c=getchar();
}
}
else
if(In(c))
{
switch(Precede(GetTop(OPTR),c))
{
case
'<':
Push(OPTR,c);
c=getchar();
break;
case
'=':
Pop(OPTR,p);
c=getchar();
break;
case
'>':
Pop(OPTR,theta);
Pop1(OPND,b);
Pop1(OPND,a);
ans=Operrate(a,theta,b);
Push1(OPND,ans);
break;
}
}
else
{
c=getchar();
}
}
return
GetTop1(OPND);
}
int
main()
{
int
ans;
ans=Calculate();
printf("%d\n",ans);
return
0;
}
2. C语言结构体所占用的字节数如何计算
结构体的数据类型的有点多我们就不啰嗦了,直接来看相同数据结构体的几种书写的格式吧。
格式一:
01.structtagPhone
02.{
03.charA;
04.intB;
05.shortC;
06.}Phone;
格式二:
01.structtagPhone
02.{
03.charA;
04.shortC;
05.intB;
06.}Phone2;
格式三:
01.structtagPhone3
02.{
03.charA;
04.charB[2];
05.charC[4];
06.}Phone3;
我们都知道,char类型占用1个字节,int型占用4个字节,short类型占用2个字节,long占用8个,double占用16个;
那么我们可能会犯一个错误就是直接1+4+2=7,该结构体占用7个字节。这是错的。
以下我们简单分析下:
计算结构体大小时需要考虑其内存布局,结构体在内存中存放是按单元存放的,每个单元多大取决于结构体中最大基本类型的大小。
对格式一:
上面结构计算大小,sizeof(Phone3) = 1 + 2 + 4 = 7, 其大小为结构体中个字段大小之和,这也是最节省空间的一种写法。
总结:
第一种写法,空间浪费严重,sizeof 计算大小与预期不一致,但是保持了每个字段的数据类型。这也是最常见的漫不经心的写法,一般人很容易这样写;
第三种写法,最节省空间的写法,也是使用 sizeof 求大小与预期一样的写法,但是全部使用字节类型,丢失了字段本生的数据类型,不方便使用;
第二种写法,介于第一种和第三种写法之间,其空间上比较紧凑,同时又保持了结构体中字段的数据类型。
只要了解是这些写法的差异性,可以视情况选用。
3. C语言中结构体字节的计算方式
在说计算方式之前先讲讲几个概念一个是 偏移量 还有一个是 内存对齐 。先说偏移量,网络对于它的定义是这样:把存储单元的实际地址与其所在段的段地址之间的距离称为段内偏移,也称为“有效地址或偏移量”。在结构体里面大概是指结构体变量中成员的地址和结构体变量地址的差。然后再说一下内存对齐这个概念:内存中存放基本类型数据时,计算机的系统会对其位置有限制,系统会要求这些数据的首地址的值是某个数的倍数,而这个数被称为该数据类型的对齐模数。虽然ANSI C标准中没有强制规定相邻声明的变量内存中要相邻,但是编译器会自动帮你处理这个问题,也就是相邻变量之间可能会填充一些字节。因此在这个问题上又有了编译器的区别。
那我们先来讲讲结构体变量在微软的编译器的对齐吧
1.结构成员的首地址要是其最宽的基本类型成员的整数倍。编译器在给结构体分配内存的时候先找到最宽的基本成员,然后再在内存中寻找地址,并将这个最宽的基本数据类型的大小作为对齐模数
2.结构体每一个成员相对于首地址的偏移量是成员大小的整数倍,如果没有达到这个要求,编译器会自动填加字节。编译器在为结构体成员开辟内存的时候会先检查开辟内存的首地址与结构体变量的首地址之间的偏移量,如果是成员体的整数倍那么就存放这个变量,不然的话就在这个成员和上一个成员之间填充字节,以达到整数倍的目的
3.结构体所占的总内存大小要是最大成员体大小的整数倍,如果不是,那么编译器会在末尾补充字节。结构体的最后一个成员,不仅要满足前两条原则,最后一条准则也要满足。
接下来来看看几个例子。
这个结构体在VS 2017下的sizeof的运算结果是12。那么根据上面的对其规则我们来对其进行计算。
首先是char a。char大小是1,相对于首地址的偏移量是0,然后是int i。int i的大小是4,相对于首地址的偏移量是1,但是1不是4的整数倍,所以编译器会自动在char a和int i之间填充字节字节。所以in i的偏移量是4。而之后的float b大小4偏移量就是int i的偏移量加上int i的大小故float b的偏移量大小就是8,而8正好是4的倍数那么就不会有字节填充。而结构体的大小也就自然是最后8+4=12了
从这里也可以看出结构体大小等于最后一个成员体的大小加上它的偏移量。
那么我们再来看一个例子
那么我们再利用之前的算法来对其进行运算,int i的大小是4偏移量是0,int c 的大小是4偏移量是4,double b的大小是8,偏移量是8。char a的大小是1 ,偏移量是16。那么这个结构体的变量的大小就是16+1=17吗?答案肯定不是这样的。在VS的sizeof的运算下这个的结果是24,为什是24呢,那么这之前说的最后一条原则就要用上了。结构体的大小确实是等于最后一个成员的偏移量加上最后一个成员的大小,但是如果这个结构不满足是结构体中最大成员大小的整数倍这个条件那么,编译器会自动在最后填充字节使其满足,也就是说,虽然我们计算出的结果是17但是17并不是8的倍数,所以编译器自动在最后填充字节使其成为8的倍数,即自动扩充成24.、
那我们再来说一下GCC编译器下的模式。GCC编译器在Windows环境下用的会比较少,主要在Linux平台下使用GCC编译器就不遵守微软的编译器下的一些准则了,比如之前 说过的对齐模数。微软的编译器下的对齐模数是结构体成员中最大的大小而在GCC编译器下对齐模数最大只能是4。这就意味着对齐模数只能是1,2,4中的一个。因此之前讲过的在微软编译器下的的一些原则会有些不同。之前讲过的成员的首地址的偏移量要是成员大小的整数倍在这里就有点区别了。在GCC中如果成员大小小于等数4那么继续按照之前的标准就好了,但如果大于4,则结构体每个成员相对于结构体首地址的偏移量只能按照是4的整数倍来进行判断是否添加填充。来看一个简单的例子。
在这个例子中,如果是按照微软的编译器的话计算的结构应该是16,但是在GCC编译器下是12。道理就是之前讲的。
虽然理论上如此但是我自己在试的时候发现上面的运算结果是16,没错是16而不是12!为什么呢?难道是这个理论错了么,当然不是。我们可以尝试在GCC下计算一下sizeof(int *)(是int *而不是int)。你会发现结果是8(如果是sizeof(int)那么结果结果就是4),输出结果是8那就解决了我们的疑惑。 64位系统的对其长度默认是8而32位的才是4 。这就合理解释了为什么计算结果是16而不是12。
对齐模数的选择只能是基于基本数据类型,所以对于结构体嵌套结构体就不能这么,至于其的计算方式之后再补充
4. C语言,结构体问题所占内在字节数,怎么算的
在c语言中如何计算结构体长度和共用体长度?
结构体的长度等于体内各个成员变量长度之后。如此题长度为字符串数组的长度加上两个int型变量的长度,再加上double长度,最后结果为10+2+2+8=22。解析:char 每个字符占一个字节(因为是一个十长度的字符数组)所以是10字节,int占两个字节,double占8个字节。所以最后是10+2*2+8=22。
共用体的长度是体内成员中最长的长度。如果一个共用体内最长长度为12字节,则共用体的长度就是12。
希望能够帮到你。如果还有什么问题在问?
5. c语言数据结构问题求解
A[0][0]和A[2][2]相差了(2*n+2)个元素,与A[3][3]相笑雀差了碰空早(3*n+3)个元亏嫌素,所以,676-644=32,32/2*3=48,644+48=692,选择c项。
满意请采纳呦~
6. c语言顺序结构程序 立体几何计算题怎么编写啊啊求解
运行结果槐模念如下:有不清楚的铅困地方,请留言。没问题,请采纳下。谢谢
#include<stdio.h>
#include<stdlib.h>
#definePI3.14//宏定义pi等于3.14
intmain()
{
floatr,h;
floatc1;//保存计算圆的周长
floatSb;//保存圆的表面积
floatVb;//保存圆柱的体积
printf("请输入圆的半径r=:
");
scanf("%f",&r);//输入圆的半径
printf("请输入圆柱的高度h=:
");
scanf("%f",&h);//输入圆柱的高
//计算半径为r的周长c1
c1=2*PI*r;
//S=4πR^2:S球面积,R球半径,π:圆周率
Sb=4*PI*r*r;
//计算圆柱的体积:底面积乘以高
Vb=PI*r*r*h;
printf("半径为r的圆的周长是:%.2f
",c1);
printf("
半径为r的圆的表面积是:%.2f
",Sb);
码橘printf("
半径为r的圆柱的体积是:%.2f
",Vb);
return0;
}