c++数组初始化和释放问题

char str[1024];
memset(str, '\0', 1024 * sizeof(char));

代码如上,我想问一下:
1.这是静态分配内存还是动态分配内存,为什么?
2.这样初始化还需要delete[]释放吗?为什么?

4个回答

char str[1024];
定义在堆栈上
memset(str, '\0', 1024 * sizeof(char));
这个不是初始化,只是清零。和你写
for (int i = 0; i < 1024; i++) str[i] = '\0';是一回事

有new malloc才是动态分配内存,用了new才需要delete

caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复william624: 不等价
大约 2 年之前 回复
william624
william624 char str[1024]和char* str = new char[1024];不等价吗?
大约 2 年之前 回复

这个是在栈上分配的,超出作用域范围系统给自动释放了,可能数据没有被删除或清空,但是不在有效,不可能访问;
只有是你主动new的才需要delete

char str[1024]已经确定大小是静态分配,里面没有内容而使用memset,几乎是多余的

普通局部变量定义, 定义在栈上, 不需要delete, 系统自动回收.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
c++数组初始化和释放问题
char str[1024]; memset(str, '\0', 1024 * sizeof(char)); 代码如上,我想问一下: 1.这是静态分配内存还是动态分配内存,为什么? 2.这样初始化还需要delete[]释放吗?为什么?
malloc动态创建一维、二维数组,内存释放的问题
``` //////////////c用malloc和free////////////////////////////// #include "stdio.h" #include <iostream> using namespace std; //***********使用malloc创建一维数组,初始化、打印和释放*********** #define MALLOC_1D(p1,len,TYPE) p1 = (TYPE *)malloc(len * sizeof(TYPE)); #define FREE_1D(p1) free(p1); template<typename TYPE> void MALLOC_1D_INIT(TYPE *p1, int len, TYPE value = 0) { for (int i = 0; i<len; i++) p1[i] = value; } template<typename TYPE> void PRINT_1D(TYPE *p1, int len) { for (int i = 0; i < len; i++) { cout << p1[i] << ","; } cout << endl; } //***********使用malloc创建二维数组,初始化、打印和释放*********** #define MALLOC_2D(p2,row,col,TYPE)\ p2 = (TYPE**)malloc(sizeof(TYPE*) *row);\ for (int i = 0; i < row; i++)\ p2[i] = (TYPE*)malloc(sizeof(TYPE) * col); #define FREE_2D(p2,row,col)\ for (int i = 0; i<row; i++)\ free(p2[i]);\ free(p2); template<typename TYPE> void MALLOC_2D_INIT(TYPE **p2, int row, int col, TYPE value=0) { for (int i = 0; i<row; i++) for (int j = 0; j<col; j++) { p2[i][j] = value; } } template<typename TYPE> void PRINT_2D(TYPE **p2, int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j<col; j++) { cout << p2[i][j] << ","; } cout << endl; } cout << endl; } void main() { int row = 3; int col = 5; int cha = 4; //一维数组 int *p1; MALLOC_1D(p1, row, int);//开辟数组空间 MALLOC_1D_INIT(p1, row);//数组初试化 PRINT_1D(p1, row);//打印 FREE_1D(p1);//释放空间 cout << " p1[0]="<<p1[0] << endl;//【1】明明free释放了,为什么还可以访问内存? //二维数组 int **p2; MALLOC_2D(p2, row, col, int);//开辟数组空间 MALLOC_2D_INIT(p2, row, col);//数组初试化 PRINT_2D(p2, row, col);//打印 FREE_2D(p2, row, col);//释放空间 //cout << " p2[0][0]=" << p2[0][0] << endl;//【2】free释放了,不能访问了,去掉注释出错! system("pause"); } ``` 我的问题是: 【1】malloc创建的一维数组,明明free释放了,为什么还可以访问内存?是我没有成功释放内存麽?而我malloc创建的二维数组,free释放了后不能访问了 【2】如何检测自己malloc动态开辟的空间,被成功free了?
c++定义了一个动态数组但是报错???
总是提示访问路径出现冲突 研究了半天才知道是 数组的问题 请看到的大神 帮帮忙 谢谢 (vs平台上的) ![图片说明](https://img-ask.csdn.net/upload/201903/11/1552295783_772317.png) 代码在下面 这是头文件部分 ``` #include<iostream> using namespace std; class Array { private://私有数据成员: int *a;// 指向根据len动态申请的数组空间 int len;// 有效数组元素的个数 public://公有成员函数 : Array(int b[], int length);// 构造函数, 使用数组b初始化a所指的动态数组, length初始化len Array(const Array &arr);// 拷贝构造函数,使用对象arr初始化新对象 void sort();// 按题意对动态数组中的元素进行排序 void print();// 输出a所指向的数组 ~Array();// 析构函数, 释放动态数组空间 }; ``` 这是成员函数部分 ``` #include"array.h" using namespace std; Array::Array(int b[], int length)// 构造函数, 使用数组b初始化a所指的动态数组, length初始化len { int i; int *a = new int[length]; len = length; for (i = 0; i<len; i++) { a[i]= b[i]; } } Array::Array(const Array &arr)// 拷贝构造函数,使用对象arr初始化新对象 { int i; len = arr.len; int *a=new int[len]; for (i = 0; i < len; i++) { a[i] = arr.a[i]; } } void Array::sort()// 按题意对动态数组中的元素进行排序 { int i,j; int temp; for(i=0;i<len;i++) { for(j=i+1;j<len;j++) { if(a[i]<a[j]) { temp = a[i]; a[i] = a[j]; a[j] = temp; } } } } void Array::print()// 输出a所指向的数组 { int i; for(i=0;i<len;i++) { cout<<a[i]<<endl; } } Array::~Array()// 析构函数, 释放动态数组空间 { delete []a; } ``` 这是主函数 ``` #include"array.h" using namespace std; int main() { int num; int i; int a[50]; cout<<"输入数组的元素个数"<<endl; cin>>num; for(i=0;i<num;i++) { cin>>a[i]; } Array text(a,num); text.sort(); text.print (); system("pause"); return 0; } ```
java 代理对象 在加入list以后变回了非代理对象,是正常现象么?怎么处理。
本人小白,在学习数据库连接池实现时,为了确保调用者在获取了Connection后,不要直接close。使用动态代理方式创建代理对象,重新处理close函数。在执行中发现,用户在释放了代理对象以后,连接在add进list以后,变回了非代理的ConnectionImpl对象,导致再次取出时,代理作用丢失,请各位帮忙分析一下是怎么回事? ``` import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.util.LinkedList; public class DBPool { private int maxSize;//最大连接数 private int initSize;//初始化连接数 private int cur = 0;//已经使用的连接数 private LinkedList<Connection> pool = new LinkedList<Connection>(); //初始化连接池 public DBPool(int initSize, int maxSize) { this.maxSize = maxSize; this.initSize = initSize; initPool(initSize); } @Override public String toString() { return "DBPool [pool=" + pool + "]"; } //得到正在使用的连接个数 public int getCur() { return cur; } //连接池中连接个数 public int getPoolSize() { return pool.size(); } //初始化连接池方法 public void initPool(int initSize) { for (int i = 0; i < initSize; i++) { pool.add(createConnection()); } } //提供给调用者一个连接 public Connection getPoolConnection() { if (pool.size() > 0) { cur++; return pool.removeFirst(); } else if (cur >= maxSize) { System.out.println("连接已达到最大值"); return null; } else { cur++; return createConnection(); } } public Connection createConnection() { //使用工具类获取数据库连接 Connection con = MysqlUtils.getConnection(); //创建代理对象,代理con的close方法,如果连接池不满,就放入连接池,如果连接池满,则调用原close方法。 Connection proxy = (Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; //判断是否close方法 if ("close".equals(method.getName())) { // 如果连接池里面连接数<initSize,则直接加入pool if (pool.size() < initSize) { cur--; pool.addLast(con); } else {// 如果连接池>initSize,则直接关闭。 cur--; result = method.invoke(con, args); } //如果不是close方法,则直接调用原函数 } else { result = method.invoke(con, args); } return result; } }); return proxy; } } ``` 测试方法如下: @Test public void testPool() throws SQLException { //初始化连接池,池大小1,最大连接数2 DBPool pool=new DBPool(1, 2); //获取2个连接 Connection[] conn=new Connection[2]; for(int i=0;i<conn.length;i++) { conn[i]=pool.getPoolConnection(); } //释放两个连接,按照代理处理结果,应该是一个放回连接池,一个关闭。 for(int i=0;i<conn.length;i++) { if(conn[i]!=null) { conn[i].close(); conn[i]=null; } } //再次获取2个连接 for(int i=0;i<conn.length;i++) { conn[i]=pool.getPoolConnection(); } //再次释放2个连接 for(int i=0;i<conn.length;i++) { if(conn[i]!=null) { conn[i].close(); conn[i]=null; } } //预期结果应该是当前使用连接cur=0,池中连接数为1. System.out.println("当前使用的连接数:"+pool.getCur()+",当前连接池中连接数:"+pool.getPoolSize()); } 执行后结果如下: 当前使用的连接数:1,当前连接池中连接数:1 ``` 当前结果与预期结果不一致。 经过调试发现: 1、初始化完毕时,链表内容为: pool LinkedList<E> (id=299) [0] $Proxy4 (id=313) 2、第一次获取getPoolConnection(),conn数组内容为: conn Connection[2] (id=322) [0] $Proxy4 (id=307) [1] $Proxy4 (id=331) 3、第一次放回池中,pool链表内容为和conn数组分别为: pool LinkedList<E> (id=293) [0] ConnectionImpl (id=316) conn Connection[2] (id=322) [0] null [1] null 4、 第二次获取getPoolConnection(),conn数组内容为: conn Connection[2] (id=322) [0] ConnectionImpl (id=316) [1] $Proxy4 (id=491) 同时,在调试时也确实在第二次close两个连接时,conn[0].close没有执行代理程序。 不好意思,没有C币,请大家多包涵。
C++问题 矩阵运算的问题
#ifndef MATRIX_H #define MATRIX_H #include<iostream> using namespace std; class Matrix; Matrix operator+ (const Matrix &a, const Matrix &b); Matrix operator- (const Matrix &a, const Matrix &b); Matrix operator* (const Matrix &a, const Matrix &b); class Matrix { friend Matrix operator+ (const Matrix &a, const Matrix &b); friend Matrix operator- (const Matrix &a, const Matrix &b); friend Matrix operator* (const Matrix &a, const Matrix &b); public: Matrix(int l, int c); Matrix(const Matrix &m); ~Matrix(); void setLine(int l); void setElems(); void setCol(int c); int getLine() const; int getCol() const; void print() const; Matrix operator=(const Matrix &m); Matrix operator~() const; private: int line; int col; int *elems; }; #endif **函数实现:** #include"Matrix.h" Matrix operator+ (const Matrix &a, const Matrix &b) { if(a.col != b.line) { cerr<<"第一个矩阵的列数和第二个矩阵的行数不相等!"<<endl; exit(EXIT_FAILURE); } int line = a.line; int col = b.col; Matrix temp(line, col); for(int i = 0; i < line * col; i++) temp.elems[i] = 0; for(int j = 0; j < line * col; j++) temp.elems[j] = a.elems[j] + b.elems[j]; return temp; } Matrix operator- (const Matrix &a, const Matrix &b) { if(a.col != b.line) { cerr<<"第一个矩阵的列数和第二个矩阵的行数不相等!"<<endl; exit(EXIT_FAILURE); } int line = a.line; int col = b.col; Matrix temp(line, col); for(int i = 0; i < line * col; i++) temp.elems[i] = 0; for( int j = 0; j < line * col; j++) temp.elems[j] = a.elems[j] - b.elems[j]; return temp; } Matrix operator* (const Matrix &a, const Matrix &b) { if(a.col != b.line) { cerr<<"第一个矩阵的列数和第二个矩阵的行数不相等!"<<endl; exit(EXIT_FAILURE); } int line = a.line; int col = b.col; int s , sum = 0; Matrix temp(line, col); for(int m = 0; m < line * col; m++) temp.elems[m] = 0; for(int i = 0; i < line; i++) { for(int k = 0; k < col; k++) { for(int j = 0; j< b.line; j++) { s = a.elems[i + j + line * i] * b.elems[k + line * j]; sum = sum + s; } temp.elems[line * i + k] = sum; } } return temp; } Matrix::Matrix(int l, int c) { line = l; col = c; elems = new int [line * col]; } Matrix::Matrix(const Matrix &m) { line = m.line; col = m.col; } Matrix::~Matrix() { delete [] elems; } void Matrix::setLine(int l) { line = l; } void Matrix::setCol(int c) { col = c; } void Matrix::setElems() { for( int i = 0; i < line * col; i++) { cin>> elems[i]; } cout<<endl; } int Matrix::getLine() const { return line; } int Matrix::getCol() const { return col; } void Matrix::print() const { for(int i = 0; i < line * col; i++) { cout<<elems[i]<<" "; if((i + 1) % 3 == 0) cout<<endl; } } Matrix Matrix::operator=(const Matrix &m) { this->line = m.line; this->col = m.col; this->elems = m.elems; return *this; } Matrix Matrix::operator~() const { Matrix temp(line, col); for(int i = 0; i < line * col; i++) temp.elems[i] = 0; for(int i = 0; i < line; i++) { for(int j = 0; j < col; j++) { temp.elems[j + line * i] = elems[j * col + i]; } } return temp; } **主函数:** #include"Matrix.h" int main() { Matrix a(3,3), b(3,3); cout<<"请输入第一个矩阵的元素:"<<endl; a.setElems(); cout<<"请输入第二个矩阵的元素:"<<endl; b.setElems(); Matrix c(3,3); cout<<"两矩阵的乘积为:"<<endl; c = a * b; c.print(); cout<<"\n转置矩阵为:"<<endl; (~c).print(); return 0; } 这是我按书上要求写的一个程序,就是实现矩阵乘法,加法,减法,和转置的程序,但不知哪错了,得不到想要的结果,想请各位牛人给改一改,谢谢大家! 声明: 要用一维数组进行编写程序,我不清楚这个elems怎么初始化,和动态申请与释放,和其中的函数实现 要求的最终实现: 请输入第一个矩阵的元素: 1 2 3 4 5 6 7 8 9 请输入第一个矩阵的元素: 9 8 7 6 5 4 3 2 1 两矩阵的乘积为: 30 24 18 84 69 54 138 114 90 转置矩阵为: 30 84 138 24 69 114 18 54 90
关于iOS内存释放问题,求解答
我的类如下: 头文件: ``` #import "BmobDanmaku.h" @interface BmobBubbleDanmaku : BmobDanmaku @property NSMutableArray *listData; @property UITableView *tableView; @property UITableViewCell *tableViewCell; -(instancetype)init; @end ``` 实现文件: ``` // // BmobBubbleDanmaku.m // BmobDanmaku // // Created by limao on 15/4/14. // Copyright (c) 2015年 Bmob. All rights reserved. // #import "BmobBubbleDanmaku.h" @interface BmobBubbleDanmaku()<UITableViewDataSource,UITableViewDelegate> @end @implementation BmobBubbleDanmaku @synthesize listData=_listData; @synthesize tableView = _tableView; @synthesize tableViewCell =_tableViewCell; -(instancetype)init{ if (self = [super init]) { //初始化表格 self.tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 200, 200) style:UITableViewStylePlain]; // 设置协议,意思就是UITableView类的方法交给了tabView这个对象,让完去完成表格的一些设置操作 self.tableView.delegate=self; self.tableView.dataSource=self; self.listData = [[NSMutableArray alloc] initWithCapacity:0]; [self addSubview:self.tableView]; } return self; } //返回多少个section -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { return 1; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.listData count]; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 声明静态字符串型对象,用来标记重用单元格 static NSString *TableSampleIdentifier = @"TableSampleIdentifier"; // 用TableSampleIdentifier表示需要重用的单元 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableSampleIdentifier]; // 如果如果没有多余单元,则需要创建新的单元 if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:TableSampleIdentifier]; } else { while ([cell.contentView.subviews lastObject ]!=nil) { [(UIView*)[cell.contentView.subviews lastObject]removeFromSuperview]; } } // 获取当前行信息值 NSUInteger row = [indexPath row]; // 填充行的详细内容 cell.detailTextLabel.text = @"详细内容"; // 把数组中的值赋给单元格显示出来 cell.textLabel.text=[self.listData objectAtIndex:row]; // cell.textLabel.backgroundColor= [UIColor greenColor]; // 表视图单元提供的UILabel属性,设置字体大小 cell.textLabel.font = [UIFont boldSystemFontOfSize:40.0f]; // 设置单元格UILabel属性背景颜色 cell.textLabel.backgroundColor=[UIColor clearColor]; return cell; } -(void)dealloc{ NSLog(@"dealloc"); } @end ``` 调用的代码如下: ``` - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *array = [NSMutableArray arrayWithObjects:@"张三",@"张四",@"张五",@"李三",@"李四",@"李五",@"李六",@"王三",@"王四",@"王五",@"王六",@"王七",@"王八",@"王九",@"王十", nil]; BmobBubbleDanmaku *bmobBubbleDanmaku = [[BmobBubbleDanmaku alloc] init]; bmobBubbleDanmaku.listData = array; [self.view addSubview:bmobBubbleDanmaku.tableView]; } ``` 运行后提示错误如下: 2015-04-14 22:55:58.289 BmobDanmaku[4909:267989] dealloc 2015-04-14 22:55:58.296 BmobDanmaku[4909:267989] *** -[BmobBubbleDanmaku numberOfSectionsInTableView:]: message sent to deallocated instance 0x7d0bab20 也就是运行到numberOfSectionsInTableView时,我的bmobBubbleDanmaku已经被释放掉了,但是我不理解为什么会被释放了,求高手帮忙解答一下。
OpenGL图像显示和别人不一样
用老师给的源代码,原封不动运行,图像异常 原本应该是这样的 ![原本的样子](https://img-ask.csdn.net/upload/201909/20/1568908959_14748.png) 然后我电脑上是这样子的 ![我运行出来的样子](https://img-ask.csdn.net/upload/201909/20/1568908978_338083.png) 下面附上main.cpp的代码 (第一次遇到这样的问题,百度谷歌弄了一下午,把VS2013卸载安装了2019,还是搞不定,求大神帮忙,感激不尽) ``` #include "Angel.h" #pragma comment(lib, "glew32.lib") const int MENU_CHOICE_WHITE = 0; const int MENU_CHOICE_BLACK = 1; const int MENU_CHOICE_RED = 2; const int MENU_CHOICE_GREEN = 3; const int MENU_CHOICE_BLUE = 4; const int MENU_CHOICE_YELLOW = 5; const int MENU_CHOICE_ORANGE = 6; const int MENU_CHOICE_PURPLE = 7; const vec3 WHITE(1.0, 1.0, 1.0); const vec3 BLACK(0.0, 0.0, 0.0); const vec3 RED(1.0, 0.0, 0.0); const vec3 GREEN(0.0, 1.0, 0.0); const vec3 BLUE(0.0, 0.0, 1.0); const vec3 YELLOW(1.0, 1.0, 0.0); const vec3 ORANGE(1.0, 0.65, 0.0); const vec3 PURPLE(0.8, 0.0, 0.8); // 主窗口变量 const int SQUARE_NUM = 6; const int SQUARE_NUM_POINTS = 4 * SQUARE_NUM; int mainWindow; int mainWindowMenu; int mainWindowSubmenu; int width = 600; // 主窗口宽度 int height = 600; // 主窗口高度 double offsetAngle = 0; // 角度偏移量 double delta = 0.05; // 每次改变角度偏移的变化量 vec3 mainWindowSquareColor = WHITE; // 子窗口变量 const int ELLIPSE_NUM_POINTS = 100; int subWindow; int subWindowMenu; vec3 subWindowObjectColor = RED; // 获得圆上的点 vec2 getEllipseVertex(vec2 center, double scale, double verticleScale, double angle) { vec2 vertex(sin(angle), cos(angle)); vertex += center; vertex *= scale; vertex.y *= verticleScale; // 修改垂直分量 return vertex; } // 生成圆上顶点的属性 void generateEllipsePoints(vec2 vertices[], vec3 colors[], vec3 color, int startVertexIndex, int numPoints, vec2 center, double scale, double verticalScale) { double angleIncrement = (2 * M_PI) / numPoints; double currentAngle = M_PI / 2; for (int i = startVertexIndex; i < startVertexIndex + numPoints; i++) { vertices[i] = getEllipseVertex(center, scale, verticalScale, currentAngle); colors[i] = color; currentAngle += angleIncrement; } } // 获得正方形的每个角度 double getSquareAngle(int point) { return (M_PI / 4 + (M_PI / 2 * point)) + offsetAngle; } // 生成正方形上顶点的属性 void generateSquarePoints(vec2 vertices[], vec3 colors[], int squareNum, int startVertexIndex) { double scale = 0.90; double scaleAdjust = scale / squareNum; vec2 center(0.0, -0.25); int vertexIndex = startVertexIndex; for (int i = 0; i < squareNum; i++) { vec3 currentColor = 0 == i % 2 ? mainWindowSquareColor : BLACK; for (int j = 0; j < 4; j++) { double currentAngle = getSquareAngle(j); vertices[vertexIndex] = vec2(sin(currentAngle), cos(currentAngle)) * scale + center; colors[vertexIndex] = currentColor; vertexIndex++; } scale -= scaleAdjust; } } // 空闲回调函数 void idleFunction() { // 改变角度的偏移量 offsetAngle += delta; // 标记主窗口重绘 glutPostWindowRedisplay(mainWindow); } void mainWindowInit() { vec2 vertices[SQUARE_NUM * 4]; vec3 colors[SQUARE_NUM * 4]; // 创建主窗口中多个正方形 generateSquarePoints(vertices, colors, SQUARE_NUM, 0); // 创建顶点数组对象 GLuint vao[1]; glGenVertexArrays(1, vao); glBindVertexArray(vao[0]); // 创建并初始化顶点缓存对象 GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), NULL, GL_STATIC_DRAW); // 分别读取数据 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors); // 读取着色器并使用 GLuint program = InitShader("vshader.glsl", "fshader.glsl"); glUseProgram(program); // 从顶点着色器中初始化顶点的位置 GLuint pLocation = glGetAttribLocation(program, "vPosition"); glEnableVertexAttribArray(pLocation); glVertexAttribPointer(pLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 从片元着色器中初始化顶点的颜色 GLuint cLocation = glGetAttribLocation(program, "vColor"); glEnableVertexAttribArray(cLocation); glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices))); // 黑色背景 glClearColor(0.0, 0.0, 0.0, 1.0); } // 菜单回调函数 void mainWindowMenuEvents(int menuChoice) { switch (menuChoice) { case MENU_CHOICE_WHITE: mainWindowSquareColor = WHITE; break; case MENU_CHOICE_BLACK: mainWindowSquareColor = BLACK; break; case MENU_CHOICE_RED: mainWindowSquareColor = RED; break; case MENU_CHOICE_GREEN: mainWindowSquareColor = GREEN; break; case MENU_CHOICE_BLUE: mainWindowSquareColor = BLUE; break; case MENU_CHOICE_YELLOW: mainWindowSquareColor = YELLOW; break; case MENU_CHOICE_ORANGE: mainWindowSquareColor = ORANGE; break; case MENU_CHOICE_PURPLE: mainWindowSquareColor = PURPLE; break; /*在此处添加控制旋转动画开始和停止的菜单选项*/ } // 标记mainWindow主窗口进行重绘 glutPostWindowRedisplay(mainWindow); } // 创建和设置主窗口菜单 void mainWindowSetupMenu() { // 创建子菜单,并注册菜单回调函数mainWindowMenuEvents mainWindowSubmenu = glutCreateMenu(mainWindowMenuEvents); glutAddMenuEntry("Yellow", MENU_CHOICE_YELLOW); glutAddMenuEntry("Orange", MENU_CHOICE_ORANGE); glutAddMenuEntry("Purple", MENU_CHOICE_PURPLE); glutAddMenuEntry("Black", MENU_CHOICE_BLACK); // 创建主菜单 mainWindowMenu = glutCreateMenu(mainWindowMenuEvents); glutAddMenuEntry("Red", MENU_CHOICE_RED); glutAddMenuEntry("Green", MENU_CHOICE_GREEN); glutAddMenuEntry("Blue", MENU_CHOICE_BLUE); glutAddMenuEntry("White", MENU_CHOICE_WHITE); // 在主菜单中添加子菜单 glutAddSubMenu("Other Square Colors", mainWindowSubmenu); // 关联鼠标右键激活菜单 glutAttachMenu(GLUT_RIGHT_BUTTON); } void mainWindowDisplay() { mainWindowInit(); // 重绘时写入新的颜色数据 glClear(GL_COLOR_BUFFER_BIT); for (int i = 0; i < SQUARE_NUM; i++) { glDrawArrays(GL_TRIANGLE_FAN, (i * 4), 4); } glutSwapBuffers(); } // 主窗口键盘回调函数 void mainWindowKeyboard(unsigned char key, int x, int y) { /*在此添加按下Esc按键退出的代码*/ } // 主窗口鼠标回调函数 void mainWindowMouse(int button, int state, int x, int y) { if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) { // 按下鼠标中键,指定当没有其他事件处理时,去调用idleFunction()这个函数 glutIdleFunc(idleFunction); } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_UP) { // 释放鼠标中键,解除调用 glutIdleFunc(NULL); } } void subWindowInit() { vec2 vertices[ELLIPSE_NUM_POINTS]; vec3 colors[ELLIPSE_NUM_POINTS]; // 创建子窗口中的椭圆 generateEllipsePoints(vertices, colors, subWindowObjectColor, 0, ELLIPSE_NUM_POINTS, vec2(0.0, 0.0), 0.7, 0.5); // 创建顶点数组对象 GLuint vao[1]; glGenVertexArrays(1, vao); glBindVertexArray(vao[0]); // 创建并初始化顶点缓存对象 GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), NULL, GL_STATIC_DRAW); // 分别读取数据 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors); // 读取着色器并复用 GLuint program = InitShader("vshader.glsl", "fshader.glsl"); glUseProgram(program); // 从顶点着色器中初始化顶点的位置 GLuint pLocation = glGetAttribLocation(program, "vPosition"); glEnableVertexAttribArray(pLocation); glVertexAttribPointer(pLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 从片元着色器中初始化顶点的颜色 GLuint cLocation = glGetAttribLocation(program, "vColor"); glEnableVertexAttribArray(cLocation); glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices))); // 设置子窗口背景颜色为白色 glClearColor(1.0, 1.0, 1.0, 1.0); } void subWindowDisplay() { subWindowInit(); // 重绘时写入新的颜色数据 glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLE_FAN, 0, ELLIPSE_NUM_POINTS); glutSwapBuffers(); } // 子窗口键盘回调函数 void subWindowKeyboard(unsigned char key, int x, int y) { switch (key) { case 'r': subWindowObjectColor = RED; break; case 'g': subWindowObjectColor = GREEN; break; case 'b': subWindowObjectColor = BLUE; break; case 'y': subWindowObjectColor = YELLOW; break; case 'o': subWindowObjectColor = ORANGE; break; case 'p': subWindowObjectColor = PURPLE; break; case 'w': subWindowObjectColor = WHITE; break; } // 标记subWindow子窗口进行重绘 glutPostWindowRedisplay(subWindow); } void printHelp() { printf("%s\n\n", "Interaction and Submenu"); printf("Keys to update the background color in sub window:\n"); printf("'r' - red\n'g' - green\n'b' - blue\n'y' - yellow\n'o' - orange\n'p' - purple\n'w' - white\n"); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); // 启用双重缓冲 glutInitWindowSize(width, height); mainWindow = glutCreateWindow("Interaction and Submenu"); glewExperimental = GL_TRUE; glewInit(); mainWindowInit(); mainWindowSetupMenu(); glutDisplayFunc(mainWindowDisplay); // 在主窗口中指定函数mainWindowMouse,在鼠标按下或释放时将会被调用 glutMouseFunc(mainWindowMouse); // 创建子窗口 subWindow = glutCreateSubWindow(mainWindow, 0, 0, width / 4, height / 4); subWindowInit(); glutDisplayFunc(subWindowDisplay); // 在子窗口中指定函数subWindowKeyboard,当一个能够生成ASCII字符的键释放时会被调用 glutKeyboardFunc(subWindowKeyboard); // 输出帮助信息 printHelp(); glutMainLoop(); return 0; } ```
关于c语言从文件中读取学生信息,处理并打印
![图片说明](https://img-ask.csdn.net/upload/201712/07/1512617928_774992.png) b) 建议函数流程: i. 打开数据文件,失败返回-1; ii. 从头到尾扫描数据文件(即预读一遍)获得学生人数; iii. 根据学生人数,利用malloc和sizeof等函数或运算符为struct student** pStudents分配内存; iv. 利用rewind函数,定位到文件头; v. 读取数据文件,并把每一条记录通过数组下标法或指针法保存到结构体数组pStudents中; vi. 关闭文件; vii. 返回学生人数。 c) 数据文件格式说明: 一行一条学生信息的记录,不同属性用空格隔开,输入数据中无总成绩记录,例如: 张三 通信 89 93 95 李四 网络 88 91 94 王五 物联网 71 94 88 3. 编写统计函数: a) 函数定义void Count(struct student pStudents[], int num)。输入参数分别为保存学生的结构体数组和学生人数。 b) 功能为:统计所有学生的总成绩和每个专业(假定一共三个专业:通信,网络,物联网)的平均成绩;输入参数包括学生信息结构体数组,学生人数,返回的每个学生的总成绩直接填充到对应的输入结构体数组对应字段中。统计信息包括三个专业的总人数、平均成绩数组,用全局变量来表示。访问每个学生信息的时候,用指针来指向当前正在处理的学生。 c) 设计一个或者三个带参数的宏,判断输入的字符串是否是指定的专业名称,并在函数Count中使用。 5. 编写main函数实现: a) 定义变量,其中保存学生信息的数据文件直接在源代码中初始化; b) 读取学生信息,如果失败,打印失败信息并退出程序; c) 统计学生信息; d) 输出统计信息。 e) 释放内存。 ``` #include <stdio.h> #include <stdlib.h> #include <string.h> struct student{ char name[15]; char major[15]; int Eng_sco; int cal_sco; int c_sco; int sum; }; int tx_per=0,tx_ave,tx_sum=0; int wl_per=0,wl_ave,wl_sum=0; int wlw_per=0,wlw_ave,wlw_sum=0; int ReadStudentInfo(const char* filename, struct student** pStudents); void Count(struct student pStudents[], int num); int main() { int count; int m; struct student *list; count=ReadStudentInfo("readme.txt", &list); printf("学生信息: \n"); printf("----------------------------------------------------\n"); printf("序号 姓 名 专业名称 英语成绩 线性代数成绩 c语言成绩 总成绩\n"); for(m=1;m<=count;m++) { printf("%4d %s %s %4d %4d %4d %4d\n",m,(list+m-1)->name,(list+m-1)->major,(list+m-1)->Eng_sco,(list+m-1)->cal_sco,(list+m-1)->c_sco,(list+m-1)->sum); } Count(list, count); printf("\n统计信息 :\n"); printf("----------------------------------------------------\n"); printf("序号 专业名称 学生人数 平均成绩\n"); printf(" 1 通信 %d %d\n",tx_per,tx_ave); printf(" 2 网络 %d %d\n",wl_per,wl_ave); printf(" 3 物联网 %d %d\n",wlw_per,wlw_ave); return 0; } int ReadStudentInfo(const char* filename, struct student** pStudents) { FILE *fp; char ch; int i=1,j; fp=fopen(readme.txt,"r"); if(fp==NULL) { printf("cann't open the file"); exit(-1); } ch=fgetc(fp); while(ch!=EOF) { if(ch=='\n') { i++; } ch=fgetc(fp); } rewind(fp); *pStudents=(struct student*)malloc(sizeof(** pStudents)*i); for(j=0;j<i;j++) { fread(&*pStudents[j],sizeof(struct student)-sizeof(int),1,fp); (*pStudents+j)->sum=((*pStudents+j)->Eng_sco+(*pStudents+j)->cal_sco+(*pStudents+j)->c_sco); } fclose(fp); return i; } void Count(struct student pStudents[], int num) { int n=1; for(n=1;n<=num;n++) { if(!strcmp((pStudents+n-1)->major,"通信")) { tx_per++; tx_sum=tx_sum+(pStudents+n-1)->sum; } if(!strcmp((pStudents+n-1)->major,"网络")) { wl_per++; wl_sum=wl_sum+(pStudents+n-1)->sum; } if(!strcmp((pStudents+n-1)->major,"物联网")) { wlw_per++; wlw_sum=wlw_sum+(pStudents+n-1)->sum; } tx_ave=tx_sum/tx_per; wl_ave=wl_sum/wl_per; wlw_ave=wlw_sum/wlw_per; } free(pStudents); } ``` 运行不起来,是哪里出问题了?
求大神帮忙在我的代码(栈,C/C++,简单的四则运算)上修改一下,代码和要求都在楼下!
已经用C语言的栈写出个位数的四则运算,但不知道怎么修改成支持小数和多位数甚至可以sin,log,绝对值等数学运算,就类似于科学计算器,只要求控制台界面简单的输入就好,求大神帮忙在我的基础上修改,谢谢了! #include<stdio.h> #include<stdlib.h> #define newp (inn *)malloc(sizeof(inn)) //定义一个申请栈地址的宏 typedef struct stack { char data;//存入数据类型为字符 struct stack *next;//建立指针 }inn; //建立栈类型 int judge(char x) //比较优先级函数 { if(x=='+'||x=='-') return 0; else if(x=='*'||x=='/') return 1; else if(x=='#'||x=='('||x==')') return -1; } int main() { int flag = 1; while(flag) { printf("尾部不需要添加任何符号即可计算: "); inn *p,*top; //栈指针和栈顶指针 int number[50];//存入数字的数组 int i=0; char c; p = newp;//s开空间,newp为宏定义 p->data='#';//头指针第一个字符为# p->next = NULL;//初始化头指针里的next指针 top = p;//top跟p一起,接着新开的p的next指向top,栈用链表顺序不一样 c = getchar();//之后是读取中缀表达式的部分,用字符一个一个的读 while(c!='\n')//直到读到回车结束 { if(c>='0' && c<='9')//如果输入的是数字,存入数字数组(number) { i++;//加完后i=1 number[i] = c-48;//字符转数字存入数组 } else if(c=='(')//如果是左括号,直接进栈 { p = newp; //s开空间,newp为宏定义 p->data = c;//把左括号字符存入 p->next = top;//指针指向栈顶指针 top = p;//top指向p,到后面读从top往回读直到p->next = NULL } else if(c==')') //如果是右括号,匹配左括号,把两者之间的栈内符号全部弹出 { while(top->data!='(')//首先判断左括号,然后从左括号开始到右括号所有字符弹出 { p = top;//从左括号开始,用于计算完后p的地址释放空间 if(top->data=='+') { number[i-1]=number[i-1]+number[i]; i--; } else if(top->data=='-') { number[i-1]=number[i-1]-number[i]; i--; } else if(top->data=='*') { number[i-1]=number[i-1]*number[i]; i--; } else if(top->data=='/') { number[i-1]=number[i-1]/number[i]; i--; } top = top->next;//遍历链表 free(p);//释放空间 } p = top;//此时p用于指向空间便于下一步释放空间 top = top->next;//top++ free(p); } else //否则就是+-*/了 { int a =judge(c),b = judge(top->data);//比较该符号和栈顶符号优先级 if(a>b) //如果大于直接压进去 { p = newp;//开空间 p->data = c; p->next = top; top = p; } else //否则就把栈顶的符号一直弹出,直到弹到可以压进去(也就是说等于也不能压进去) { while(a<=b) { p = top;//从左括号开始,用于计算完后p的地址释放空间 if(top->data=='+') { number[i-1]=number[i-1]+number[i]; i--; } else if(top->data=='-') { number[i-1]=number[i-1]-number[i]; i--; } else if(top->data=='*') { number[i-1]=number[i-1]*number[i]; i--; } else if(top->data=='/') { number[i-1]=number[i-1]/number[i]; i--; } top = top->next;//遍历链表 free(p);//释放空间 b = judge(top->data); } p = newp;//开空间 p->data = c;//存入字符 p->next = top; top = p; } } c = getchar();//读取下一个字符 } while(top->data!='#')//读完还没有结束,还要把栈内剩余的所有符号挨个弹出 { p = top; if(top->data=='+') { number[i-1] = number[i-1]+number[i]; i--; } else if(top->data=='-') { number[i-1] = number[i-1]-number[i]; i--; } else if(top->data=='*') { number[i-1] = number[i-1]*number[i]; i--; } else if(top->data=='/') { number[i-1]=number[i-1]/number[i]; i--; } top = top->next; free(p); } printf("结果 = %d\n",number[i]); printf("\n是否需要继续输入?输入任何个位数字继续 / 0则退出\n"); scanf("%d",&flag); c = getchar(); } return 0; }
为什么会出现C语言指针指空的呢
/* * 将node链接到list的末尾 */ static void link_last(ENode *list, ENode *node) { ENode *p=list ; while(p->next_edge) p = p->next_edge; p->next_edge = node; } 编译会提示这方面里的错误 ![图片说明](https://img-ask.csdn.net/upload/201904/28/1556458124_943536.jpg) 0XFEFEFFEFE6表示明指针所指向的空间已经被释放 咋办 求大神解决 完整代码: #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <string.h> #define MAX 100 #define INF (~(0x1<<31)) // 最大值(即0X7FFFFFFF) #define isLetter(a) ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z'))) #define LENGTH(a) (sizeof(a)/sizeof(a[0])) // 邻接表中表对应的链表的顶点 typedef struct _ENode { int ivex; // 该边的顶点的位置 int weight; // 该边的权 struct _ENode *next_edge; // 指向下一条弧的指针 }ENode, *PENode; // 邻接表中表的顶点 typedef struct _VNode { char data; // 顶点信息 ENode *first_edge; // 指向第一条依附该顶点的弧 }VNode; // 邻接表 typedef struct _LGraph { int vexnum; // 图的顶点的数目 int edgnum; // 图的边的数目 VNode vexs[MAX]; }LGraph; /* * 返回ch在matrix矩阵中的位置 */ static int get_position(LGraph G, char ch) { int i; for(i=0; i<G.vexnum; i++) if(G.vexs[i].data==ch) return i; return -1; } /* * 读取一个输入字符 */ static char read_char() { char ch; do { ch = getchar(); } while(!isLetter(ch)); return ch; } /* * 将node链接到list的末尾 */ static void link_last(ENode *list, ENode *node) { ENode *p=list ; while(p->next_edge) p = p->next_edge; p->next_edge = node; } /* * 创建邻接表对应的图(自己输入) */ LGraph* create_lgraph() { char c1, c2; int v, e; int i, p1, p2; int weight; ENode *node1, *node2; LGraph* pG; // 输入"顶点数"和"边数" printf("输入顶点数: "); scanf("%d", &v); printf("输入边数: "); scanf("%d", &e); if ( v < 1 || e < 1 || (e > (v * (v-1)))) { printf("input error: invalid parameters!\n"); return NULL; } if ((pG=(LGraph*)malloc(sizeof(LGraph))) == NULL ) return NULL; memset(pG, 0, sizeof(LGraph)); // 初始化"顶点数"和"边数" pG->vexnum = v; pG->edgnum = e; // 初始化"邻接表"的顶点 for(i=0; i<pG->vexnum; i++) { printf("顶点(%d): ", i); pG->vexs[i].data = read_char(); pG->vexs[i].first_edge = NULL; } // 初始化"邻接表"的边 for(i=0; i<pG->edgnum; i++) { // 读取边的起始顶点,结束顶点,权 printf("边(%d): ", i); c1 = read_char(); c2 = read_char(); scanf("%d", &weight); p1 = get_position(*pG, c1); p2 = get_position(*pG, c2); // 初始化node1 node1 = (ENode*)malloc(sizeof(ENode)); node1->ivex = p2; node1->weight = weight; // 将node1链接到"p1所在链表的末尾" if(pG->vexs[p1].first_edge == NULL) pG->vexs[p1].first_edge = node1; else{ link_last(pG->vexs[p1].first_edge, node1); } // 初始化node2 node2 = (ENode*)malloc(sizeof(ENode)); node2->ivex = p1; node2->weight = weight; // 将node2链接到"p2所在链表的末尾" if(pG->vexs[p2].first_edge == NULL) pG->vexs[p2].first_edge = node2; else{ link_last(pG->vexs[p2].first_edge, node2);} free(node1); free(node2); } return pG; } // 边的结构体 typedef struct _edata { char start; // 边的起点 char end; // 边的终点 int weight; // 边的权重 }EData; /* * 打印邻接表图 */ void print_lgraph(LGraph G) { int i; ENode *node; printf("List Graph:\n"); for (i = 0; i < G.vexnum; i++) { printf("%d(%c): ", i, G.vexs[i].data); node = G.vexs[i].first_edge; while (node != NULL) { printf("%d(%c) ", node->ivex, G.vexs[node->ivex].data); node = node->next_edge; } printf("\n"); } } /* * 获取G中边<start, end>的权值;若start和end不是连通的,则返回无穷大。 */ int getWeight(LGraph G, int start, int end) { ENode *node; if (start==end) return 0; node = G.vexs[start].first_edge; while (node!=NULL) { if (end==node->ivex) return node->weight; node = node->next_edge; } return INF; } /* * 获取图中的边 */ EData* get_edges(LGraph G) { int i; int index=0; ENode *node; EData *edges; edges = (EData*)malloc(G.edgnum*sizeof(EData)); for (i=0; i<G.vexnum; i++) { node = G.vexs[i].first_edge; while (node != NULL) { if (node->ivex > i) { edges[index].start = G.vexs[i].data; // 起点 edges[index].end = G.vexs[node->ivex].data; // 终点 edges[index].weight = node->weight; // 权 index++; } node = node->next_edge; } } return edges; } /* * 对边按照权值大小进行排序(由小到大) */ void sorted_edges(EData* edges, int elen) { int i,j; for (i=0; i<elen; i++) { for (j=i+1; j<elen; j++) { if (edges[i].weight > edges[j].weight) { // 交换"第i条边"和"第j条边" EData tmp = edges[i]; edges[i] = edges[j]; edges[j] = tmp; } } } } /* * 获取i的终点 */ int get_end(int vends[], int i) { while (vends[i] != 0) i = vends[i]; return i; } /* * 克鲁斯卡尔(Kruskal)最小生成树 */ void kruskal(LGraph G) { int i,m,n,p1,p2; int length; int index = 0; // rets数组的索引 int vends[MAX]={0}; // 用于保存"已有最小生成树"中每个顶点在该最小树中的终点。 EData rets[MAX]; // 结果数组,保存kruskal最小生成树的边 EData *edges; // 图对应的所有边 // 获取"图中所有的边" edges = get_edges(G); // 将边按照"权"的大小进行排序(从小到大) sorted_edges(edges, G.edgnum); for (i=0; i<G.edgnum; i++) { p1 = get_position(G, edges[i].start); // 获取第i条边的"起点"的序号 p2 = get_position(G, edges[i].end); // 获取第i条边的"终点"的序号 m = get_end(vends, p1); // 获取p1在"已有的最小生成树"中的终点 n = get_end(vends, p2); // 获取p2在"已有的最小生成树"中的终点 // 如果m!=n,意味着"边i"与"已经添加到最小生成树中的顶点"没有形成环路 if (m != n) { vends[m] = n; // 设置m在"已有的最小生成树"中的终点为n rets[index++] = edges[i]; // 保存结果 } } free(edges); // 统计并打印"kruskal最小生成树"的信息 length = 0; for (i = 0; i < index; i++) length += rets[i].weight; printf("Kruskal=%d: ", length); for (i = 0; i < index; i++) printf("(%c,%c) ", rets[i].start, rets[i].end); printf("\n"); } void main() { LGraph* pG; pG = create_lgraph(); print_lgraph(*pG); // 打印图 kruskal(*pG); // kruskal算法生成最小生成树 }
C++课程设计 求大神帮忙写下构造函数和析构函数
1.网格世界类 网格中每个元素存放各种生物对象的指针或者为空。模拟过程中,我们需要移动生物,还有繁殖和饥饿(死亡),所以在网格类中,我们可以将一只生物放到网格中;可以读取网格中的某个指定位置的生物,获取它的指针,以便在每一个time step中对它进行处理(移动、繁殖和饥饿死亡)。在一个time step中,网格中每只生物都要处理一遍,先狮蚁,后蚂蚁。另外,应该有一个显示网格的成员函数。 2.有机生物类 生物要能够放到网格中,所以每一只生物都有相关的函数。可以是构造函数,即构造生物的时候,同时指明放到网格的哪一个位置上。 有Move函数,Breed函数,Starve函数(是否饿死)。这些函数在派生类中有派生类自己的实现。所以,在有机生物类中,这些函数应该是纯虚函数,有机生物类是一个抽象类。 网格世界类中,从某个网格位置读取生物并处理时,需要知道是哪一种类型的生物(是狮蚁还是蚂蚁),所以,有机生物类里应该考虑如何返回生物的类型。简单的办法是,用不同的常量来表示狮蚁和蚂蚁。例如,用整数1表示狮蚁,2表示蚂蚁。在有机生物类中定义纯虚函数GetType,返回生物的具体类型。 3.蚂蚁类 实现Move函数,Breed函数,Starve函数和GetType函数。 4.狮蚁类 实现Move函数,Breed函数,Starve函数和GetType函数。 (二)细化: 1.网格世界类: (1)属性。数据结构:网格世界中如何存放蚂蚁或狮蚁对象? 20*20的网格,用一个20*20的二维数组来表示,数组元素是什么类型? (2)方法。网格世界类应该有哪些成员函数? 构造函数:初始化网格。 析构函数:释放掉所有生物。 Set函数:指定x,y位置(二维数组的下标),以及一只生物的地址(指针),将这只生物存入网格中。 Get函数:获取网格中x,y坐标上的生物的地址(指针)。 OneStep函数:在一个time step中,网格中每只生物都要处理一遍,包括移动、繁殖和饥饿。首先,把网格中的每一只生物在本轮是否移动过的标记moved先都标记为假(为什么?);其次,移动,先狮蚁,后蚂蚁,同时把该生物的moved标记为真;再次,把饥饿的狮蚁消灭掉;最后,繁殖。 Display函数:显示函数,显示网格中的具体情况。每个网格,如果是空,显示”.”;如果是蚂蚁,显示”o”;如果是狮蚁,显示”x”。 2.有机生物类 (1)属性 要记录每只生物的一些基本属性:属于哪个网格对象,具体在哪个位置上(x,y坐标),本轮是否移动过。另外,为了记录是否到了繁殖时间,要有一个跟踪器,即记录上次繁殖之后,又经历了多少次time step。 (2)方法 构造函数: 带参数的构造函数:指定网格对象和x、y位置,把构造的生物放到网格中。 析构函数: Move函数,Breed函数,Starve函数和GetType函数为纯虚函数。 3.蚂蚁类 (1)属性 不需要再添加属性。 (2)方法 构造函数: 带参数的构造函数:指定网格对象和x、y位置,把构造的蚂蚁放到网格中。 析构函数: Move函数:随机选择一个方向,看是否能移动,否则保持在原位置。 Breed函数:繁殖跟踪器+1.如果是3的倍数,就需要繁殖,同时跟踪器清零。 Starve函数:本模拟中蚂蚁不会饿死,所以仅返回false值即可。 GetType函数:返回蚂蚁的类型标记。 4.狮蚁类 (1)属性 狮蚁会饿死,需要添加一个属性,跟踪记录狮蚁饥饿了多少次time step。 (2)方法 构造函数: 带参数的构造函数:指定网格对象和x、y位置,把构造的狮蚁放到网格中。 析构函数: Move函数:若有相邻蚂蚁,移动到单元网格,吃掉蚂蚁;否则,随机选择一个方向,看是否能移动,不能移动则保持在原位置。 Breed函数:繁殖跟踪器+1,如果是8的倍数,就需要繁殖,同时跟踪器清零。 Starve函数:饥饿跟踪器+1,如果是3的倍数,则饥饿并死亡,从网格中拿掉该狮蚁,同时跟踪器清零。 GetType函数:返回狮蚁的类型标记。 四、其它 (一)所有涉及的常量定义为类型常量。如: const int ANTBREED = 3; //蚂蚁的繁殖周期为3个time steps const int DOODLEBREED = 8; //狮蚁的繁殖周期为8个time steps 初始化网格世界时,用的狮蚁只数和蚂蚁只数,分别为5只和100只,也定义为类型常量。如: const int INITIALANTS = 100; const int INITIALBUGS = 5;
C++的这个有类模板的代码怎么改成三个文件(seqstack.h、seqstack.cpp、main.cpp)?具体代码是怎么样的?
``` //功能:顺序栈的功能演示 #include <stdlib.h> #include <conio.h> #include <string.h> #include <iostream.h> //以下为栈的定义部分,如果用工程建立程序,可以另外启用文件seqstack.h /* 模板顺序栈类seqstack的定义说明 */ template <class Type> class seqstack { public: seqstack();//创建一个空栈 seqstack(int size);//创建一个可以容纳size个元素的栈 ~seqstack();//回收一个栈 bool create(int size);//实际创建一个可以容纳size个元素的栈 void destroy();//销毁一个栈 bool isempty() const;//确定栈是否已空 bool isfull() const;//确定栈是否已满 bool push(Type &item);//数据进栈 bool pop();//数据出栈 bool pop(Type &item);//数据出栈并返回出栈前的栈顶 bool getpop(Type &item);//取出当前栈顶数据 void display();//显示栈的所有元素 private: Type *stackspace;//栈空间的具体实现,在下面通过动态申请空间建立数组 int stacksize;//栈的大小,当为0时,栈没有创建空间 int top;//栈顶位置,当为-1时,栈为空 }; //以下为栈的实现部分,如果用工程建立程序,可以另外启用文件seqstack.cpp template <class Type> seqstack<Type>::seqstack()//创建一个空栈 { stackspace=NULL;//初始化,空间起始地址为空 stacksize=0;//栈的大小,初始值为0,表示目前还没有建立 top=-1;//栈顶位置,当为-1时,栈为空 } template <class Type> seqstack<Type>::seqstack(int size)//创建一个可以容纳size个元素的栈 { stackspace=NULL;//初始化,空间起始地址为空 stacksize=0;//栈的大小,初始值为0,表示目前还没有建立 top=-1;//栈顶位置,当为-1时,栈为空 create(size);//开始用size大小为参数建立栈的空间 } template <class Type> seqstack<Type>::~seqstack()//回收一个栈 { destroy();//析构函数,释放相关空间 } template <class Type> bool seqstack<Type>::create(int size)//实际创建一个可以容纳size个元素的栈 { if(stacksize)//栈已经存在,不能再创建 return false; if(size<=0)//size的值必须大于零 return false; stackspace=new Type[size];//申请动态数组空间 if(!stackspace)//没有申请到存储空间,创建栈不成功 return false; stacksize=size;//申请到存储空间,创建栈成功,大小为size top=-1;//栈刚建立成功时,栈顶指针为-1 return true; } template <class Type> void seqstack<Type>::destroy()//销毁一个栈 { if(stackspace) delete [] stackspace;//释放栈的空间,还给操作系统 stackspace=NULL;//空间起始地址恢复为空 stacksize=0;//栈的大小恢复为初始值0,表示目前还没有建立 top=-1;//栈顶指针恢复为-1 } template <class Type> bool seqstack<Type>::isempty() const//确定栈是否已空 { if(!stacksize)//确定栈是否被创建,没有创建视为空 return true; return top==-1?true:false;//根据栈顶指针的位置返回是否为空 } template <class Type> bool seqstack<Type>::isfull() const//确定栈是否已满 { if(!stacksize)//确定栈是否被创建,没有创建视为空 return true; return top==stacksize-1?true:false;//根据栈顶指针的位置返回是否为满 } template <class Type> bool seqstack<Type>::push(Type &item)//数据进栈 { if(!stacksize)//如果栈没有被创建,则不能执行进栈操作 return false; if(isfull())//如果栈空间已满,则不能执行进栈操作 return false; stackspace[++top]=item;//实际进栈的操作,具体分为两步:先产生地址,后插入数据 return true;//返回成功标志 } template <class Type> bool seqstack<Type>::pop()//数据出栈 { if(isempty())//如果栈空间已经为空,则不能执行出栈操作 return false; top--;//执行出栈操作,栈顶指针减1 return true;//返回成功标志 } template <class Type> bool seqstack<Type>::pop(Type &item)//数据出栈并返回出栈前的栈顶 { if(isempty())//如果栈空间已经为空,则不能执行进栈操作 return false; item=stackspace[top--];//执行出栈操作,把栈顶数据保存起来返回,栈顶指针减1 return true;//返回成功标志 } template <class Type> bool seqstack<Type>::getpop(Type &item)//取出当前栈顶数据 { if(isempty())//如果栈空间已经为空,则不能执行进栈操作 return false; item=stackspace[top];//把栈顶数据保存起来返回 return true;//返回成功标志 } template <class Type> void seqstack<Type>::display()//显示栈的所有元素 { if(!stacksize)//当栈中没有数据时则放弃显示所有数据 cout<<"栈尚未建立!"<<endl; else//当栈中有数据时则显示所有数据 { cout<<"目前栈中的内容是:"; cout<<"栈底■"; for(int i=0;i<=top;i++)//栈的空间从0到top指向的位置 cout<<stackspace[i]<<" ";//输出每一个数据,同时间隔一个空格 cout<<"←top栈顶"<<endl; } } /* 定义一个实现顺序栈功能的菜单处理类interfacebase */ template <class Type> class interfacebase { private: seqstack<Type> seqstackonface; public: void clearscreen(void);//清屏 void showmenu(void);//显示菜单函数 int userchoice(void);//用户的选项 void processmenu(int menuchoice);//菜单函数 }; template <class Type> void interfacebase<Type>::clearscreen(void) { system("cls"); } template <class Type> void interfacebase<Type>::showmenu(void) { cout<<"顺序栈基本功能菜单"<<endl; cout<<"=================="<<endl; cout<<"1.创建一个栈"<<endl; cout<<"2.销毁一个栈"<<endl; cout<<"3.数据进栈(仅限整数)"<<endl; cout<<"4.数据出栈"<<endl; cout<<"5.显示栈中全部数据"<<endl; cout<<"6.读取栈顶数据"<<endl; cout<<"7.判断是否空栈"<<endl; cout<<"8.判断是否满栈"<<endl; cout<<"0.退出"<<endl; cout<<"=================="<<endl; } template <class Type> int interfacebase<Type>::userchoice(void) { int menuchoice; cout<<"请输入您的选择:"; cin>>menuchoice; return menuchoice; } template <class Type> void interfacebase<Type>::processmenu(int menuchoice) { int size; Type item; switch(menuchoice)//根据用户的选择进行相应的操作 { case 1: cout<<"请输入栈的大小:"; cin>>size; seqstackonface.create(size); cout<<"栈的大小为:"<<size; break; case 2: seqstackonface.destroy(); cout<<"栈已销毁!"<<endl; break; case 3: cout<<"请输入进栈数据:"; cin>>item; seqstackonface.push(item); cout<<"数据已进栈!"<<endl; break; case 4: seqstackonface.pop(item); cout<<"出栈数据:"<<item<<endl; cout<<"数据已出栈!"<<endl; break; case 5: seqstackonface.display(); cout<<"已遍历栈中全部数据!"<<endl; break; case 6: seqstackonface.getpop(item); cout<<"当前栈顶数据为:"<<item<<endl; break; case 7: if(seqstackonface.isempty()) cout<<"栈已空!"<<endl; else cout<<"栈未空!"<<endl; break; case 8: if(seqstackonface.isfull()) cout<<"栈已满!"<<endl; else cout<<"栈未满!"<<endl; break; case 0: exit(0); default: cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl; break; } } /* 程序主入口 */ void main(void) { int menuchoice;//定义变量,菜单选单项的选择 interfacebase<int> interfacenow; seqstack<int> seqstacknow; system("color f0");//修改屏幕的背景色和字的颜色 interfacenow.clearscreen();//清屏 while(1)//永真循环 { interfacenow.showmenu();//显示菜单 menuchoice=interfacenow.userchoice();//获取用户的选择 interfacenow.processmenu(menuchoice);//处理用户的选择 system("pause");//暂停 interfacenow.clearscreen();//清屏 } }//主函数结束 ```
编译报错,destroyList要先声明后使用,但是为什么initSqlist不报错
#include <stdio.h> #include <stdlib.h> //定义一个三元数组 typedef struct Sqlist{ int * elem;//起始地址 int length;//初始长度 int listSize;//线性表容量 }Sqlist; int main(int argc, char *argv[]) { Sqlist q; initSqlist(&q,10); //destroyList(&q); printf("%d\n",q.listSize); system("PAUSE"); return 0; } /* *初始化一个线性列表 *list 是需要被初始化的列表引用 *size 是分配的空间大小 */ int initSqlist(Sqlist* list,int size) { list->length = 0; list->listSize = size; list->elem = (int*) malloc(size*sizeof(int)); } /* 释放malloc分配的内存空间 */ void destroyList(Sqlist* list) { free(list); }
关于C语言链表的一些问题,代码怎么都运行不成功跪求大神指点
下面代码主要实现链表的创建,插入,删除,并且能将两个年龄递增链表进行合并成递减链表 然而在插入和删除操作中gets函数无法起作用,strcmp函数也出现位置冲突报错。。功力不足实在解决不了。。跪求大神解答。。(感觉自己写的东西除了上面两个错误应该还有,但是因为位置冲突问题就只能编译到那个地方无法进行下去。。我肉眼实在找不出来。。 ``` #include<stdio.h> #include<stdlib.h> #include<string.h> int a[10]={0}; int c[10]={0}; char b[100][10]; char d[100][10]; typedef struct stuInfo { char stuName[10];/*学生姓名*/ int age; /*年龄*/ } ElemType; typedef struct node { ElemType data; struct node *next; }LNode,*ListPtr;/*定义结构*/ ListPtr List_Init(int a[],char b[][10],int n){/*链表载入数据*/ LNode *s,*h; int i; h=NULL; h=(LNode*)malloc(sizeof(LNode)); h->data.age=0; memset(h->data.stuName,0,10*sizeof(char)); h->next=NULL; for(i=n-1;i>=0;i--) { s=(LNode*)malloc(sizeof(LNode));/*分配内存*/ memset(s->data.stuName,0,10*sizeof(char)); s->data.age=a[i];/*把年龄载入*/ strcpy(s->data.stuName,b[i]);/*把名字载入*/ s->next=h->next;/*新的结点指向头节点的下一个结点*/ h->next=s;/*头结点指向新的结点*/ } return h; } ListPtr List_Insert (ListPtr h, ElemType x){/*结点插入*/ LNode *s; s=(LNode*)malloc(sizeof(LNode)); s->data.age=x.age; strcpy(s->data.stuName,x.stuName);/*分配空间结点载入*/ s->next=h->next;/*新的结点指向前一个结点的后一个结点*/ h->next=s;/*前一个结点指向新结点*/ return h; } void List_Destroy(ListPtr h,ListPtr L){ LNode *s,*p; s=L->next;/*指向第一个结点*/ p=s; while(s){/*寻找所要删除的数据结点的前一个结点*/ if(s->data.age==h->data.age&&strcmp(s->data.stuName,h->data.stuName)==0) break; p=s; s=s->next; } s=p->next;/*s指定要删除的结点*/ p->next=s->next;/*前一个结点指向所要删除结点的后一个结点*/ free(s); } ListPtr List_Merge(ListPtr La, ListPtr Lb){/*链表变换,使递增链表变为递减链表,并去重*/ LNode *s, *pa, *pb; pa=La->next; pb=Lb->next;/*各指向两个链表的头结点*/ La->next=NULL; while(pa!=NULL&&pb!=NULL){ if(pa->data.age<=pb->data.age){ s=pa->next; pa->next=La->next; La->next=pa; pa=s;/*如果pa指向的年龄比pb的小则保留并逆置,pa指针指向下一个数据*/ if(strcmp(pa->data.stuName,pb->data.stuName)==0){ pb=pb->next;/*如果pa和pb所指的是同一个人,则pb也指向下一个数据,避免重复*/ } } else{ s=pb->next; pb->next=La->next; La->next=pb; pb=s; }/*如果pb指向的年龄比pa的小,则插入到La链表中*/ } while(pa!=NULL){ s=pa->next; pa->next=La->next; La->next=pa; pa=s;}/*处理La未处理的数据*/ while(pb!=NULL){ s=pb->next; pb->next=La->next; La->next=pb; pb=s;}/*处理Lb未处理的数据*/ Lb->next=NULL; free(Lb);/*释放Lb*/ } void OutPut(ListPtr La){/*输出链表*/ LNode *s; s=La->next; while(s){ printf("%s\t%d\n",s->data.stuName, s->data.age); } } int main(){ ElemType x; int n,i,j; ListPtr La=NULL, Lb=NULL; LNode *p,*r; for(i=0;i<10;i++){ memset(b[i],0,10*sizeof(char)); memset(d[i],0,10*sizeof(char)); }/*初始化字符串数组*/ strcpy(b[0],"Levis");a[0]=22; strcpy(b[1],"Adam");a[1]=23; strcpy(b[2],"Lord");a[2]=26; strcpy(b[3],"Fred");a[3]=28; strcpy(b[4],"May");a[4]=30; strcpy(b[5],"York");a[5]=35; La=List_Init(a, b, 6); /*La数据载入*/ strcpy(d[0],"Yuki");c[0]=19; strcpy(d[1],"Soraru");c[1]=27; strcpy(d[2],"Katin");c[2]=29; strcpy(d[3],"Sinsan");c[3]=31; strcpy(d[4],"York");c[4]=35; Lb=List_Init(c, d, 5); /*Lb数据载入*/ printf("choose operation: 1. insert 2. delete 3.nothing: "); scanf("%d",&j); if(j==1){ printf("enter the student's name you want to insert:");/*插入数据操作*/ gets(x.stuName); printf("enter the student's age:"); scanf("%d",&x.age); p=La->next; while(p){/*查找La中是否有此人*/ if(strcmp(p->data.stuName,x.stuName)==0) break; p=p->next; } if(p=NULL){/*如果没则寻找插入位置*/ p=La->next;r=p; while (p){ if(x.age<=p->data.age) break; r=p; p=p->next;/*找到比它大的值后,r记录此结点的前一个结点*/ } List_Insert (r, x);/*在r后插入此数据结点*/ } else{ p=Lb->next;/*La中已有此人,则查找Lb*/ while(p){ if(strcmp(p->data.stuName,x.stuName)==0) break; p=p->next; } if(p=NULL){ p=Lb->next;r=p; while (p){ if(x.age<=p->data.age) break; r=p; p=p->next; } List_Insert (r, x);}}/*同La*/ if(p!=NULL){ printf("inserted fail");}/*如果两链表中已有此人,则表示插入失败*/ } if(j==2){ printf("enter the student's name you want to delete:");/*进行删除操作*/ gets(x.stuName); printf("which lianbiao do you choose, if La, input 1;Lb,input 2:");/*选择要插入的链表*/ scanf("%d",&i); if(i==1){ p=La->next; while(p){ if(strcmp(p->data.stuName,x.stuName)==0)/*查找La中此人的位置*/ break; p=p->next;/*移动到下一个结点*/ } if(p!=NULL){ List_Destroy(p,La);} else {printf("查无此人");}/*移动到下一个结点*/ } if(i==2){ p=Lb->next; while(p){ if(strcmp(p->data.stuName,x.stuName)==0) break; p=p->next; } if(p!=NULL){List_Destroy(p,Lb);} else {printf("查无此人");}}/*同La*/ } printf("now ranking......\n");/*显示递增合并为递减的信息*/ List_Merge(La, Lb); OutPut(La);/*输出函数*/ return 0; } ``` 然而在插入和删除操作中gets函数无法起作用,strcmp函数也出现位置冲突报错。。功力不足实在解决不了。。跪求大神解答。。(感觉自己写的东西除了上面两个错误应该还有,但是因为位置冲突问题就只能编译到那个地方无法进行下去。。我肉眼实在找不出来。。
类模板实例化(整型)后,再实例化(浮点型),为什么只能用整型?
``` //Vc++6.0实现,问题代码在choiceType类processstack(int number)里 //seqstack.h //以下为栈的定义部分,如果用工程建立程序,可以另外启用文件seqstack.h enum returninfo{success,fail,overflow,nooverflow,underflow,nounderflow};//定义返回信息清单 /* 模板顺序栈类seqstack的定义说明 */ template <class Type> class seqstack { public: seqstack();//创建一个空栈 seqstack(int size);//创建一个可以容纳size个元素的栈 ~seqstack();//回收一个栈 bool create(int size);//实际创建一个可以容纳size个元素的栈 returninfo destroy();//销毁一个栈 returninfo isempty() const;//确定栈是否已空 returninfo isfull() const;//确定栈是否已满 bool push(Type &item);//数据进栈 returninfo pushfull();//进栈时是否栈满 bool pop();//数据出栈 bool pop(Type &item);//数据出栈并返回出栈前的栈顶 returninfo popempty();//出栈时是否栈空 returninfo getpop(Type &item);//取出当前栈顶数据 returninfo information();//栈空间使用情况 returninfo display();//显示栈的所有元素 private: Type *stackspace;//栈空间的具体实现,在下面通过动态申请空间建立数组 int stacksize;//栈的大小,当为0时,栈没有创建空间 int top;//栈顶位置,当为-1时,栈为空 int count;//已进栈数据个数 }; /* 定义一个实现顺序栈功能的菜单处理类interfacebase */ template <class Type> class interfacebase { private: seqstack<Type> seqstackonface; int choice; public: void clearscreen(void);//清屏 void showmenu(void);//显示菜单函数 int userchoice(void);//用户的选项 int judgechoice(); returninfo processmenu(int menuchoice);//菜单函数 }; /* 定义一个选择数据类型的菜单处理类choiceType */ template <class Type> class choiceType { private: interfacebase<Type> interfacebaseonface; public: void clearscreen(void);//清屏 void showmenu(void);//显示菜单函数 int userchoice(void);//用户的选项 void processstack(int number); returninfo processmenu(int menuchoice);//菜单函数 }; //seqstack.cpp //功能:顺序栈的功能演示 #include "seqstack.h" #include <stdlib.h> #include <conio.h> #include <string.h> #include <iostream.h> //以下为栈的实现部分,如果用工程建立程序,可以另外启用文件seqstack.cpp /* seqstack类的实现部分 */ template <class Type> seqstack<Type>::seqstack()//创建一个空栈 { stackspace=NULL;//初始化,空间起始地址为空 stacksize=0;//栈的大小,初始值为0,表示目前还没有建立 top=-1;//栈顶位置,当为-1时,栈为空 count=0;//已进栈数据个数为零 } template <class Type> seqstack<Type>::seqstack(int size)//创建一个可以容纳size个元素的栈 { stackspace=NULL;//初始化,空间起始地址为空 stacksize=0;//栈的大小,初始值为0,表示目前还没有建立 top=-1;//栈顶位置,当为-1时,栈为空 count=0;//已进栈数据个数为零 create(size);//开始用size大小为参数建立栈的空间 } template <class Type> seqstack<Type>::~seqstack()//回收一个栈 { destroy();//析构函数,释放相关空间 } template <class Type> bool seqstack<Type>::create(int size)//实际创建一个可以容纳size个元素的栈 { if(stacksize)//栈已经存在,不能再创建 return false; if(size<=0)//size的值必须大于零 return false; stackspace=new Type[size];//申请动态数组空间 if(!stackspace)//没有申请到存储空间,创建栈不成功 return false; stacksize=size;//申请到存储空间,创建栈成功,大小为size top=-1;//栈刚建立成功时,栈顶指针为-1 count=0;//已进栈数据个数为零 return true; } template <class Type> returninfo seqstack<Type>::destroy()//销毁一个栈 { if(isempty()==fail)//确定栈是否被创建,没有创建视为空 return fail; if(stackspace) delete [] stackspace;//释放栈的空间,还给操作系统 stackspace=NULL;//空间起始地址恢复为空 stacksize=0;//栈的大小恢复为初始值0,表示目前还没有建立 top=-1;//栈顶指针恢复为-1 count=0;//已进栈数据个数为零 return success; } template <class Type> returninfo seqstack<Type>::isempty() const//确定栈是否已空 { if(!stacksize)//确定栈是否被创建,没有创建视为空 return fail; return top==-1?underflow:nounderflow;//根据栈顶指针的位置返回是否为空 } template <class Type> returninfo seqstack<Type>::isfull() const//确定栈是否已满 { if(!stacksize)//确定栈是否被创建,没有创建视为空 return fail; return top==stacksize-1?overflow:nooverflow;//根据栈顶指针的位置返回是否为满 } template <class Type> bool seqstack<Type>::push(Type &item)//数据进栈 { stackspace[++top]=item;//实际进栈的操作,具体分为两步:先产生地址,后插入数据 count++;//进栈数据个数加1 return true;//返回成功标志 } template <class Type> returninfo seqstack<Type>::pushfull()//进栈时是否栈满 { if(isempty()==fail) return fail; if(isfull()==overflow)//如果栈空间已经为满,则不能执行进栈操作 return overflow; else return success; } template <class Type> bool seqstack<Type>::pop()//数据出栈 { top--;//执行出栈操作,栈顶指针减1 count--;//进栈数据个数减1 return true;//返回成功标志 } template <class Type> bool seqstack<Type>::pop(Type &item)//数据出栈并返回出栈前的栈顶 { item=stackspace[top--];//执行出栈操作,把栈顶数据保存起来返回,栈顶指针减1 count--;//进栈数据个数减1 return true;//返回成功标志 } template <class Type> returninfo seqstack<Type>::popempty()//出栈时是否栈空 { if(isempty()==fail) return fail; if(isempty()==underflow)//如果栈空间已经为空,则不能执行出栈操作 return underflow; else return success; } template <class Type> returninfo seqstack<Type>::getpop(Type &item)//取出当前栈顶数据 { if(isempty()==fail)//如果栈空间已经为空,则不能执行出栈操作 return fail; if(isempty()==underflow) return underflow; item=stackspace[top];//把栈顶数据保存起来返回 return success;//返回成功标志 } template <class Type> returninfo seqstack<Type>::information()//栈空间使用情况 { if(isempty()==fail)//当栈中没有数据时则放弃显示所有数据 return fail; else { cout<<"栈总空间:"<<stacksize<<"个"<<endl<<"栈已用空间:"<<count<<"个"<<endl<<"栈剩余空间:"<<stacksize-count<<"个"; return success; } } template <class Type> returninfo seqstack<Type>::display()//显示栈的所有元素 { if(isempty()==fail)//当栈中没有数据时则放弃显示所有数据 return fail; else//当栈中有数据时则显示所有数据 { cout<<"目前栈中的内容是:"; cout<<"栈底■"; for(int i=0;i<=top;i++)//栈的空间从0到top指向的位置 cout<<stackspace[i]<<" ";//输出每一个数据,同时间隔一个空格 cout<<"←top栈顶"<<endl; return success; } } /* interfacebase类的实现部分 */ template <class Type> void interfacebase<Type>::clearscreen(void) { system("cls"); } template <class Type> void interfacebase<Type>::showmenu(void) { cout<<"顺序栈基本功能菜单"<<endl; cout<<"=================="<<endl; cout<<"1.创建一个栈"<<endl; cout<<"2.销毁一个栈"<<endl; cout<<"3.数据进栈(仅限整数)"<<endl; cout<<"4.数据出栈"<<endl; cout<<"5.显示栈中全部数据"<<endl; cout<<"6.读取栈顶数据"<<endl; cout<<"7.判断是否空栈"<<endl; cout<<"8.判断是否满栈"<<endl; cout<<"9.栈空间使用情况"<<endl; cout<<"0.返回"<<endl; cout<<"=================="<<endl; } template <class Type> int interfacebase<Type>::userchoice(void) { int menuchoice; cout<<"请输入您的选择:"; cin>>menuchoice; choice=menuchoice; return menuchoice; } template <class Type> int interfacebase<Type>::judgechoice() { return choice; } template <class Type> returninfo interfacebase<Type>::processmenu(int menuchoice) { int size,returnvalue; Type item; switch(menuchoice)//根据用户的选择进行相应的操作 { case 1: cout<<"请输入栈的大小:"; cin>>size; seqstackonface.create(size); break; case 2: returnvalue=seqstackonface.destroy(); if(returnvalue==fail) cout<<"栈尚未建立!"<<endl; else cout<<"栈已销毁!"<<endl; break; case 3: returnvalue=seqstackonface.pushfull(); if(returnvalue==fail) cout<<"栈尚未建立!"<<endl; else if(returnvalue==overflow) cout<<"栈已满,数据无法进栈!"<<endl; else { cout<<"请输入进栈数据:"; cin>>item; seqstackonface.push(item); cout<<"数据已进栈!"<<endl; } break; case 4: returnvalue=seqstackonface.popempty(); if(returnvalue==fail) cout<<"栈尚未建立!"<<endl; else if(returnvalue==underflow) cout<<"栈已空,无数据出栈!"<<endl; else { seqstackonface.pop(item); cout<<"出栈数据:"<<item<<endl; cout<<"数据已出栈!"<<endl; } break; case 5: returnvalue=seqstackonface.display(); if(returnvalue==fail) cout<<"栈尚未建立!"<<endl; else cout<<"已遍历栈中全部数据!"<<endl; break; case 6: returnvalue=seqstackonface.getpop(item); if(returnvalue==fail) cout<<"栈尚未建立!"<<endl; else if(returnvalue==underflow) cout<<"栈已空,无栈顶数据!"<<endl; else cout<<"当前栈顶数据为:"<<item<<endl; break; case 7: returnvalue=seqstackonface.isempty(); if(returnvalue==underflow) cout<<"栈已空!"<<endl; else if(returnvalue==nounderflow) cout<<"栈未空!"<<endl; else cout<<"栈尚未建立!"<<endl; break; case 8: returnvalue=seqstackonface.isfull(); if(returnvalue==overflow) cout<<"栈已满!"<<endl; else if(returnvalue==nooverflow) cout<<"栈未满!"<<endl; else cout<<"栈尚未建立!"<<endl; break; case 9: returnvalue=seqstackonface.information(); if(returnvalue==fail) cout<<"栈尚未建立!"<<endl; else cout<<endl; break; case 0: break; default: cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl; break; } return success; } /* choiceType类的实现部分 */ template <class Type> void choiceType<Type>::clearscreen(void) { system("cls"); } template <class Type> void choiceType<Type>::showmenu(void) { cout<<"顺序栈数据类型菜单"<<endl; cout<<"=================="<<endl; cout<<"1.int"<<endl; cout<<"2.float"<<endl; cout<<"3.double"<<endl; cout<<"0.退出"<<endl; cout<<"=================="<<endl; } template <class Type> int choiceType<Type>::userchoice(void) { int menuchoice; cout<<"根据需要进栈的数据类型,"<<endl<<"请输入您的选择:"; cin>>menuchoice; return menuchoice; } template <class Type> void choiceType<Type>::processstack(int number) { int menuchoice;//定义变量,菜单选单项的选择 interfacebase<Type> interfacenow; if(number==1) interfacebase<int> interfacenow; else if(number==2) interfacebase<float> interfacenow; else if(number==3) interfacebase<double> interfacenow; else cout<<endl; interfacenow.clearscreen();//清屏 while(interfacenow.judgechoice()) { interfacenow.showmenu();//显示菜单 menuchoice=interfacenow.userchoice();//获取用户的选择 interfacenow.processmenu(menuchoice);//处理用户的选择 system("pause");//暂停 interfacenow.clearscreen();//清屏 } } template <class Type> returninfo choiceType<Type>::processmenu(int menuchoice) { switch(menuchoice)//根据用户的选择进行相应的操作 { case 1: processstack(1); break; case 2: processstack(2); break; case 3: processstack(3); break; case 0: exit(0); default: cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl; system("pause");//暂停 break; } return success; } //main.cpp #include "seqstack.cpp" #include <windows.h> /* 程序主入口 */ void main(void) { int menuchoice;//定义变量,菜单选单项的选择 choiceType<int> choiceTypenow; system("color f0");//修改屏幕的背景色和字的颜色 choiceTypenow.clearscreen();//清屏 while(1)//永真循环 { choiceTypenow.showmenu();//显示菜单 menuchoice=choiceTypenow.userchoice();//获取用户的选择 choiceTypenow.processmenu(menuchoice);//处理用户的选择 choiceTypenow.clearscreen();//清屏 } }//主函数结束 ```
spring+hibernate游标不释放问题
系统使用spring+hibernate连接池与spring事务设置如下: [code="java"] <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass"> <value>oracle.jdbc.driver.OracleDriver</value> </property> <property name="jdbcUrl"> <value>jdbc:oracle:thin:@192.168.1.106:1521:orcl</value> </property> <property name="user"> <value>wjcx</value> </property> <property name="password"> <value>wjcx</value> </property> <!--连接池中保留的最小连接数。--> <property name="minPoolSize"> <value>5</value> </property> <!--连接池中保留的最大连接数。Default: 15 --> <property name="maxPoolSize"> <value>30</value> </property> <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 --> <property name="initialPoolSize"> <value>10</value> </property> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> <property name="maxIdleTime"> <value>60</value> </property> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement"> <value>5</value> </property> <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0--> <property name="maxStatements"> <value>0</value> </property> <!--每60秒检查所有连接池中的空闲连接。Default: 0 --> <property name="idleConnectionTestPeriod"> <value>60</value> </property> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --> <property name="acquireRetryAttempts"> <value>30</value> </property> <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false--> <property name="breakAfterAcquireFailure"> <value>true</value> </property> <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable 等方法来提升连接测试的性能。Default: false --> <property name="testConnectionOnCheckout"> <value>false</value> </property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref bean="dataSource" /> </property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation"> <value>classpath:hibernate.cfg.xml</value> </property> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.cache.provider_class">com.jweb.common.cache.OSCacheProvider</prop> <prop key="hibernate.cache.use_query_cache">false</prop> </props> </property> </bean> <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean> <bean id="baseTxProxy" abstract="true" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean="transactionManager" /> </property> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="list*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="add*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="edit*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="save*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="create*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="update*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="remove*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean> [/code] dao中的代码如下 [code="java"] public List getListByArticle(ArticleModel article, String orderby, int firstResult, int maxResults,String tid) { String hql = "from UserModel"; Session session = this.getSession(); Query query = session.createQuery(hql); query.setFirstResult(firstResult); query.setMaxResults(maxResults); return query.list(); } [/code] 里面有很多如上面的方法:但系统运行一段时间后总是游标超出最大值!因为用了spring事务,service类中没有关闭连接.但不知道为什么游标老是超出,希望有人解答! [b]问题补充:[/b] 程序有些地方使用了HibernateTemplate这个,但因为存在一些复杂SQL的组装只想知道上面这种写法会不会关掉游标的. [b]问题补充:[/b] 不是使用spring的事务管理就不用关连接吗 [b]问题补充:[/b] 发现添加了session.close();系统后就会报得不到session了!象上面这种写法有什么补求的办法吗?因为代码已经写了很多了!
Linux C 调用mysql API 无法通过编译 怎么回事
``` 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include <mysql/mysql.h> 16 17 MYSQL *g_conn; // mysql 连接 18 MYSQL_RES *g_res; // mysql 记录集 19 MYSQL_ROW g_row; // 字符串数组,mysql 记录行 20 21 #define MAX_BUF_SIZE 1024 // 缓冲区最大字节数 22 23 const char *g_host_name = "localhost"; 24 const char *g_user_name = "root"; 25 const char *g_password = "root"; 26 const char *g_db_name = "test"; 27 const unsigned int g_db_port = 3306; 28 29 void print_mysql_error(const char *msg) { // 打印最后一次错误 30 if (msg) 31 printf("%s: %s\n", msg, mysql_error(g_conn)); 32 else 33 puts(mysql_error(g_conn)); 34 } 35 36 int executesql(const char * sql) { 37 /*query the database according the sql*/ 38 if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败 39 return -1; // 表示失败 40 41 return 0; // 成功执行 42 } 43 44 45 int init_mysql() { // 初始化连接 46 // init the database connection 47 g_conn = mysql_init(NULL); 48 49 /* connect the database */ 50 if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败 51 return -1; 52 53 // 是否连接已经可用 54 if (executesql("set names utf8")) // 如果失败 55 return -1; 56 57 return 0; // 返回成功 58 } 59 60 61 int main(void) { 62 puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */ 63 64 if (init_mysql()); 65 print_mysql_error(NULL); 66 67 char sql[MAX_BUF_SIZE]; 68 sprintf(sql, "INSERT INTO `test`(`name`) VALUES('testname')"); 69 70 if (executesql(sql)) 71 print_mysql_error(NULL); 72 73 if (executesql("SELECT * FROM `test`")) // 句末没有分号 74 print_mysql_error(NULL); 75 76 g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集 77 78 int iNum_rows = mysql_num_rows(g_res); // 得到记录的行数 79 int iNum_fields = mysql_num_fields(g_res); // 得到记录的列数 80 81 printf("共%d个记录,每个记录%d字段\n", iNum_rows, iNum_fields); 82 83 puts("id\tname\n"); 84 85 while ((g_row=mysql_fetch_row(g_res))) // 打印结果集 86 printf("%s\t%s\n", g_row[0], g_row[1]); // 第一,第二字段 87 88 mysql_free_result(g_res); // 释放结果集 89 90 mysql_close(g_conn); // 关闭链接 91 92 return EXIT_SUCCESS; 93 } ``` [root@localhost opt]# gcc mysql.c -lmysqlclient mysql.c:4:25: 错误:mysql/mysql.h:没有那个文件或目录 mysql.c:6: 错误:expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token mysql.c:7: 错误:expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token mysql.c:8: 错误:expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘g_row’ mysql.c: 在函数‘print_mysql_error’中: mysql.c:21: 错误:‘g_conn’未声明(在此函数内第一次使用) mysql.c:21: 错误:(即使在一个函数内多次出现,每个未声明的标识符在其 mysql.c:21: 错误:所在的函数内也只报告一次。) mysql.c: 在函数‘executesql’中: mysql.c:29: 错误:‘g_conn’未声明(在此函数内第一次使用) mysql.c: 在函数‘init_mysql’中: mysql.c:39: 错误:‘g_conn’未声明(在此函数内第一次使用) mysql.c: 在函数‘main’中: mysql.c:63: 错误:‘g_res’未声明(在此函数内第一次使用) mysql.c:63: 错误:‘g_conn’未声明(在此函数内第一次使用) mysql.c:72: 错误:‘g_row’未声明(在此函数内第一次使用)
静态链表为什么实现不了数据反转,哪里错了,具体的代码如何实现?
``` //vc6.0实现的C++版 //功能:静态链表实现线性表的基本功能 #include <iostream.h>//读入必须包含的头文件 #include <windows.h>//清屏和颜色设置需要 #include <iomanip.h> enum returninfo{success,fail,overflow,underflow,range_error};//定义返回信息清单 #define NULLP -1//静态链表的空地址模拟 const int MAXSIZE=10;//静态链表的总空间大小 class node { public: int data;//数据域 int next;//指针域 }; /* 定义一个线性表类staticlinklist */ class staticlinklist { private: node dataarray[MAXSIZE];//定义静态链表的数组 int freep,headp;//freep管理空闲空间,headp管理实际线性表空间 int count;//计数器 统计结点个数即线性表的长度 public: staticlinklist();//构造函数 ~staticlinklist();//析构函数 int getnewnode(void);//申请一个新的可用空间 returninfo create(int number);//静态链表的初始化 bool empty(void) const;//判断是否空链 int size(void) const;//求静态链表的长度 void deletenode(int position);//把某个空间地址归还给空闲空间 returninfo traverse(void);//遍历静态链表所有元素 returninfo retrieve(int position,int &item) const;//读取一个结点 returninfo replace(int position,const int &item);//修改一个结点 returninfo insert(int position,const int &item);//插入一个结点 returninfo remove(int position);//删除一个结点 returninfo invertlist(void);//静态链表所有数据反转 void showinfo(void);//显示静态链表相关信息 }; staticlinklist::staticlinklist()//构造函数 { //静态链表初始化,约定开始时地址域为从小到大顺序挂链,最后一个为NULLP(即-1) int i; for(i=0;i<MAXSIZE;i++) dataarray[i].next=i+1; dataarray[MAXSIZE-1].next=-1; freep=0;//设置空闲区的指针 count=0;//计数器清零,表明开始时没有实际数据 headp=NULLP; } staticlinklist::~staticlinklist()//析构函数 { } staticlinklist::getnewnode(void) { int tempaddress;//定义一个临时地址指针 tempaddress=freep;//保存目前可用空间的第一个地址 freep=dataarray[freep].next;//可用空间头指针后移 return tempaddress; } returninfo staticlinklist::create(int number)//静态链表的初始化 { int tempaddress,tempp; cout<<"请依次输入数据(用空格隔开):"; for(int i=1;i<=number;i++) { tempaddress=getnewnode(); cin>>dataarray[tempaddress].data; dataarray[tempaddress].next=NULLP; count++; if(i==1)//挂第一个结点 { headp=tempaddress; tempp=headp; } else//挂其他结点 { dataarray[tempp].next=tempaddress; tempp=tempaddress; } } return success; } bool staticlinklist::empty(void) const//判断是否空链 { if(headp==NULLP) return true; else return false; } int staticlinklist::size(void) const//求静态链表的长度 { return count; } void staticlinklist::deletenode(int position) { dataarray[position].next=freep; freep=position; } returninfo staticlinklist::traverse(void)//遍历静态链表中的所有元素 { int searchp;//启用搜索指针 if(empty()) return underflow;//空表的处理 searchp=headp; cout<<"静态链表中的全部数据为:Headp->";//提示显示数据开始 while(searchp!=NULLP)//循环显示所有数据 { cout<<"["<<dataarray[searchp].data; if(dataarray[searchp].next==NULLP) cout<<"|^]"; else cout<<"|-]->"; searchp=dataarray[searchp].next; } cout<<endl;//最后有一个回车的控制 return success;//本次操作成功 } returninfo staticlinklist::retrieve(int position,int &item) const//读取一个结点 { if(empty())//处理意外,空表 return underflow; if(position<=0||position>=count+1) //处理意外,范围不正确 return range_error; int searchp=headp;//定义搜索指针,初始化 for(int i=1;i<position&&searchp!=NULLP;i++)//提示:注意小于号 searchp=dataarray[searchp].next;//顺序访问方式,用循环,算法复杂度是O(n) item=dataarray[searchp].data;//返回读取的数据 return success;//本次操作成功 } returninfo staticlinklist::replace(int position,const int &item)//修改一个结点 { if(empty())//处理意外,空表 return underflow; if(position<=0||position>=count+1) //处理意外,范围不正确 return range_error; int searchp=headp;//定义搜索指针,初始化 for(int i=1;i<position&&searchp!=NULLP;i++)//提示:注意小于号 searchp=dataarray[searchp].next;//顺序访问方式,用循环,算法复杂度是O(n) dataarray[searchp].data=item;//实际修改数据的语句 return success;//本次操作成功 } returninfo staticlinklist::insert(int position,const int &item)//插入一个结点 { if(position<=0||position>=count+2) //处理意外,范围不正确 return range_error; int newnodep,searchp=headp,followp=NULLP; newnodep=getnewnode();//此处需要申请新的一个可用空间,地址赋给newnodep if(newnodep==NULLP) return overflow; dataarray[newnodep].data=item;//给数据赋值 if(position==1) { dataarray[newnodep].next=headp; headp=newnodep; count++; return success; } for(int i=1;i<position&&searchp!=NULLP;i++)//以下为查找插入位置 { followp=searchp; searchp=dataarray[searchp].next; } //以下开始修改链表,完成插入数据 dataarray[newnodep].next=dataarray[followp].next;//注意此处的次序相关性 dataarray[followp].next=newnodep; count++;//计数器加1 return success; } returninfo staticlinklist::remove(int position)//删除一个结点 { if(empty())//处理意外,空表 return underflow; if(position<=0||position>=count+1) //处理意外,范围不正确 return range_error; int searchp=headp,followp=NULLP;//这里两个指针的初始值设计一前一后 if(position==1) { searchp=headp; headp=dataarray[headp].next; deletenode(searchp);//释放该结点空间 count--;//计数器减1 return success; } for(int i=1;i<position&&searchp!=NULLP;i++) { followp=searchp; searchp=dataarray[searchp].next; } dataarray[followp].next=dataarray[searchp].next;//删除结点的实际语句 deletenode(searchp);//释放该结点 count--;//计数器减1 return success; } returninfo staticlinklist::invertlist(void)//静态链表所有数据反转 { int nowp,midp,lastp;//启用多个辅助指针 if(empty()) return underflow; nowp=dataarray[headp].next; midp=NULLP; while(nowp!=NULLP) { lastp=midp; midp=nowp; nowp=dataarray[nowp].next; dataarray[midp].next=lastp; } dataarray[headp].next=midp; return success; } void staticlinklist::showinfo(void)//显示静态链表相关信息 { int searchp; cout<<"目前静态链表总空间:"<<setw(3)<<MAXSIZE<<"地址为(0--"<<MAXSIZE-1<<")"<<endl; cout<<"其中自由空间大小为:"<<setw(3)<<MAXSIZE-count<<"编号为:"; searchp=freep; while(searchp!=NULLP) { cout<<" "<<searchp; searchp=dataarray[searchp].next; } cout<<endl; cout<<"线性表的已用空间为:"<<setw(3)<<count<<"编号为:"; searchp=headp; while(searchp!=NULLP) { cout<<" "<<searchp; searchp=dataarray[searchp].next; } cout<<endl; } /* 定义一个实现静态链表功能的菜单处理类interfacebase */ class interfacebase { private: staticlinklist listonface; public: void clearscreen(void);//清屏 void showmenu(void);//显示菜单函数 int userchoice(void);//用户的选项 returninfo processmenu(int menuchoice);//菜单函数 }; void interfacebase::clearscreen(void) { system("cls"); } void interfacebase::showmenu(void) { cout<<"静态链表基本功能菜单"<<endl; cout<<"=================="<<endl; cout<<"1.输入数据(键盘输入)"<<endl; cout<<"2.显示数据(遍历全部数据)"<<endl; cout<<"3.修改数据(要提供位置和新值)"<<endl; cout<<"4.插入数据(要提供位置和新值)"<<endl; cout<<"5.删除数据(要提供位置)"<<endl; cout<<"6.读取数据(要提供位置)"<<endl; cout<<"7.求表长度"<<endl; cout<<"8.数据反转(全部数据逆序存储)"<<endl; cout<<"9.静态链表相关信息"<<endl; cout<<"0.退出程序"<<endl; cout<<"=================="<<endl; } int interfacebase::userchoice(void) { int menuchoice; cout<<"请输入您的选择:"; cin>>menuchoice; return menuchoice; } returninfo interfacebase::processmenu(int menuchoice) { int position,item,returnvalue; switch(menuchoice)//根据用户的选择进行相应的操作 { case 1: cout<<"请问你要输入数据的个数,注意要在"<<MAXSIZE<<"个以内:"; cin>>item; if(item>MAXSIZE) cout<<"对不起,输入数据超限,操作已取消!请按任意键继续..."<<endl; else { returnvalue=listonface.create(item); if(returnvalue==success) cout<<"建立静态链表操作成功!请按任意键继续..."<<endl; } break; case 2: returnvalue=listonface.traverse(); if(returnvalue==underflow) cout<<"静态链表目前为空,没有数据可以显示!请按任意键继续..."<<endl; else cout<<"静态链表遍历操作成功!请按任意键继续..."<<endl; break; case 3: cout<<"请输入要修改数据的位置:"; cin>>position; cout<<"请输入要修改的新数据:"; cin>>item; returnvalue=listonface.replace(position,item); if(returnvalue==underflow) cout<<"对不起,静态链表已空!请按任意键继续..."<<endl; else if(returnvalue==range_error) cout<<"对不起,修改的位置超出了范围!请按任意键继续..."<<endl; else cout<<"修改操作成功!请按任意键继续..."<<endl; break; case 4: cout<<"请输入要插入数据的位置:"; cin>>position; cout<<"请输入要插入的新数据:"; cin>>item; returnvalue=listonface.insert(position,item);//注意这个位置的参数 if(returnvalue==overflow) cout<<"对不起,静态链表溢出,无法插入新数据!请按任意键继续..."<<endl; else if(returnvalue==range_error) cout<<"对不起,插入的位置超出了范围!请按任意键继续..."<<endl; else cout<<"插入操作成功!请按任意键继续..."<<endl; break; case 5: cout<<"请输入要删除数据的位置:"; cin>>position; returnvalue=listonface.remove(position);//注意这个位置的参数 if(returnvalue==underflow) cout<<"对不起,静态链表已空!请按任意键继续......"<<endl; else if(returnvalue==range_error) cout<<"对不起,删除的位置超出了范围!请按任意键继续..."<<endl; else cout<<"删除操作成功!请按任意键继续..."<<endl; break; case 6: cout<<"请输入要读取数据的位置:"; cin>>position; returnvalue=listonface.retrieve(position,item); if(returnvalue==underflow) cout<<"对不起,静态链表已空!请按任意键继续......"<<endl; else if(returnvalue==range_error) cout<<"对不起,读取的位置超出了范围!请按任意键继续..."<<endl; else cout<<"读取的数据为:"<<item<<endl<<"读取操作成功!请按任意键继续..."<<endl; break; case 7: cout<<"静态链表目前的长度为:"<<listonface.size()<<endl; cout<<"求静态链表长度操作成功!请按任意键继续..."<<endl; break; case 8: returnvalue=listonface.invertlist(); if(returnvalue==underflow) cout<<"对不起,链表已空!请按任意键继续......"<<endl; else cout<<"链表所有元素反转操作成功!请按任意键继续..."<<endl; break; case 9: listonface.showinfo(); break; case 0: exit(0); default: cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl; break; } return success; } /* 程序主入口 */ void main(void) { int menuchoice;//定义变量,菜单选单项的选择 interfacebase interfacenow; staticlinklist linklistnow; system("color f0");//修改屏幕的背景色和字的颜色 interfacenow.clearscreen();//清屏 while(1)//永真循环 { interfacenow.showmenu();//显示菜单 menuchoice=interfacenow.userchoice();//获取用户的选择 interfacenow.processmenu(menuchoice);//处理用户的选择 system("pause");//暂停 interfacenow.clearscreen();//清屏 } }//主函数结束 ```
急!!!在线等各位大神解答!!!析构函数何时被执行
我写了一个矩阵类,其中想要实现乘法的重载,下面是我的具体实现: //重载矩阵与矩阵乘法运算 CMatrix CMatrix::operator *(CMatrix &M2) { CMatrix temp; temp.initialize(m_row,M2.m_col);//矩阵初始化 for(int i=0; i<m_row; i++) { for(int j = 0; j < M2.m_col; j++){ for(int k = 0; k < m_col; k++){ temp.m_pData[i][j] = temp.m_pData[i][j] + m_pData[i][k] * M2.m_pData[k][j]; } } } temp.print(); return temp; } 在上面的代码中,我定义了一个temp临时变量,因为temp在初始化的时候已经分配了一定的空间,我希望能够在执行完乘法之后把这部分空间释放,所以就定义了一个析构函数,如下: CMatrix::~CMatrix() { for(int _i=0;_i<m_row;_i++) delete []m_pData[_i]; delete []m_pData; } 但是输出的时候又错误,我想问一下这个析构函数是在执行return temp之后执行的还是再此之前就执行了啊~ 为什么return返回的矩阵式空的啊~ //动态创建二维数组 #define matrix_allocate(m,w,h,TYPE) { m=new TYPE*[h + 1];for(int _i=0;_i<h;_i++){int t=_i-1;m[_i]=new TYPE[w +1];if(!m[_i]) _i = t;}} //动态删除二维数组 #define matrix_delete(m,w,h) { for(int _i=0;_i<h;_i++) delete[]m[_i]; delete[]m;} //矩阵初始化函数 bool CMatrix::initialize(int r,int c) { m_row=r; m_col=c; matrix_allocate(m_pData,m_col,m_row,double); m_pData[0][0] = 123; for(int i=0; i < m_row; i++) { for(int j = 0; j < m_col; j++) m_pData[i][j] = 0; } return true; }
为什么键盘输入字符串和文件导入字符串都有错?错误应该怎么改?
``` #include <iostream.h> #include <windows.h> #include <string> #include<fstream> using namespace std; class Stack;//类Stack的声明 /* 定义一个链栈结点类Stacknode */ class Stacknode { friend class Stack;//申请友元类 private: Stacknode(Stacknode *nextp=NULL);//构造函数 Stacknode(char &newdata,Stacknode *nextp=NULL);//构造函数 int data;//数据元素 Stacknode *next;//递归定义指向后继结点的指针 }; /* Stacknode的实现部分 */ Stacknode::Stacknode(Stacknode *nextp)//构造函数 { next=nextp; } Stacknode::Stacknode(char &newdata,Stacknode *nextp)//构造函数 { data=newdata; next=nextp; } //结点类Stacknode的定义结束 /* 定义一个链栈类Stack */ class Stack { public: Stack();//创建一个空栈 ~Stack();//回收一个栈 void clear();//销毁一个栈 bool empty() const;//确定栈是否已空 bool push(char &item);//把数据压进栈 bool pop();//出栈 bool pop(char &item);//把数据弹出栈,返回 bool top(char &item) const;//取出栈顶元素 private: Stacknode *newnode(Stacknode *nextp=NULL); Stacknode *newnode(char &item,Stacknode *nextp=NULL);//创建新的结点 Stacknode *Stacktop; int Stacklength; }; /* Stack的实现部分 */ Stacknode *Stack::newnode(Stacknode *nextp)//创建新的结点,不带数据 { return new Stacknode(nextp); } Stacknode *Stack::newnode(char &item,Stacknode *nextp)//创建新的结点,数据域赋值 { return new Stacknode(item,nextp); } //以下为栈类Stack的函数定义 Stack::Stack()//创建一个空栈 { Stacktop=newnode();//创建一个栈顶指针初始化,相当于Stacktop=NULL;本链表没有用头结点 Stacklength=0; } Stack::~Stack()//回收一个栈 { clear(); delete Stacktop;//释放栈底 } void Stack::clear()//销毁一个栈 { while(pop());//不停地出栈,而每次释放空间在出栈函数中完成 } bool Stack::empty() const//确定栈是否已空 { return Stacklength<=0?true:false; } bool Stack::push(char &item)//数据进栈 { Stacknode *newnodep;//定义指针newnodep,准备指向申请的新结点 newnodep=newnode(item,Stacktop);//申请新结点,把数据存入,把指针域指向头指针 if(!newnodep)//如果没有申请到空间,返回失败 return false; Stacktop=newnodep;//改链,完成进栈 Stacklength++;//栈的长度增加 return true;//本次操作成功 } bool Stack::pop()//出栈,不要栈顶数据 { Stacknode *usednodep;//定义指针usednodep,准备指向出栈的结点 if(!empty())//判断是否栈空 { usednodep=Stacktop;//指向出栈的结点 Stacktop=Stacktop->next;//栈顶指针后移 delete usednodep;//释放空间 Stacklength--;//栈的长度减少 return true;//本次操作成功 } return false;//否则本次操作失败 } bool Stack::pop(char &item)//出栈,把栈顶数据弹返回去 { Stacknode *usednodep;//定义指针usednodep,准备指向出栈的结点 if(!empty())//判断是否栈空 { usednodep=Stacktop;//指向出栈的结点 Stacktop=Stacktop->next;//栈顶指针后移 item=usednodep->data;//把数据保留下来,返回去 delete usednodep;//释放空间 Stacklength--;//栈的长度减少 return true;//本次操作成功 } return false;//否则本次操作失败 } bool Stack::top(char &item) const//取出栈顶数据返回去 { if(!empty())//如果栈不空,记录当前栈顶元素 { item=Stacktop->data;//通过item返回去 return true;//本次操作成功 } return false;//否则本次操作失败 } /* 定义一个功能类SymbolMatching */ class SymbolMatching { private: Stack *stack; public: SymbolMatching();//构造函数 ~SymbolMatching();//析构函数 bool manualinputdatabase(char *database);//人工输入数据信息 bool fileguidedatabase(char *filename);//文件导入数据信息 }; SymbolMatching::SymbolMatching()//构造函数 { stack=new Stack; } SymbolMatching::~SymbolMatching()//析构函数 { delete stack; } bool SymbolMatching::manualinputdatabase(char *database)//人工输入数据信息 { int i=0; char match,symbol; bool is_match=true; while(database[i]!='\0'&&is_match) { symbol=database[i++]; if(symbol=='('||symbol=='{'||symbol=='[') stack->push(symbol);//入栈 else if(symbol==')'||symbol=='}'||symbol==']') { if(stack->empty()) { if(database[i+1]!='\0') cout<<"右边符号多于左边符号!"<<endl; else cout<<"符号"<<symbol<<"无法找到与之匹配的符号!"<<endl; is_match=false; } else { stack->top(match); stack->pop();//出栈 is_match=(symbol==')'&&match=='('||symbol==']'&&match=='['||symbol=='}'&&match=='{'); if(!is_match) cout<<"符号"<<match<<"和"<<symbol<<"不匹配!"<<endl; } } } if(is_match) { if(!stack->empty())//栈不为空 { cout<<"左边符号多于右边符号!"<<endl; is_match=false; } else cout<<"左右符号匹配次序正确!"<<endl; } stack->clear(); return is_match; } bool SymbolMatching::fileguidedatabase(char *filename)//文件导入数据信息 { int i=0; char match,symbol; bool is_match=true; while(filename[i]!='\0'&&is_match) { symbol=filename[i++]; if(symbol=='('||symbol=='{'||symbol=='[') stack->push(symbol);//入栈 else if(symbol==')'||symbol=='}'||symbol==']') { if(stack->empty()) { if(filename[i+1]!='\0') cout<<"右边符号多于左边符号!"<<endl; else cout<<"符号"<<symbol<<"无法找到与之匹配的符号!"<<endl; is_match=false; } else { stack->top(match); stack->pop();//出栈 is_match=(symbol==')'&&match=='('||symbol==']'&&match=='['||symbol=='}'&&match=='{'); if(!is_match) cout<<"符号"<<match<<"和"<<symbol<<"不匹配!"<<endl; } } } if(is_match) { if(!stack->empty())//栈不为空 { cout<<"左边符号多于右边符号!"<<endl; is_match=false; } else cout<<"左右符号匹配次序正确!"<<endl; } stack->clear(); return is_match; } /* 定义一个实现链栈功能的菜单处理类interfacebase */ class interfacebase { private: SymbolMatching SymbolMatchingonface; public: void clearscreen(void);//清屏 void showmenu(void);//显示菜单函数 int userchoice(void);//用户的选项 void processmenu(int menuchoice);//菜单函数 }; /* interfacebase类的实现部分 */ void interfacebase::clearscreen(void) { system("cls"); } void interfacebase::showmenu(void) { cout<<"链式堆栈实现括号匹配判断的功能菜单"<<endl; cout<<"=================================="<<endl; cout<<"1.人工输入数据信息"<<endl; cout<<"2.文件导入数据信息"<<endl; cout<<"0.退出"<<endl; cout<<"=================================="<<endl; } int interfacebase::userchoice(void) { int menuchoice; cout<<"请输入您的选择:"; cin>>menuchoice; return menuchoice; } void interfacebase::processmenu(int menuchoice) { switch(menuchoice)//根据用户的选择进行相应的操作 { case 1: { string str; char temp; cout<<"输入字符串,按回车键结束输入:"<<endl; while((temp=cin.get())!='\n') { str +=temp; } const int LEN =str.length(); char* database = new char[LEN];//根据输入字符串的长度,创建字符数组 for(int i = 0;i<LEN;i++) //将字符串保存到字符数组中 { database[i]=str[i]; } SymbolMatchingonface.manualinputdatabase(database); delete database; } break; case 2: { ifstream in("data.txt"); char data,j,*filename=new char[100]; int num=0; while(!in.eof()) { in>>data; filename[num]=data; cout<<filename[num]; num++; } cout<<endl; SymbolMatchingonface.fileguidedatabase(filename); delete filename; } break; case 0: exit(0); default: cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl; break; } } /* 程序主入口 */ void main(void) { int menuchoice;//定义变量,菜单选单项的选择 interfacebase interfacebasenow; system("color f0");//修改屏幕的背景色和字的颜色 interfacebasenow.clearscreen();//清屏 while(1)//永真循环 { interfacebasenow.showmenu();//显示菜单 menuchoice=interfacebasenow.userchoice();//获取用户的选择 interfacebasenow.processmenu(menuchoice);//处理用户的选择 system("pause"); interfacebasenow.clearscreen();//清屏 } }//主函数结束 ```
爬虫福利二 之 妹子图网MM批量下载
爬虫福利一:27报网MM批量下载    点击 看了本文,相信大家对爬虫一定会产生强烈的兴趣,激励自己去学习爬虫,在这里提前祝:大家学有所成! 目标网站:妹子图网 环境:Python3.x 相关第三方模块:requests、beautifulsoup4 Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运行即可。
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入 假设现有4个人...
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 欢迎 改进 留言。 演示地点跳到演示地点 html代码如下`&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;music&lt;/title&gt; &lt;meta charset="utf-8"&gt
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。 1. for - else 什么?不是 if 和 else 才
数据库优化 - SQL优化
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。 判断问题SQL 判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象 CPU消耗严重 IO等待严重 页面响应时间过长
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 c/c++ 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7
通俗易懂地给女朋友讲:线程池的内部原理
餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!” 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不动了,升迁也无望,于是拿着手里
经典算法(5)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
JDK12 Collectors.teeing 你真的需要了解一下
前言 在 Java 12 里面有个非常好用但在官方 JEP 没有公布的功能,因为它只是 Collector 中的一个小改动,它的作用是 merge 两个 collector 的结果,这句话显得很抽象,老规矩,我们先来看个图(这真是一个不和谐的图????): 管道改造经常会用这个小东西,通常我们叫它「三通」,它的主要作用就是将 downstream1 和 downstre...
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
SQL-小白最佳入门sql查询一
不要偷偷的查询我的个人资料,即使你再喜欢我,也不要这样,真的不好;
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
【图解经典算法题】如何用一行代码解决约瑟夫环问题
约瑟夫环问题算是很经典的题了,估计大家都听说过,然后我就在一次笔试中遇到了,下面我就用 3 种方法来详细讲解一下这道题,最后一种方法学了之后保证让你可以让你装逼。 问题描述:编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3…这样依次报),数到 m 的 士兵会被杀死出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。 1、方...
致 Python 初学者
欢迎来到“Python进阶”专栏!来到这里的每一位同学,应该大致上学习了很多 Python 的基础知识,正在努力成长的过程中。在此期间,一定遇到了很多的困惑,对未来的学习方向感到迷茫。我非常理解你们所面临的处境。我从2007年开始接触 python 这门编程语言,从2009年开始单一使用 python 应对所有的开发工作,直至今天。回顾自己的学习过程,也曾经遇到过无数的困难,也曾经迷茫过、困惑过。开办这个专栏,正是为了帮助像我当年一样困惑的 Python 初学者走出困境、快速成长。希望我的经验能真正帮到你
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
程序员:我终于知道post和get的区别
是一个老生常谈的话题,然而随着不断的学习,对于以前的认识有很多误区,所以还是需要不断地总结的,学而时习之,不亦说乎
GitHub标星近1万:只需5秒音源,这个网络就能实时“克隆”你的声音
作者 | Google团队 译者 | 凯隐 编辑 | Jane 出品 | AI科技大本营(ID:rgznai100) 本文中,Google 团队提出了一种文本语音合成(text to speech)神经系统,能通过少量样本学习到多个不同说话者(speaker)的语音特征,并合成他们的讲话音频。此外,对于训练时网络没有接触过的说话者,也能在不重新训练的情况下,仅通过未知...
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU...
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1...
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员...
网易云6亿用户音乐推荐算法
网易云音乐是音乐爱好者的集聚地,云音乐推荐系统致力于通过 AI 算法的落地,实现用户千人千面的个性化推荐,为用户带来不一样的听歌体验。 本次分享重点介绍 AI 算法在音乐推荐中的应用实践,以及在算法落地过程中遇到的挑战和解决方案。 将从如下两个部分展开: AI算法在音乐推荐中的应用 音乐场景下的 AI 思考 从 2013 年 4 月正式上线至今,网易云音乐平台持续提供着:乐屏社区、UGC...
【技巧总结】位运算装逼指南
位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。 判断奇偶数 判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下...
【管理系统课程设计】美少女手把手教你后台管理
【文章后台管理系统】URL设计与建模分析+项目源码+运行界面 栏目管理、文章列表、用户管理、角色管理、权限管理模块(文章最后附有源码) 1. 这是一个什么系统? 1.1 学习后台管理系统的原因 随着时代的变迁,现如今各大云服务平台横空出世,市面上有许多如学生信息系统、图书阅读系统、停车场管理系统等的管理系统,而本人家里就有人在用烟草销售系统,直接在网上完成挑选、购买与提交收货点,方便又快捷。 试想,若没有烟草销售系统,本人家人想要购买烟草,还要独自前往药...
4G EPS 第四代移动通信系统
目录 文章目录目录4G 与 LTE/EPCLTE/EPC 的架构E-UTRANE-UTRAN 协议栈eNodeBEPCMMES-GWP-GWHSSLTE/EPC 协议栈概览 4G 与 LTE/EPC 4G,即第四代移动通信系统,提供了 3G 不能满足的无线网络宽带化,主要提供数据(上网)业务。而 LTE(Long Term Evolution,长期演进技术)是电信领域用于手机及数据终端的高速无线通...
相关热词 c# 二进制截断字符串 c#实现窗体设计器 c#检测是否为微信 c# plc s1200 c#里氏转换原则 c# 主界面 c# do loop c#存为组套 模板 c# 停掉协程 c# rgb 读取图片
立即提问