Jadual Kandungan
1. Tatasusunan panjang sifar dan panjang berubah" >1. Tatasusunan panjang sifar dan panjang berubah
2.skop kes" >2.skop kes
3. Ungkapan penyata" >3. Ungkapan penyata
4.jenis kata kunci" >4.jenis kata kunci
5. Makro parameter boleh ubah" >5. Makro parameter boleh ubah
6. Elemen label" >6. Elemen label
7. Nama fungsi semasa" >7. Nama fungsi semasa
8.特殊属性声明" >8.特殊属性声明
9.内建函数" >9.内建函数
Rumah Tutorial sistem LINUX Apakah perbezaan antara Linux GNU C dan ANSI C?

Apakah perbezaan antara Linux GNU C dan ANSI C?

Feb 05, 2024 pm 04:30 PM
linux tutorial linux sistem linux arahan linux skrip shell embeddedlinux lesen yang bagus Bermula dengan linux pembelajaran linux

Pengkompil C yang tersedia di Linux ialah Pengkompil GNU C, yang dibina di atas lesen pengaturcaraan Yayasan Perisian Percuma dan oleh itu boleh diedarkan dan digunakan secara bebas. GNU C membuat satu siri sambungan kepada standard C untuk meningkatkan kefungsian standard C.

Linux GNU C 与 ANSI C 有什么区别?

1. Tatasusunan panjang sifar dan panjang berubah

GNU C membenarkan penggunaan tatasusunan sifar panjang, yang sangat berguna apabila mentakrifkan struktur pengepala objek panjang berubah-ubah. Contohnya:

struct var_data { 
    int len; 
    char data[0]; 
};
Salin selepas log masuk

data char[0] hanya bermakna program boleh mengakses alamat indeks selepas len melalui ahli data[index] contoh struktur var_data Ia tidak memperuntukkan memori untuk tatasusunan data[], jadi sizeof (struct var_data) = sizeof(int).

Dengan mengandaikan bahawa medan data struct var_data disimpan dalam kawasan memori sejurus selepas struct var_data, data boleh dilalui melalui kod berikut:

struct var_data s; 
... 
for (i = 0; i printf("%02x", s.data[i]);
Salin selepas log masuk

Dalam GNU C, anda juga boleh menggunakan 1 pembolehubah untuk menentukan tatasusunan, seperti "double x[n]" yang ditakrifkan dalam kod berikut:

int main (int argc, char *argv[]) 
{ 
    int i, n = argc; 
    double x[n]; 
    for (i = 0; i return 0; 
}
Salin selepas log masuk

2.skop kes

GNU C menyokong sintaks kes x...y Nombor dalam selang [x, y] akan memenuhi syarat kes ini. Sila lihat kod berikut:

switch (ch) { 
case '0'... '9': c -= '0'; 
    break;
case 'a'... 'f': c -= 'a' - 10; 
    break; 
case 'A'... 'F': c -= 'A' - 10; 
    break; 
}
Salin selepas log masuk

huruf '0'...'9' dalam kod adalah bersamaan dengan dalam standard C:

case '0': case '1': case '2': case '3': case '4': 
case '5': case '6': case '7': case '8': case '9':
Salin selepas log masuk

3. Ungkapan penyata

GNU C menganggap pernyataan majmuk yang terkandung dalam kurungan sebagai ungkapan, dipanggil ungkapan pernyataan, yang boleh muncul di mana-mana sahaja di mana ungkapan dibenarkan. Kita boleh menggunakan gelung, pembolehubah tempatan, dsb. yang hanya boleh digunakan dalam pernyataan majmuk dalam ungkapan pernyataan, contohnya:

#define min_t(type,x,y) \ 
( { type _ _x =(x);type _ _y = (y); _ _xfloat fa, fb, minf; 
mini = min_t(int, ia, ib); 
minf = min_t(float, fa, fb);
Salin selepas log masuk

Oleh kerana dua pembolehubah tempatan __xx dan __y ditakrifkan semula, makro yang ditakrifkan dengan cara di atas tidak akan mempunyai kesan sampingan. Dalam standard C, makro yang sepadan akan menghasilkan kesan sampingan:

#define min(x,y) ((x) 
Salin selepas log masuk

Kod min(++ia,++ib) akan dikembangkan kepada ((++ia)

4.jenis kata kunci

Pernyataan jenis(x) boleh mendapatkan jenis x Oleh itu, makro min boleh ditakrifkan semula dengan bantuan jenis:

#define min(x,y) ({ \ 
const typeof(x) _x = (x); \ 
const typeof(y) _y = (y); \ 
(void) (&_x == &_y); \ 
_x 
Salin selepas log masuk

Kita tidak perlu memasukkan jenis seperti min_t (jenis, x, y) makro, kerana jenis boleh diperolehi melalui jenis (x), jenis (y). Fungsi baris kod (kosong) (&_x==&_y) adalah untuk menyemak sama ada jenis _x dan _y adalah konsisten.

5. Makro parameter boleh ubah

Standard C menyokong fungsi parameter berubah, yang bermaksud bahawa parameter fungsi tidak tetap Contohnya, prototaip fungsi printf() ialah:

int printf( const char *format [, argument]... );
Salin selepas log masuk

Dalam GNU C, makro juga boleh menerima bilangan parameter yang berubah-ubah, contohnya:

#define pr_debug(fmt,arg...) \ 
printk(fmt,##arg)
Salin selepas log masuk

Di sini arg mewakili parameter yang selebihnya, yang boleh mempunyai sifar atau lebih parameter ini dan koma antara parameter membentuk nilai arg digantikan semasa pengembangan makro, seperti yang ditunjukkan dalam kod berikut:

pr_debug("%s:%d",filename,line)
Salin selepas log masuk

akan diperluaskan kepada:

printk("%s:%d", filename, line)
Salin selepas log masuk

Gunakan "##" untuk mengendalikan situasi di mana arg tidak mewakili sebarang parameter Pada masa ini, koma sebelumnya menjadi berlebihan. Selepas menggunakan "##", prapemproses GNU C akan membuang koma sebelumnya, jadi kod berikut:

pr_debug("success!\n")
Salin selepas log masuk

akan dikembangkan dengan betul kepada:

printk("success!\n")
Salin selepas log masuk

bukannya:

printk("success!\n",)
Salin selepas log masuk

6. Elemen label

Standard C memerlukan nilai permulaan tatasusunan atau struktur mesti muncul dalam susunan tetap Dalam GNU C, nilai permulaan dibenarkan muncul dalam sebarang susunan dengan menyatakan indeks atau nama ahli struktur.

Cara untuk menentukan indeks tatasusunan adalah dengan menambah "[INDEX]=" sebelum nilai permulaan Sudah tentu, anda juga boleh menentukan julat dalam bentuk "[PERTAMA...TERAKHIR]=". Sebagai contoh, kod berikut mentakrifkan tatasusunan dan memperuntukkan semua elemen di dalamnya kepada 0:

unsigned char data[MAX] = { [0 ... MAX-1] = 0 };
Salin selepas log masuk

Kod berikut memulakan struktur dengan bantuan nama ahli struktur:

struct file_operations ext2_file_operations = { 
    llseek: generic_file_llseek, 
    read: generic_file_read, 
    write: generic_file_write, 
    ioctl: ext2_ioctl, 
    mmap: generic_file_mmap, 
    open: generic_file_open, 
    release: ext2_release_file, 
    fsync: ext2_sync_file, 
};
Salin selepas log masuk

Walau bagaimanapun, Linux 2.6 mengesyorkan bahawa kod yang serupa hendaklah berada dalam standard C sebanyak mungkin:

struct file_operations ext2_file_operations = { 
    .llseek     = generic_file_llseek, 
    .read       = generic_file_read, 
    .write      = generic_file_write, 
    .aio_read   = generic_file_aio_read, 
    .aio_write  = generic_file_aio_write, 
    .ioct       = ext2_ioctl, 
    .mmap       = generic_file_mmap, 
    .open       = generic_file_open, 
    .release    = ext2_release_file, 
    .fsync      = ext2_sync_file, 
    .readv      = generic_file_readv, 
    .writev     = generic_file_writev, 
    .sendfile   = generic_file_sendfile, 
};
Salin selepas log masuk

7. Nama fungsi semasa

GNU C mentakrifkan dua pengecam untuk menyimpan nama fungsi semasa, __FUNCTION__ menyimpan nama fungsi dalam kod sumber dan __PRETTY_FUNCTION__ menyimpan nama dengan ciri bahasa. Dalam fungsi C, kedua-dua nama ini adalah sama.

void example() 
{ 
    printf("This is function:%s", __FUNCTION__); 
}
Salin selepas log masuk

__FUNCTION__ dalam kod bermaksud rentetan "contoh". C99 sudah pun menyokong makro __func__, jadi adalah disyorkan untuk tidak lagi menggunakan __FUNCTION__ dalam pengaturcaraan Linux dan sebaliknya menggunakan __func__:

void example(void) 
{ 
    printf("This is function:%s", __func__); 
}
Salin selepas log masuk

8.特殊属性声明

GNU C允许声明函数、变量和类型的特殊属性,以便手动优化代码和定制代码检查的方法。要指定一个声明的 属性,只需要在声明后添加__attribute__((ATTRIBUTE))。其中ATTRIBUTE为属性说明,如果存在多个属 性,则以逗号分隔。GNU C支持noreturn、format、section、aligned、packed等十多个属性。

noreturn属性作用于函数,表示该函数从不返回。这会让编译器优化代码,并消除不必要的警告信息。例如:

# define ATTRIB_NORET __attribute__((noreturn)) .... 
asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;
Salin selepas log masuk

format属性也用于函数,表示该函数使用printf、scanf或strftime风格的参数,指定format属性可以让编译器根据格 式串检查参数类型。例如:

asmlinkage int printk(const char * fmt, ...) __attribute__ ((format (printf, 1, 2)));
Salin selepas log masuk

上述代码中的第1个参数是格式串,从第2个参数开始都会根据printf()函数的格式串规则检查参数。

unused属性作用于函数和变量,表示该函数或变量可能不会用到,这个属性可以避免编译器产生警告信息。

aligned属性用于变量、结构体或联合体,指定变量、结构体或联合体的对齐方式,以字节为单位,例如:

struct example_struct { 
    char a; 
    int b; 
    long c; 
} __attribute__((aligned(4)));
Salin selepas log masuk

表示该结构类型的变量以4字节对齐。

packed属性作用于变量和类型,用于变量或结构体成员时表示使用最小可能的对齐,用于枚举、结构体或联合体类型时表示该类型使用最小的内存。例如:

struct example_struct { 
    char a; 
    int b; 
    long c __attribute__((packed)); 
};
Salin selepas log masuk

编译器对结构体成员及变量对齐的目的是为了更快地访问结构体成员及变量占据的内存。例如,对 于一个32位的整型变量,若以4字节方式存放(即低两位地址为00),则CPU在一个总线周期内就可以读取32 位;否则,CPU需要两个总线周期才能读取32位。

9.内建函数

GNU C提供了大量内建函数,其中大部分是标准C库函数的GNU C编译器内建版本,例如memcpy()等,它们与对应的标准C库函数功能相同。

不属于库函数的其他内建函数的命名通常以__builtin开始,如下所示。

内建函数__builtin_return_address(LEVEL)返回当前函数或其调用者的返回地址,参数LEVEL指定调用栈的级数,如0表示当前函数的返回地址,1表示当前函数的调用者的返回地址。

内建函数__builtin_constant_p(EXP)用于判断一个值是否为编译时常数,如果参数EXP的值是常数,函数返回1,否则返回0。例如,下面的代码可检测第1个参数是否为编译时常数以确定采用参数版本还是非参数版本:

#define test_bit(nr,addr) \ 
(__builtin_constant_p(nr) \ 
constant_test_bit((nr),(addr)) : \ 
variable_test_bit((nr),(addr)))
Salin selepas log masuk

内建函数__builtin_expect(EXP,C)用于为编译器提供分支预测信息,其返回值是整数表达式EXP的值,C的 值必须是编译时常数。

Linux内核编程时常用的likely()和unlikely()底层调用的likely_notrace()、unlikely_notrace()就是基于 __builtin_expect(EXP,C)实现的。

#define likely_notrace(x) __builtin_expect(!!(x), 1) 
#define unlikely_notrace(x) __builtin_expect(!!(x), 0)
Salin selepas log masuk

若代码中出现分支,则即可能中断流水线,我们可以通过likely()和unlikely()暗示分支容易成立还是不容易 成立,例如:

if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev)))
    if (ipv4_is_loopback(saddr)) 
    goto e_inval;
Salin selepas log masuk

在使用gcc编译C程序的时候,如果使用“-ansi–pedantic”编译选项,则会告诉编译器不使用GNU扩展语法。例如对 于如下C程序test.c:

struct var_data { 
    int len; 
    char data[0]; 
};
struct var_data a;
Salin selepas log masuk

直接编译可以通过:

gcc -c test.c
Salin selepas log masuk

如果使用“-ansi–pedantic”编译选项,编译会报警:

gcc -ansi -pedantic -c test.c 
test.c:3: warning: ISO C forbids zero-size array 'data'
Salin selepas log masuk

Atas ialah kandungan terperinci Apakah perbezaan antara Linux GNU C dan ANSI C?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Cara Membuka Web.xml Cara Membuka Web.xml Apr 03, 2025 am 06:51 AM

Untuk membuka fail web.xml, anda boleh menggunakan kaedah berikut: Gunakan editor teks (seperti Notepad atau TextEdit) untuk mengedit arahan menggunakan persekitaran pembangunan bersepadu (seperti Eclipse atau NetBeans) (Windows: Notepad Web.xml; Mac/Linux: Open -A -A TextEdit Web.xml)

Empat cara untuk melaksanakan multithreading dalam bahasa c Empat cara untuk melaksanakan multithreading dalam bahasa c Apr 03, 2025 pm 03:00 PM

Multithreading dalam bahasa dapat meningkatkan kecekapan program. Terdapat empat cara utama untuk melaksanakan multithreading dalam bahasa C: Buat proses bebas: Buat pelbagai proses berjalan secara bebas, setiap proses mempunyai ruang ingatan sendiri. Pseudo-Multithreading: Buat pelbagai aliran pelaksanaan dalam proses yang berkongsi ruang memori yang sama dan laksanakan secara bergantian. Perpustakaan multi-threaded: Gunakan perpustakaan berbilang threaded seperti PTHREADS untuk membuat dan mengurus benang, menyediakan fungsi operasi benang yang kaya. Coroutine: Pelaksanaan pelbagai threaded ringan yang membahagikan tugas menjadi subtask kecil dan melaksanakannya pada gilirannya.

Untuk apa yang paling baik digunakan oleh Linux? Untuk apa yang paling baik digunakan oleh Linux? Apr 03, 2025 am 12:11 AM

Linux paling baik digunakan sebagai pengurusan pelayan, sistem tertanam dan persekitaran desktop. 1) Dalam pengurusan pelayan, Linux digunakan untuk menjadi tuan rumah laman web, pangkalan data, dan aplikasi, menyediakan kestabilan dan kebolehpercayaan. 2) Dalam sistem tertanam, Linux digunakan secara meluas di rumah pintar dan sistem elektronik automotif kerana fleksibiliti dan kestabilannya. 3) Dalam persekitaran desktop, Linux menyediakan aplikasi yang kaya dan prestasi yang cekap.

