查看完整版本: 關於C語言struct的疑問?
頁: [1]

CodeMonk 發表於 2016-7-5 02:17 AM

關於C語言struct的疑問?

本帖最後由 CodeMonk 於 2016-7-5 02:18 AM 編輯

先看Code:

void main (void) {
    {
        struct Car {
            char *name;
            int x;
            int y;
            void (*where) (struct Car * args);
        } new = {"undef", 0, 0};

        void Where (struct Car * args){
            print f("the x is %d\n",args->x);
            print f("the y is %d\n",args->y);
        }

        struct Car a = new;
        a.where = &Where;//問題就在這裡!
        a.where(&a);
        a.x = 1;
        a.where(&a);
    }
}


我不知道怎麼設定struct的default質,當那一個struct裡有function用到那struct自己本身!
所以才寫的那麼畸形的樣子!有沒有更好的方法呢?



...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>

chevylin0802 發表於 2016-7-5 05:23 PM

本帖最後由 chevylin0802 於 2016-7-5 05:26 PM 編輯

規矩的C語言完全不允許你把struct定義在函式裏面
規矩的C語言也完全不允許你把函式程式碼寫在另一個函式裏
事實上如果更嚴格的規範的話
包括一般的變數以及函式都不允許大小寫混合使用
C++才有大小寫英文字的混合用法
如果你要用C語言的表示法
就請按照C語言的通用寫法
別拿C++混用進來struct xxx {
.........
};

void main() {
.........
}

...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

inunu 發表於 2016-7-6 12:20 PM

C 裡面資料結構和函式是分開的
一般會提供公用函式來建立物件設定初始值, 例如#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Car
{
    char *name;
    int x;
    int y;
    void (*where)(struct Car * args);
};

void Where(struct Car * args)
{
    print f("the x is %d\n", args->x);
    print f("the y is %d\n", args->y);
}

void my_func(struct Car * args)
{
    print f("Car %s: %d, %d\n", args->name, args->x, args->y);
}

struct Car* car_create(const char *name, int x, int y, void (*handler)(struct Car * args))
{
    struct Car* pCar = (struct Car*)malloc(sizeof(struct Car));
    pCar->name = (char *)malloc(strlen(name + 1));
    strcpy(pCar->name, name);
    pCar->x = x;
    pCar->y = y;
    pCar->where = (handler != NULL) ? handler : &Where;
    return pCar;
}

void car_destroy(struct Car* pCar)
{
    free(pCar->name);
    free(pCar);
}

void main(void)
{
    struct Car* a = car_create("A", 1, 2, NULL);
    struct Car* b = car_create("B", 3, 4, &my_func);

    a->where(a);
    a->x = 10;
    a->where(a);

    b->where(b);
    b->x = 20;
    b->where(b);
   
    car_destroy(a);
    car_destroy(b);
}...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

gitlab 發表於 2016-7-8 03:35 AM

不必想了,C做不到

另外 nested function 不在準標之內

thebestjavauser 發表於 2016-8-14 01:54 AM

本帖最後由 thebestjavauser 於 2016-8-15 11:10 PM 編輯

clang 的 extension 可以做到
clang -fblocks using_blocks.c -lBlocksRuntime

#include <stdio.h>
#include <Block.h>
     
int
main ()
{
  float f = 0.01;

  void (^closure)(int) = ^(int i)
  { print f("%f%d\n", f, i); };

  closure(100);

  return 0;
}



output:
0.01100
<br><br><br><br><br><div></div>

thebestjavauser 發表於 2016-8-15 11:39 PM

chevylin0802 發表於 2016-7-5 05:23 PM static/image/common/back.gif
規矩的C語言完全不允許你把struct定義在函式裏面
規矩的C語言也完全不允許你把函式程式碼寫在另一個函式裏
...

C 語言允許 scope 內的 struct difinition
所以也完全允許把 struct 定義在函式裏面

