谁能帮我说下C语言中的堆栈
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谁能帮我说下C语言中的堆栈相关的知识,希望对你有一定的参考价值。
可以用C#编写一个类来实现堆栈功能吗?
个人认为楼上的不懂C语言堆栈到底是怎么回事,按楼上说法,只是大概讲了下栈,没有讲堆.要讲C语言的堆栈,要从计算机的数据内存分配讲起.
____________________
| Stack区(数组,指针,结构体,局部变量)
____________________
| Static变量(静态变量,全局变量)
____________________
| Heep区(堆区)
____________________
| 代码段
____________________
从上面示意图中可看出整个内存分配,堆分配是在内存中按块划分,也就是相对与函数malloc,realloc,calloc.这3个函数为内存分配函数.而且需要手动调用free函数释放资源,否则会造成大量的内存碎片.
如果楼主不相信可以自己写一个死循环,内部调用malloc函数,创建N个内存块,运行一段时间后,绝对会造成系统瘫痪,资源被耗尽.
栈区划分为计算机自身划分,即在函数或局部变量被调用时,系统自动为其分配栈,以后进先出为原则实现变量的保存,在函数调用完毕时,系统会自动释放栈内资源,所以,栈可以说是短命的(生存周期只在调用过程中).
这里只是粗略说了下堆和栈,另外再说下static-->静态区,全局变量或静态变量存放于静态区,只要代码中存在静态变量或全局变量,自动放于静态区,静态区存放的变量生存周期是整个程序结束时才释放.
代码段区,顾名思义存放的是程序代码(暂时先这么理解).
PS:本人原创,最近发现一些人盗用本人回答的问题.特此声明.嘿嘿.
____________________ _________
补充:
我对于C#不是很熟悉,而且我也是从事C开发的,对于面向对象语言应用不是很熟.在这只能给出C++的代码.代码有点长,不知道你能不能看的懂,才写的.
#include <iostream.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <assert.h>
/*
//基于数组的栈的实现
#define N 50
typedef struct Stack
int top;
int A[N];
*pStack;
//Pop出栈
int Pop(pStack pst)
int e;
if(pst->top == -1)
cout<<"Stack is empty!"<<endl;
return -1;
else
e = pst->A[pst->top];
pst->top--;
// cout<<"The element "<<e<<" is pop"<<endl;
return e;
//Push入栈
void Push(pStack pst)
int e;
if(pst->top == N-1)
cout<<"Stack is full!"<<endl;
else
cout<<"Input the push number:";
cin>>e;
pst->top++;
pst->A[pst->top] = e;
//清空栈
void empty(pStack pst)
pst->top = -1;
//判断栈是否为空
int IsEmpty(pStack pst)
if(pst->top == -1)
return 0;
// cout<<"The Stack is empty!"<<endl;
else
return 1;
// cout<<"The Stack is not empty!"<<endl;
//判断栈是否为满
int IsFull(pStack pst)
if(pst->top == N-1)
return 0;
else
return 1;
//初始化栈
void InitStack(pStack pst)
pst->top = -1;
void main()
Stack S;
InitStack(&S);
int n;
cout<<"How many times do you want to Push:";
cin>>n;
for(int i=0; i<n; i++)
Push(&S);
cout<<"How many times do you want to Pop:";
cin>>n;
for(i=0; i<n; i++)
cout<<"The element "<<Pop(&S)<<" is pop"<<endl;
cout<<"The Stack's stutor:"<<endl;
if(IsEmpty(&S) == 0)
cout<<"The Stack is empty!"<<endl;
else
cout<<"The Stack is not empty!"<<endl;
if(IsFull(&S) == 0)
cout<<"The Stack is full!"<<endl;
else
cout<<"The Stack is not full!"<<endl;
empty(&S);
cout<<"The Stack's stutor:"<<endl;
if(IsEmpty(&S) == 0)
cout<<"The Stack is empty!"<<endl;
else
cout<<"The Stack is not empty!"<<endl;
*/
typedef struct Stack
Stack *prior;
Stack *next;
int element;
*pStack;
//压栈
void Push(pStack *pst)
if((*pst) == NULL)
pStack S = (pStack)malloc(sizeof(Stack));
(*pst) = S;
(*pst)->next = NULL;
(*pst)->prior = NULL;
cout<<"Input the PUSH data:";
cin>>(*pst)->element;
else
pStack S = (pStack)malloc(sizeof(Stack));
(*pst)->next = S;
S->prior = (*pst);
S->next = NULL;
(*pst) = S;
cout<<"Input the PUSH data:";
cin>>(*pst)->element;
//判断是否为空
int IsEmpty(pStack pst)
if(pst == NULL)
cout<<"The Stack is empty!"<<endl;
return 1;
return 0;
//出栈
pStack Pop(pStack *pst)
if(IsEmpty((*pst)) == 1)
return (*pst);
pStack S = (*pst);
if((*pst)->prior == NULL)
cout<<"Out:"<<(*pst)->element<<endl;
(*pst) = NULL;
free(S);
return (*pst);
else
cout<<"Out:"<<(*pst)->element<<endl;
(*pst) = (*pst)->prior;
(*pst)->next = NULL;
free(S);
return (*pst);
//初始化栈
void InitStack(pStack pst)
pst = NULL;
void main()
pStack pS = NULL;
// InitStack(pS);
int n;
cout<<"How many times do you want to Push:";
cin>>n;
for(int i=0; i<n; i++)
Push(&pS);
pStack S;
S = Pop(&pS);
参考技术A 堆栈是一种执行“后进先出”算法的数据结构。
设想有一个直径不大、一端开口一端封闭的竹筒。有若干个写有编号的小球,小球的直径比竹筒的直径略小。现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来。所以“先进后出”就是这种结构的特点。
堆栈就是这样一种数据结构。它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中。有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫做堆栈指示器。开始放入数据的单元叫做“栈底”。数据一个一个地存入,这个过程叫做“压栈”。在压栈的过程中,每有一个数据压入堆栈,就放在和前一个单元相连的后面一个单元中,堆栈指示器中的地址自动加1。读取这些数据时,按照堆栈指示器中的地址读取数据,堆栈指示器中的地址数自动减 1。这个过程叫做“弹出pop”。如此就实现了后进先出的原则。
堆栈是计算机中最常用的一种数据结构,比如函数的调用在计算机中是用堆栈实现的。
堆栈可以用数组存储,也可以用以后会介绍的链表存储。
下面是一个堆栈的结构体定义,包括一个栈顶指针,一个数据项数组。栈顶指针最开始指向-1,然后存入数据时,栈顶指针加1,取出数据后,栈顶指针减1。
#define MAX_SIZE 100
typedef int DATA_TYPE;
struct stack
DATA_TYPE data[MAX_SIZE];
int top;
;
谁能帮我检查一下我的BMI计算器? (C#)
我刚刚开始编程一周前,我的第一个任务是编写BMI计算器。
推出时应该看起来像这样:
BMI Calculator
Your weight in kg: x
Your height in cm: x
Gender (m/f): x
-> You are underweight/normal/overweight
到目前为止,这是我的代码:
Console.WriteLine("BMI Calculator");
Console.WriteLine("===========");
Console.WriteLine();
Console.Write("Weight in kg: ");
int kg;
kg = Convert.ToInt32(Console.ReadLine());
Console.Write("Height in cm: ");
int m;
m = Convert.ToInt32(Console.ReadLine());
Console.Write("Gender (m/f):");
string Geschlecht = Console.ReadLine();
int BMI;
BMI = kg / (m / 100) * (m / 100);
if (BMI < 19 & Gender == "f")
{ Console.WriteLine("-> Underweight"); }
if (BMI >= 19 & BMI <= 24 & Gender == "f")
{ Console.WriteLine("-> Normal"); }
if (BMI > 24 & Geschlecht == "f")
{ Console.WriteLine("-> Overweight"); }
if (BMI < 20 & Gender == "m")
{ Console.WriteLine("-> Underweight"); }
if (BMI >= 20 & BMI <= 25 & Gender == "m")
{ Console.WriteLine("-> Normal"); }
if (BMI > 25 & Gendert == "m")
{ Console.WriteLine("-> Overweight"); }
Console.ReadLine();
我不确定我的代码有什么问题,但每当我输入60公斤,170厘米和男性时,我都会超重,即使我应该恢复正常。实际上超过10公斤的东西也是如此。
PS:我真的是编程的初学者,所以我为编程术语的命令道歉。
为了您的方便:
http://i.stack.imgur.com/admqr.png
提前致谢!
答案
当你这样做时:
BMI = kg / (m / 100) * (m / 100);
而m
是一个int
,你将做整数除法,在这种情况下170 / 100 = 1
。正如User1551892指出的那样,您需要更加具体地了解计算顺序。
尝试:
double BMI = kg / ( ( m / 100.0 ) * ( m / 100.0 ) );
这将迫使它做浮点除法,应该会得到更好的结果。
此外,您可以使用Math.Pow
避免m / 100.0
两次:
double BMI = kg / Math.Pow( m / 100.0, 2 );
另一答案
请检查此行:
BMI = kg / (m / 100) * (m / 100);
它应该是这样的:
BMI = kg / ((m / 100) * (m / 100)) ;
另一答案
仅供参考FYI新堆栈的交换门户网站:codereview.stackexchange.com
应该是更好的地方要求审查
另一答案
LOGIX.ASPX
using System;
using System.Configuration;
using System.Data.SqlClient;
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLogin_Click(object sender, EventArgs e)
{
bool blnLoginOK = false;
//Verbindung zur DB herstellen
SqlConnection conDBTodo = new SqlConnection(ConfigurationManager.ConnectionStrings["conStrLogin"].ConnectionString);
//SqlCommand vorbereiten, Verbindung zur Tabelle
SqlCommand comDemoSelect = new SqlCommand();
comDemoSelect.Connection = conDBTodo;
//comDemoSelect.CommandType = comm
comDemoSelect.CommandText = "SELECT ID FROM tabUser WHERE Email=@Email AND Passwort=@Passwort";
comDemoSelect.Parameters.AddWithValue("@Email", this.txtMail.Text);
comDemoSelect.Parameters.AddWithValue("@Passwort", this.txtPW.Text);
comDemoSelect.Connection.Open();
//Datareader um Daten anzuzeigen
SqlDataReader drTodo = comDemoSelect.ExecuteReader();
//Datenausgabe in Labelfeld mit Datareader
blnLoginOK = drTodo.HasRows; //Sind Datensätze vorhanden?
//Schliessen aller Verbindungen
drTodo.Dispose();
drTodo.Close();
comDemoSelect.Dispose();
comDemoSelect.Connection.Close();
conDBTodo.Dispose();
conDBTodo.Close();
if (blnLoginOK == true)
{
Session["LoggedIn"] = "true";
Response.Redirect("Secure.aspx");
}
else
{
Response.Redirect("Login.aspx");
}
}
protected void btnReg_Click(object sender, EventArgs e)
{
Response.Redirect("Registration.aspx");
}
protected void btnWeg_Click(object sender, EventArgs e)
{
//Verbindung zur DB herstellen
SqlConnection conDBTodoDelete = new SqlConnection(ConfigurationManager.ConnectionStrings["conStrLogin"].ConnectionString);
//SqlCommand vorbereiten, Verbindung zur Tabelle mit SQL - Befehl
SqlCommand comDemoDelete = new SqlCommand("DELETE FROM tabUser WHERE Email = @Email AND Passwort = @Passwort");
comDemoDelete.Connection = conDBTodoDelete;
comDemoDelete.Parameters.AddWithValue("@Email", this.txtMail.Text);
comDemoDelete.Parameters.AddWithValue("@Passwort", this.txtPW.Text);
comDemoDelete.Connection.Open();
comDemoDelete.ExecuteNonQuery();
comDemoDelete.Connection.Close();
comDemoDelete.Dispose();
conDBTodoDelete.Dispose();
conDBTodoDelete.Close();
txtMail.Text = "Sie haben nun Ihren Account gelöscht!";
return;
}
}
REGISTRATION.ASPX
using System;
using System.Configuration;
using System.Data.SqlClient;
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnRegistrierung_Click(object sender, EventArgs e)
{
//Verbindung zur DB herstellen
SqlConnection conDBTodo = new SqlConnection(ConfigurationManager.ConnectionStrings["conStrLogin"].ConnectionString);
//SqlCommand vorbereiten, Verbindung zur Tabelle mit SQL - Befehl
SqlCommand comDemoInsert = new SqlCommand("INSERT INTO tabUser(Benutzername, Email, Passwort) VALUES (@Benutzername, @Email, @Passwort)");
comDemoInsert.Connection = conDBTodo;
comDemoInsert.Parameters.AddWithValue("@Benutzername", this.txtBen.Text);
comDemoInsert.Parameters.AddWithValue("@Email", this.txtMail.Text);
comDemoInsert.Parameters.AddWithValue("@Passwort", this.txtPW.Text);
comDemoInsert.Connection.Open();
comDemoInsert.ExecuteNonQuery();
comDemoInsert.Connection.Close();
comDemoInsert.Dispose();
conDBTodo.Dispose();
conDBTodo.Close();
Response.Redirect("Login.aspx");
}
protected void btnBack_Click(object sender, EventArgs e)
{
Response.Redirect("Login.aspx");
}
}
另一答案
protected void btnGoo_Click(object sender, EventArgs e)
{
this.txtErgebnis.BackColor = System.Drawing.Color.White;
this.txtErgebnis.Text = "";
this.txtErgebnis.ForeColor = System.Drawing.Color.White;
//variablen Definieren
double dblGroesse = 0;
double dblGewicht = 0;
double dblErgebnis = 0;
if (Double.TryParse(txtGroesse.Text, out dblGroesse) == false) {
txtGroesse.Text = "Geben Sie ihre Grösse ein";
return;
}
if (Double.TryParse(txtGewicht.Text, out dblGewicht) == false)
{
txtGewicht.Text = "Geben Sie ihr Gewicht ein";
return;
}
dblErgebnis = dblGewicht / (dblGroesse * dblGroesse);
txtErgebnis.Text = Convert.ToString (dblErgebnis);
if (dblErgebnis <= 16)
{
this.txtErgebnis.BackColor = System.Drawing.Color.Coral;
this.txtErgebnis.ForeColor = System.Drawing.Color.LightGoldenrodYellow;
}
else if (dblErgebnis <= 25)
{
this.txtErgebnis.BackColor = System.Drawing.Color.DarkRed;
this.txtErgebnis.ForeColor = System.Drawing.Color.DarkSlateGray;
}
}
}
以上是关于谁能帮我说下C语言中的堆栈的主要内容,如果未能解决你的问题,请参考以下文章
C语言的指针传递,指针的指针的问题,谁能帮我分析分析这个问题?
谁能帮我用C语言写一个测试选择排序性能(函数的运行时间)的程序,不胜感激!