谁能帮我说下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语言谁能帮我写个for循环给二维数组赋值

C语言的指针传递,指针的指针的问题,谁能帮我分析分析这个问题?

谁能帮我用C语言写一个测试选择排序性能(函数的运行时间)的程序,不胜感激!

谁能帮我把一个hex文件反编译为c语言文件?

谁能帮我做下这道C语言编程题,明天就要交了,好心人帮帮忙,谢谢了~~~~求救呀·~~~

C语言:怎么将十进制数字转换为二进制字符串,谁能帮我写个函数