摘要: 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 閱讀(243) |
評論 (0) |
編輯 收藏
摘要: 一言難盡啊。。。最近發現一個怪現象。。。浙大門口斑馬線的紅綠燈是只顯示紅燈的。。。綠燈的時候是全黑的。。。難道是培養耐心?。。ink.cpp文件(這個文件主要用來測試鏈表增刪查改函數):
#include<stdio.h>#include"link.h"int main(){ int i; &n...
閱讀全文
posted @
2010-10-31 20:05 jince 閱讀(253) |
評論 (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 閱讀(692) |
評論 (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 閱讀(248) |
評論 (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 閱讀(164) |
評論 (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 閱讀(638) |
評論 (0) |
編輯 收藏
在家里一直投簡歷,面試,等待?。?br>今天又去了,總結一下心得:
1)在家沒事學點東西,不要求精但是要廣。。
2)一些基礎的東西要記住,不要像我連blog的地址也記不住。。(今天很尷尬?。。。?br> 3)以前學過的東西最好能夠記錄下來可以溫習一下,說不定哪天就能用上。。。
4)多出去走走,不期望撿到金子,但是可以給你創造的靈感(我去面試過很多公司了,感覺很不一樣)。。。
posted @
2010-10-20 11:01 jince 閱讀(256) |
評論 (0) |
編輯 收藏
哈哈哈哈哈哈