例1: 從函式返回結構及陣列
#include <stdio.h>
typedef struct powers {
double base, square, cube;
} powers;
powers get_power(double in){
powers out = {.base = in,
.square = in*in,
.cube = in*in*in};
return out;
}
int *get_even(int count){
int out[count];
for (int i=0; i< count; i++)
out<em> = 2*i;
return out; //bad.
}
int main(){
powers threes = get_power(3);
int *evens = get_even(3);
printf("threes: %g\t%g\t%g\n", threes.base, threes.square, threes.cube);
printf("evens: %i\t%i\t%i\n", evens[0], evens[1], evens[2]);
}
編譯方式:
export CFLAGS="-g -Wall -std=gnu11 -O3" #the usual.
make automem
我在MINGW下,得到的警告訊息為,
automem.c: In function 'get_even':
automem.c:22:5: warning: function returns address of local variable [-Wreturn-lo
cal-addr]
return out; //bad.
^
執行結果:
$ ./automem
threes: 3 9 27
evens: 0 0 0
筆者改了一下,想得到預期的結果,
int out[];
int *get_even(int count){
把返回值宣告在全域_,_
執行結果會對,
$ ./automem_1
threes: 3 9 27
evens: 0 2 4
編譯時會有警告!
automem_1.c:17:5: warning: array 'out' assumed to have one element [enabled by d
efault]
int out[];
^
automem_1.c: In function 'main':
automem_1.c:21:12: warning: array subscript is above array bounds [-Warray-bound
s]
out = 2*i;
^
這個問題,筆者沒想過,覺得是陣列的有效範圍的問題,但是結構宣告在函式裏,定義在函式外,卻能正確返回值。
例2:指標是別名
#include <assert.h>
#include <string.h> //memcpy
int main(){
int abc[] = {0, 1, 2};
int *copy1, copy2[3];
copy1 = abc;
memcpy(copy2, abc, sizeof(int)*3);
abc[0] = 3;
assert(copy1[0]==3);
assert(copy2[0]==0);
}
copy1是指標,這裏是別名效果,所以值會改變。
而copy2是獨立的儲存位址,故不受abc改變值的影響。
這是老派(antediluvian)的寫法,但仍然有用,複製位址的大小,順便把值複製過去,然後就脫勾了。
例3:指標平常的用法複習
#include <stdio.h>
int main(){
int evens[5] = {0, 2, 4, 6, 8};
printf("The first even number is, of course, %i\n", *evens);
int *positive_evens = &evens[1];
printf("The first positive even number is %i\n", positive_evens[0]);
}
*evens 是 第0個元素,就是evens[0], 所以positive_evens[0]也和*positive_evens同意思。
_int *positive_evens = &evens[1];_是用**&**把陣列中的值取出,指給新指標。
**小結:**本來以為將會是輕鬆的下面幾章,好像和C有關係,事情就不簡單了,老鳥寫的這些範例,看似簡單,實作起來總覺得不少迷惑。