PDA

查看完整版本 : 有人會C語言嗎?


哈啦
2014-01-29, 07:06 PM
版上高手很多,不知哪位會C語言的?
有些很粗淺的程式問題想請教一下?:bow

http://q.to/error1

不知為何中間有錯誤?這是按照一本書上的範例一字不錯的抄上去的。

yumi
2014-01-29, 08:36 PM
把第5行int myfunc(void);删掉
把18-21行拷到原第5行的位置,再试试。

哈啦
2014-01-29, 08:50 PM
把第5行int myfunc(void);删掉
把18-21行拷到原第5行的位置,再试试。

~yes ~yes

我把第五行的int myfunc(void);删掉之後,其它不變就成功了!

請問怎會如此呢?我這是按照書上抄的。為何按原來會說 too many arguments?

yumi
2014-01-29, 09:04 PM
这应该和不同的编译器有关。某些编译器不修改也能通过。
myfunc(void)应该是没有参数的。后来,调用myfunc时用了一个参数。所以是 too many arguments 参数太多了

哈啦
2014-01-29, 09:15 PM
myfunc(void)应该是没有参数的。后来,调用myfunc时用了一个参数。所以是 too many arguments 参数太多了

yes ,果然如你所言,把void拿掉也可以了。thanks!!:bow

你是學這方面的嗎?以後還要多請教一下。

哈啦
2014-02-05, 05:38 PM
有人能幫我解說一下,裡面我註釋中提到的那個問題嗎?
唔該。

http://codepad.org/jEgTb9wr

lukawa
2014-02-05, 07:31 PM
迴圈的x 是 1~10
但是C的陣列是0開始
所以要 x-1
也就是0~9
不確定你得問題是不是這個:)

哈啦
2014-02-05, 08:53 PM
迴圈的x 是 1~10
但是C的陣列是0開始
所以要 x-1
也就是0~9
不確定你得問題是不是這個:)

這個我知道,只是說這整個程式的邏輯,為何會如此寫?如何知道要加這一句 for(x=1;x<11;x++) sqrs[x-1]=x*x*x; ?

thanks,

yumi
2014-02-05, 09:24 PM
这一句应该是计算、赋值,就是将1的立方的结果放进sqrs[0]、将2的立方的结果放进sqrs[1]、……、将10的立方的结果放进sqrs[9]。

哈啦
2014-02-05, 09:33 PM
这一句应该是计算、赋值,就是将1的立方的结果放进sqrs[0]、将2的立方的结果放进sqrs[1]、……、将10的立方的结果放进sqrs[9]。

thanks.

其實我是能理解全部程式的用意,只是要我自己從頭開始,就無法在腦中跳出這一句,自然不會成功。我現在想知道的就是這個程式的思考邏輯的過程,呵。

but 沒關係,這都是學習的過程,也許學久了就知道了。~cici

yumi
2014-02-05, 09:49 PM
如果出题的人要求打印1-10的立方的话,有很多种写法可以达到目的。当然,不可少的是计算赋值、然后打印了。

#include <stdio.h>
int main(void)
{
int sqrs[11];
int x;
for(x=1;x<11;x++)
{sqrs[x]=x*x*x; printf("%d\n",sqrs[x]);}
return 0;
}

哈啦
2014-02-05, 09:56 PM
#include <stdio.h>
int main(void)
{
int sqrs[11];
int x;
for(x=1;x<11;x++)
{sqrs[x]=x*x*x; printf("%d\n",sqrs[x]);}
return 0;
}

~yes 你這個程式的邏輯我就完全能懂了,thanks!!

但請教一下,陣列不是都要從sqrs[0]開始嗎?雖然你這程式打印出來是正確的,我也都能理解,只是為何不是從[0](如前面那個程式是以sqrs[x-1]來達到以0開始的作用)開始?

yumi
2014-02-05, 10:08 PM
区别就在于:
原先的程序,定义了int sqrs[10];,只是从sqrs[0]到sqrs[9]这10个单元,没有sqrs[10],所以在计算10个立方值时,无法把10的立方放进sqrs[10],只好采取错位的方式,把x的立方放在sqrs[x-1]的位置。
而我后来定义的是int sqrs[11];从sqrs[0]定义到了sqrs[10],在计算10个立方值时,可以把10的立方放进sqrs[10],直接把x的立方放进sqrs[x],这样更好理解、符合人的习惯。当然这样,sqrs[0]就闲置无用了,浪费了4个字节的内存。但在今天,已经没有必要在意4个字节内存了。怎么容易理解就怎么写呗。