Bagaimana keserasian Debian Hadoop Bagaimana keserasian Debian Hadoop Apr 02, 2025 am 08:42 AM

Debianlinux terkenal dengan kestabilan dan keselamatannya dan digunakan secara meluas dalam persekitaran pelayan, pembangunan dan desktop. Walaupun kini terdapat kekurangan arahan rasmi mengenai keserasian langsung dengan Debian dan Hadoop, artikel ini akan membimbing anda tentang cara menggunakan Hadoop pada sistem Debian anda. Keperluan Sistem Debian: Sebelum memulakan konfigurasi Hadoop, sila pastikan sistem Debian anda memenuhi keperluan operasi minimum Hadoop, yang termasuk memasang Java Runtime Environment (JRE) dan pakej Hadoop. Langkah Penyebaran Hadoop: Muat turun dan Unzip Hadoop: Muat turun versi Hadoop yang anda perlukan dari laman web Apachehadoop rasmi dan selesaikannya

Adakah saya perlu memasang klien oracle semasa menyambung ke pangkalan data oracle menggunakan GO? Adakah saya perlu memasang klien oracle semasa menyambung ke pangkalan data oracle menggunakan GO? Apr 02, 2025 pm 03:48 PM

Adakah saya perlu memasang klien oracle semasa menyambung ke pangkalan data oracle menggunakan GO? Semasa membangun di GO, menyambung ke pangkalan data Oracle adalah keperluan biasa ...

