摘要: File.cpp函数定义文件:
#include<stdlib.h>#include<stdio.h>#include"File_Head.h"int studentnum=2;student stud[SIZE];void File_fputc_fgetc(){ FILE ...
阅读全文
posted @
2010-11-01 22:25 jince 阅读(224) |
评论 (0) |
编辑 收藏
摘要: 一言难尽啊。。。最近发现一个怪现象。。。浙大门口斑马线的红绿灯是只显示红灯的。。。绿灯的时候是全黑的。。。难道是培养耐心!!!Link.cpp文件(这个文件主要用来测试链表增删查改函数):
#include<stdio.h>#include"link.h"int main(){ int i; &n...
阅读全文
posted @
2010-10-31 20:05 jince 阅读(238) |
评论 (0) |
编辑 收藏
值传递, 指针传递?
这几天在学习C过程中,在使用指针作为函数参数传递的时候出现了问题,根本不知道从何得解:源代码如下:
createNode(BinNode *tree,char *p)
{
tree = (BinNode *) malloc(sizeof(BinNode));
tree->data = *p;
}
该代码段的意图是通过一个函数创建一个二叉树的节点,然而在,调用该函数后,试图访问该节点结构体的成员时候,却发生了内存访问错误,到底问题出在哪儿呢?
一直不明白指针作为函数参数传值的机制,翻开林锐的《高质量C/C++编程指南》,找到了答案。
[如果函数的参数是一个指针,不要指望用该指针去申请动态内存]
原来问题出在C编译器原理上:编译器总是要为函数的每个参数制作临时副本,指针参数tree的副本是 _tree,编译器使 _tree = tree。如果函数体内的程序修改了_tree的内容,就导致参数tree的内容作相应的修改。这就是指针可以用作输出参数的原因。
即上面的函数代码经过编译后成为:
createNode(BinNode *tree,char *p)
{
BinNode *_tree;
_tree = tree;
_tree = (BinNode *) malloc(sizeof(BinNode));
_tree->data = *p;
}
如果没有
_tree = (BinNode *) malloc(sizeof(BinNode));
这个语句,在函数体内修改了_tree的内容,将会导致参数tree的内容作相应的修改,因为它们指向相同的内存地址。而
_tree = (BinNode *) malloc(sizeof(BinNode));
这个句,系统重新分配内存给_tree指针,_tree指针指向了系统分配的新地址,函数体内修改的只是_tree的内容,对原tree所指的地址的内容没有任何影响。因此,函数的参数是一个指针时,不要在函数体内部改变指针所指的地址,那样毫无作用,需要修改的只能是指针所指向的内容。即应当把指针当作常量。
如果非要使用函数指针来申请内存空间,那么需要使用指向指针的指针
createNode(BinNode **tree,char *p)
{
*tree = (BinNode *) malloc(sizeof(BinNode));
}
上面的是林锐的说法,目前来说不知道怎么去理解,不过可以有另外的方案,通过函数返回值传递动态内存:
BinNode *createNode()
{
BinNode *tree;
tree = (BinNode *) malloc(sizeof(BinNode));
return tree;
}
这个倒还说得过去,因为函数返回的是一个地址的值,该地址就是申请的内存块首地址。但是,这个容易和另外的一个忠告相混绕
[不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡]
这里区分一下静态内存,栈内存和动态分配的内存(堆内存)的区别:
(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
因此,试图返回一个栈上分配的内存将会引发未知错误
char *GetString(void)
{
char p[] = "hello world";
return p; // 编译器将提出警告
}
p是在栈上分配的内存,函数结束后将会自动释放,p指向的内存区域内容不是"hello world",而是未知的内容。
如果是返回静态存储的内存呢:
char *GetString(void)
{
char *p = "hello world";
return p;
}
这里“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString,它返回的始终是同一个“只读”的内存块。
[参考:林锐《高质量C/C++编程指南》]
posted @
2010-10-31 19:32 jince 阅读(680) |
评论 (0) |
编辑 收藏
1、结构体内存分配按照最严格的数据类型分配
例:
struct student
{
int num;
char c;
};
struct student stu1,stu2,stus[20],*ps;
内存分配的时候按照int型分配(地址按照能被4整除),成员的排列次序不同,内存分配不同。。。
另外编译器影响结构体的内存分配。。最有效的方式(sizeof(student))计算字节数。。
struct student
{
int num;
char name[20];
}stu1,stu2,stus[20],*ps;
struct
{
int num;
char name[20];
}stu1;//没有结构体名称,所以不能在其他地方定义变量。。
无语。。
2、结构体可以嵌套,但是结构体不能嵌套自身。。。
Linux定义: Linux is not unix!!!
struct student li,zhang={"zhang",1,2,3};
li=zhang;//结构体可以直接相等。。当然两个不同的结构体变量不能直接赋值。。。
li={"li",1,2,3};//错。。
if(stu1==stu2);//错。。
struct student
{
int age;
char *name;
}*ps;
ps=(struct student *)malloc(sizeof(struct student));
(*ps).age=30;
(*ps).name=(char *)malloc(20);
strcpy((*ps).name,"jince");
free((*ps).name);//释放顺序。。。
free(ps);
3、海贼王更新。。。
4、typedef int intage;
typedef double real;
#define int intage;
#define char* string;
string s1,s2;//这时候存在问题。。。 char* s1,s2;。。。
typedef char* string;
string s1,s2;//OK
typedef int bool;
struct Rec
{
...
};
typedef struct Rec Rec;
Rec jince;
指针变量统一占4个字节。。。
指针数组。。。解决链表问题??
前一个节点记录后一个节点的地址。。。。
typedef struct Link
{
int a;
char c;
Link *next;
}Link;
5、#ifndef LIST_H //预编译命令。。。对于已经定义的LIST_H不进行编译。。
posted @
2010-10-30 20:31 jince 阅读(234) |
评论 (0) |
编辑 收藏
str_cat()函数自定义:
#include<stdio.h>
char * str_cat(char *s1,char *s2)
{
char *s;
s=(char *)malloc(strlen(s1)+strlen(s2)+1);
strcpy(s,s1);
strcpy(s+strlen(s1),s2);
return s;
}
int main()
{
char s1[10],s2[10];
char *s3;
while(scanf("%s %s",s1,s2)!=EOF)
{
s3=str_cat(s1,s2);
puts(s3);
}
return 0;
}
报数题:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int s[100];
int n,m,i,j,temp,k,g;
while(scanf("%d%d%d",&n,&m,&g)!=EOF)//n为总人数,m为开始报数人序号,g为报数循环数
{
int j=m;
memset(s,0,sizeof(s));
for(i=1;i<n;i++)
{
temp=0;
while(temp<g)
{
if(s[j]==0)
temp++;
if(temp==g)
break;
j++;
if(j>n)
{
for(k=1;k<=n;k++)
if(s[k]==0)
{
j=k;
break;
}
}
}
s[j]=1;
// printf("%d\n",j);
for(k=1;k<=n;k++)
{
printf("%d ",s[k]);
}
printf("\n");
}
for(k=1;k<=n;k++)
{
if(s[k]==0)
{
printf("最后留下同学序号:%d\n",k);
break;
}
}
}
return 0;
}
一个五位数*4=这个数的逆序题:
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void Numtostring(int num,char s[]) //自定义数字转换成字符串函数
{
int temp,i=0;
// char *s;
// s=(char *)malloc(500);
//char s[500];
while(num!=0)
{
temp=num%10;
s[i]=temp+48;
i++;
num=num/10;
}
s[i]='\0';
strrev(s);
}
int main()
{
int i;
int num;
char s[500],s0[500];
for(i=10000;i<100000;i++)
{
num=i*4;
//printf("%d\n",num);
Numtostring(i,s);
Numtostring(num,s0);
// printf("%s\n",s);
strrev(s0);
if(strcmp(s,s0)==0)
printf("%d*4=%s\n",i,strrev(s));
}
return 0;
}
posted @
2010-10-29 20:28 jince 阅读(153) |
评论 (0) |
编辑 收藏
今天培训的老师让我们做的题目。。。
我写了几个(不多说了比较累直接上代码了):
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
void Numtostring(int num,char s[]) //自定义数字转换成字符串函数
{
int temp,i=0;
// char *s;
// s=(char *)malloc(500);
//char s[500];
while(num!=0)
{
temp=num%10;
s[i]=temp+48;
i++;
num=num/10;
}
s[i]='\0';
strrev(s);
}
int NumberTest0(int num) //数字逆序,返回逆序值
{
int temp;
int n,i;
int num0=0;
n=log10(num);
printf("n=%d\n",n);
for(i=n;i>=0;i--)
{
temp=num%10;
num=num/10;
num0+=temp*pow(10,i);
printf("num0=%d\n",num0);
}
return num0;
}
int StringTest(int num)//回文判断,字符串逆转思路
{
char s[500],s1[500];
Numtostring(num,s);//数字转换成字符串函数
puts(s);
strcpy(s1,s);
strrev(s1);
if(strcmp(s1,s)==0)
printf("Yes\n");
else
printf("No\n");
return 0;
}
int NumberTest1(int n)//回文判断 老师解题思路 听说是大神级的人物写的。。。
{
int temp=0;
int m=n;
while(n)
{
temp=temp*10;
temp+=n%10;
n=n/10;
}
printf("%d\n",temp);
if(temp==m)
printf("Yes\n");
else
printf("No\n");
return 0;
}
int main()
{
int num,num0;
// long n;
char s[500];
while(scanf("%d",&num)!=EOF)
{
/**//*num0=Test(num);
printf("%d\n",num0);
if(num0==num)
printf("Yes\n");
else
printf("No\n");*/
// Numtostring(num,s);
// puts(s);
// StringTest(num);
NumberTest1(num);
}
return 0;
}
posted @
2010-10-29 19:57 jince 阅读(623) |
评论 (0) |
编辑 收藏
在家里一直投简历,面试,等待!!
今天又去了,总结一下心得:
1)在家没事学点东西,不要求精但是要广。。
2)一些基础的东西要记住,不要像我连blog的地址也记不住。。(今天很尴尬!!!)
3)以前学过的东西最好能够记录下来可以温习一下,说不定哪天就能用上。。。
4)多出去走走,不期望捡到金子,但是可以给你创造的灵感(我去面试过很多公司了,感觉很不一样)。。。
posted @
2010-10-20 11:01 jince 阅读(243) |
评论 (0) |
编辑 收藏
哈哈哈哈哈哈