哈啦
2014-02-05, 10:11 PM
当然这样,sqrs[0]就闲置无用了,浪费了4个字节的内存。但在今天,已经没有必要在意4个字节内存了。怎么容易理解就怎么写呗。


原來如此,所以陣列以0為起始,但我們未必非得凡事都從它的0開始,頂多就是浪費了之前配置的一些memory了,是這樣嗎?:bow 又長知識了。~yes

lukawa
2014-02-06, 09:19 AM
其實我一直覺得學程式有些習慣需要內化,就像是array由0開始,這跟我們一般的習慣
就不大一樣,或者說

x = x +1

如果以數學來說,應該沒有一個值,會符合上面的運算式的^^!!
所以上面的"equal" 應該是解釋為 "assign"
這寫程式寫久了就會內化成習慣,但是剛開始學程式的人,可能都會有類似的疑問
另外站長的疑問,比較像是把題目跟答案倒著看了,先想著題目,自然就會有這樣的答案出來:)

哈啦
2014-02-06, 12:37 PM
其實我一直覺得學程式有些習慣需要內化,就像是array由0開始,這跟我們一般的習慣
就不大一樣,或者說

x = x +1

如果以數學來說,應該沒有一個值,會符合上面的運算式的^^!!
所以上面的"equal" 應該是解釋為 "assign"
這寫程式寫久了就會內化成習慣,但是剛開始學程式的人,可能都會有類似的疑問
另外站長的疑問,比較像是把題目跟答案倒著看了,先想著題目,自然就會有這樣的答案出來:)

~yes 所言極是。

sakillll
2014-02-06, 12:52 PM
哈大在學寫程式?:shorto:shorto

哈啦
2014-02-06, 01:02 PM
哈大在學寫程式?:shorto:shorto

對,自己看一點,主要是年紀大了,為了防止腦袋退化:shorto,兼學點有用的東西。~cici

sakillll
2014-02-06, 01:36 PM
對,自己看一點,主要是年紀大了,為了防止腦袋退化:shorto,兼學點有用的東西。~cici

趕快做出成品給大家玩玩:applaud

哈啦
2014-02-06, 04:38 PM
繼續請教高手:
以下的式子是要把陣列a1的數值複製給陣列a2。

課本上的標準寫法如下:
#include <stdio.h>

int main(void)
{

int i,a1[10],a2[10];

for(i=1;i<11;i++) a1[i-1]=i;
for(i=0;i<10;i++) a2[i]=a1[i];
for(i=0;i<10;i++) printf("%d\n",a2[i]);

return 0;
}

而我看了yumi剛才的寫法後獲得啟發,也改寫為如下:
#include <stdio.h>

int main(void)
{

int i,a1[10],a2[10];

for(i=1;i<11;i++){
a1[i-1]=i;
a2[i]=a1[i-1];
printf("%d\n",a2[i]);}
return 0;
}

這二者跑出來的結果都是一樣的,看似我改寫的也頗為正確,不過我自己懷疑第二個式子中有不可見的錯誤存在?(編譯器未發出警告),就是紅字部份的a2[i]=a1[i-1],它等於是a2陣列的第一個是從a2[1]啟始,前面的a2[0]並未被賦值,這一點不打緊,但由於a2[10]之前已宣告為只有十個元素,因此這裡最後會一路被加到a[10]而這是第十一個元素,超過了原先只能有十個元素的宣告。看網路上說,C/C++ 為了執行效率,並不會自動檢查陣列索引值是否超過陣列邊界,
我們要自己寫程式來確保不會越界。一旦越界,將導致無法預期的後果。
因此我的疑問如下,我這改寫的式子雖然答案是ok的,但它式子本身應是錯的,是嗎?
其次,陣列元素超過原來宣告的數目,未必一定會造成錯誤,就是說有可能有影響也有可能沒影響,所謂的導致無法預期的後果?是這樣嗎?
我有試著把a2[i]=a1[i-1]改成
a2[i-1]=a1[i-1] 或者
a2[i]=a1[i]
結果答案出來全都亂七八糟。
請問正確的改寫法該是什麼呢?