Adakah debian rentetan serasi dengan pelbagai pelayar Adakah debian rentetan serasi dengan pelbagai pelayar Apr 02, 2025 am 08:30 AM

"Debianstrings" bukan istilah standard, dan makna khususnya masih belum jelas. Artikel ini tidak dapat mengulas secara langsung mengenai keserasian penyemak imbasnya. Walau bagaimanapun, jika "debianstrings" merujuk kepada aplikasi web yang dijalankan pada sistem Debian, keserasian penyemak imbasnya bergantung kepada seni bina teknikal aplikasi itu sendiri. Sebilangan besar aplikasi web moden komited untuk keserasian penyemak imbas. Ini bergantung kepada standard web berikut dan menggunakan teknologi front-end yang serasi (seperti HTML, CSS, JavaScript) dan teknologi back-end (seperti PHP, Python, Node.js, dll.). Untuk memastikan bahawa aplikasi itu serasi dengan pelbagai pelayar, pemaju sering perlu menjalankan ujian silang dan menggunakan responsif

Libv adalah dua Libv adalah dua Apr 03, 2025 pm 08:03 PM

Saya membangunkan projek yang dipanggil Lua-Libuv dan gembira untuk berkongsi pengalaman saya. Hasrat asal projek ini adalah untuk meneroka cara menggunakan libuv (perpustakaan I/O yang tidak segerak yang ditulis dalam C) untuk membina pelayan HTTP yang mudah tanpa perlu mempelajari bahasa C secara mendalam. Dengan bantuan CHATGPT, saya menyelesaikan kod asas http.c. Apabila berurusan dengan sambungan yang berterusan, saya berjaya melaksanakan menutup sambungan dan membebaskan sumber pada masa yang tepat. Pada mulanya saya cuba membuat pelayan mudah yang mengakhiri program utama dengan menutup sambungan, tetapi saya mempunyai beberapa masalah. Saya telah cuba menghantar blok data menggunakan streaming, dan semasa ia berfungsi, ini menghalang benang utama. Pada akhirnya, saya memutuskan untuk berputus asa pada pendekatan ini kerana matlamat saya bukan untuk mempelajari bahasa C secara mendalam. Akhirnya, saya

Tidak dapat log masuk ke mysql sebagai akar Tidak dapat log masuk ke mysql sebagai akar Apr 08, 2025 pm 04:54 PM

Sebab utama mengapa anda tidak boleh log masuk ke MySQL sebagai akar adalah masalah kebenaran, ralat fail konfigurasi, kata laluan tidak konsisten, masalah fail soket, atau pemintasan firewall. Penyelesaiannya termasuk: periksa sama ada parameter pengikat di dalam fail konfigurasi dikonfigurasi dengan betul. Semak sama ada kebenaran pengguna root telah diubahsuai atau dipadam dan ditetapkan semula. Sahkan bahawa kata laluan adalah tepat, termasuk kes dan aksara khas. Semak tetapan dan laluan kebenaran fail soket. Semak bahawa firewall menyekat sambungan ke pelayan MySQL.

See all articles