至於把函式定義在另一個函式裏 GNU C 是允許的, ISO C 則不允許
大小寫混用不論如何都是完全允許的, 另外, c 和 c++ 的命名規則是完全相同的, 沒有混用的問題...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

chevylin0802 發表於 2016-8-16 12:20 AM

本帖最後由 chevylin0802 於 2016-8-16 12:29 AM 編輯

thebestjavauser 發表於 2016-8-15 11:39 PM static/image/common/back.gif
C 語言允許 scope 內的 struct difinition
所以也完全允許把 struct 定義在函式裏面


你把C++的規則套到C上了
事實上linux kernel的開發者不會像你這樣子做的
理由是C的正規用法仍然還是以K&R的標準為主
包括不使用.//作為單行註釋的方式
事實上正規的C語言工作者仍然維持傳統的寫法
也就是在C++問世以前的寫法
雖然gcc允許C++的寫法進行編譯
但是在國際上尤其是進行linux kernel方面的維護人員
仍然遵循著Linus Tovars的規定

...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

thebestjavauser 發表於 2016-8-17 04:39 AM

chevylin0802 發表於 2016-8-16 12:20 AM static/image/common/back.gif
你把C++的規則套到C上了
事實上linux kernel的開發者不會像你這樣子做的
理由是C的正規用法仍然還是以K&R ...

……
自己去翻翻 c99, c11 standard 吧…
K&R 是 老古董c89 制定前暫用的標準,和 Linus 半點關係也沒有
現在的 linux kernel 遵循的是完完全全的 c90,跟 K&R 也是相隔久遠
更何況標準就是標準,支援的語法就是支援,和 linux kernel 有什麼規定沒有半點關係
C 語言又不只有 linux kernel 這個應用…
還有你講的單行註解只有 c89 以前才不支援
在 linux kernel 上對註解形式的規範是 coding style 而不是語法限制...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

chevylin0802 發表於 2016-8-17 07:38 AM

本帖最後由 chevylin0802 於 2016-8-17 07:48 AM 編輯

thebestjavauser 發表於 2016-8-17 04:39 AM static/image/common/back.gif
……
自己去翻翻 c99, c11 standard 吧…
K&R 是 老古董c89 制定前暫用的標準,和 Linus 半點關係也沒有

C99允許在函式內部的任何地方使用變數宣告
這確實有人用在開發linux kernel上
但那是少數
因為編譯器大多都會在最佳化的過程當中指定成暫存器變數
無論你是採取舊的宣告方式或者是新的宣告方式
除此之外C99其實改變不大
只是也允許單行註釋方式
比如在函式裏定義的結構是一件很差勁的事情
它破壞整個程式的可讀性
新不等於就是好
而且linux kernel並沒有特別提到完全遵循C99這件事情
這點你真的完全搞錯
gcc如果要編譯符合C99語法的原始碼還需要將 -std=c99 加在編譯環境裏
我只看過少數的程式庫在Makefile裏面有這種東西

...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

thebestjavauser 發表於 2016-8-17 02:48 PM

chevylin0802 發表於 2016-8-17 07:38 AM static/image/common/back.gif
C99允許在函式內部的任何地方使用變數宣告
這確實有人用在開發linux kernel上
但那是少數


哈囉 你以為 C 語言只能寫 kernel 喔?還是只能寫 linux kernel? XD
c99 是真的改變不多(不過照這樣講哪一次標準有改變很多的),但很多重要的東西從這時候開始有
然後 linux kernel 遵循的是 c90 而不是 c99,先看清楚再來回覆吧
你在 makefile 裡沒看到是因為它通常在整個專案的 root 裡的 makefile 指定,其他的沒有
而且如果是用 configure 相關工具生成的 makefile 已經保證編譯器實作的行為和預期相同,不需要再另外指定使用哪個標準
至於 inline struct 和 anonymous struct 是否破壞可讀性等你寫過更多程式再來評論吧
它在 OO 看來會造成不必要的 dependency,但是在 Generic 看來就完全不是這麼回事...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>
頁: [1]