唔該先。:bow?:teeth

yumi
2014-02-06, 08:21 PM
正确的写法其实就是:
#include <stdio.h>

int main(void)
{

int i,a1[10],a2[10];

for(i=1;i<11;i++){
a1[i-1]=i;
a2[i-1]=a1[i-1];
printf("%d\n",a2[i-1]);}
return 0;
}

哈啦
2014-02-06, 08:24 PM
正确的写法其实就是:
#include <stdio.h>

int main(void)
{

int i,a1[10],a2[10];

for(i=1;i<11;i++){
a1[i-1]=i;
a2[i-1]=a1[i-1];
printf("%d\n",a2[i-1]);}
return 0;
}


~yes~yes:bow

many thanks!

lukawa
2014-02-06, 10:09 PM
其實哈大已經開始碰觸到C(C++)"精華的地方了",其實也就是討厭的地方
也就是記憶體管理跟指標,今天a1 a2 兩個陣列其實都是指標pointer
C語言強大在這個地方,失敗也在這個地方,我們透過指標可以快速輕易的
存取到記憶體中個個位子,但是並不是每個位子,你都是可以存取的,所以要非常的小心
你得寫法事實上已經超過這個陣列的範圍了,但是他在你得電腦上跑也許沒有問題
換個環境可能問題就會產生,這是非常討厭的,因為你有時候很難抓到這種BUG
但是也是因為這樣方便的存取記憶體的方式,所以C寫出來的程式非常的有效率,

哈啦
2014-02-06, 10:32 PM
也就是記憶體管理跟指標,今天a1 a2 兩個陣列其實都是指標pointer
C語言強大在這個地方,失敗也在這個地方,我們透過指標可以快速輕易的
存取到記憶體中個個位子,但是並不是每個位子,你都是可以存取的,所以要非常的小心
你得寫法事實上已經超過這個陣列的範圍了,但是他在你得電腦上跑也許沒有問題
換個環境可能問題就會產生,這是非常討厭的,因為你有時候很難抓到這種BUG
但是也是因為這樣方便的存取記憶體的方式,所以C寫出來的程式非常的有效率,

~yes

我剛才也有自己「玩」一下,例如把for(i=1;i<11;i++)這裡改成for(i=1;i<123;i++)之類超出原來該有元素很多的數目,結果跑出來的結果十分不同,我的電腦通常會持續跑出幾十甚上百的數列,但幾乎都會跟著當掉而被迫要關掉這個程式。就如您說的,會發生不可知的結果。?:teeth

哈啦
2014-02-17, 05:35 PM
再請教一個問題,這是一個陣列的程式。就是有五個server以及各server的user有多少人?如今輸入一個server的號碼,就去列出該server的user是多少人。如果輸入的server不在其中就回答not listed。
#include <stdio.h>

int main(void)
{

int serverusers[5][2]=
{
1,14,
2,28,
3,19,
4,8,
5,15};

int server;
int i;

printf("enter the server number: \n");
scanf("%d",&server);

//look it up in the table.
for(i=0;i<5;i++)
if(server==serverusers[i][0]){
printf("there are %d users on server %d.\n",serverusers[i][1],server);
break;
}
//report error if not found.
if(i==5) printf("server not listed.\n");
return 0;
}

為何最後以i等於5的話來判定輸入的值不在預設之中?

thanks

best-url
2014-02-17, 05:43 PM
再請教一個問題,這是一個陣列的程式。就是有五個server以及各server的user有多少人?如今輸入一個server的號碼,就去列出該server的user是多少人。如果輸入的server不在其中就回答not listed。


為何最後以i等於5的話來判定輸入的值不在預設之中?

thanks


以前 不是有一個 站長俱樂部嗎?!

那裡應該有很多懂程式的高手嗎?

lukawa
2014-02-17, 07:52 PM
for(i=0;i<5;i++) 會由 0 跑到 4 (五次) 一直跑到i = 5 時
才會跳出迴圈,所以當i = 5 時,也等義於找不到資料的意思

另外請教哈大,目前是用什麼IDE在開發呢?

哈啦
2014-02-17, 08:07 PM
for(i=0;i<5;i++) 會由 0 跑到 4 (五次) 一直跑到i = 5 時
才會跳出迴圈,所以當i = 5 時,也等義於找不到資料的意思

另外請教哈大,目前是用什麼IDE在開發呢?

原來是這個邏輯,:bow 但我如果用i==6 or i==9等,則程式就出錯,不會印出not listed,為什麼呢?

我用的是devcpp的軟體來編和跑。

lukawa
2014-02-17, 08:58 PM
因為跑出for(i=0;i<5;i++)這個迴圈以後,就不會再執行到i++
所以當然i只會跑到5不會繼續往下加

如果有使用IDE,應該有step by step debug的功能
你可以一行一行去看i的值的變化,這樣你就會很清楚
i為什麼只會跑到5

哈啦
2014-02-17, 09:07 PM
因為跑出for(i=0;i<5;i++)這個迴圈以後,就不會再執行到i++
所以當然i只會跑到5不會繼續往下加

如果有使用IDE,應該有step by step debug的功能
你可以一行一行去看i的值的變化,這樣你就會很清楚
i為什麼只會跑到5

了解,因為我主要是這個i==5的推理想不通,為何會想出要用i==5來達到這個目的?為何i==6,7...就不行?:whoknows 所以現在就是因為i最後是跑到5而停下來,因此如果i==5就不符合之前的if(),但i確實有到5就是了?

這個step by step的功能尚找到。~embarass:

lukawa
2014-02-17, 09:51 PM
其實我自己的習慣,會在進入迴圈時,會先設定一個exist 的變數為 false
如果真的有找到,就把他設定true,那這樣讀起就非常的直覺,但是很多人
寫程式的當下,不會特別去想這些事情,所以到時候,有時會很難維護

哈啦
2014-02-17, 10:13 PM
其實我自己的習慣,會在進入迴圈時,會先設定一個exist 的變數為 false
如果真的有找到,就把他設定true,那這樣讀起就非常的直覺,但是很多人
寫程式的當下,不會特別去想這些事情,所以到時候,有時會很難維護

原來如此。~yes

不知就本式來看,您能否示範一下,您說的設一個exit的變數?如果可以的話?:bow

另外就i==5的邏輯推演我剛才似乎有點想通了,推演如下,以資記錄備忘:
i 一旦算到5,該迴圈就會跳出來,因此如果i==5,則表示之前從i==0,i==1,i==2,i==3,i==4都沒有符合的答案,因此i最終會來到5,則給予not listed的回應。所以也不能給i==6 or more.

lukawa
2014-02-18, 09:21 AM
太久沒寫C了,查了一下,發現沒有boolean 型態,所以那就用int 代替啦


#include <stdio.h>

int main(void)
{

int serverusers[5][2]=
{
1,14,
2,28,
3,19,
4,8,
5,15};

int server;
int i;
int existFlag;

printf("enter the server number: \n");
scanf("%d",&server);

//look it up in the table.

existFlag = 0;
for(i=0;i<5;i++)
if(server==serverusers[i][0]){
existFlag = 1;
printf("there are %d users on server %d.\n",serverusers[i][1],server);
break;
}
//report error if not found.
if(existFlag==0) printf("server not listed.\n");
return 0;
}

哈啦
2014-02-18, 12:16 PM
太久沒寫C了,查了一下,發現沒有boolean 型態,所以那就用int 代替啦


#include <stdio.h>

int main(void)
{

int serverusers[5][2]=
{
1,14,
2,28,
3,19,
4,8,
5,15};

int server;
int i;
int existFlag;

printf("enter the server number: \n");
scanf("%d",&server);

//look it up in the table.

existFlag = 0;
for(i=0;i<5;i++)
if(server==serverusers[i][0]){
existFlag = 1;
printf("there are %d users on server %d.\n",serverusers[i][1],server);
break;
}
//report error if not found.
if(existFlag==0) printf("server not listed.\n");
return 0;
}

~yes thanks.