Apakah perbezaan antara Linux GNU C dan ANSI C?
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.
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]; };
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]);
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; }
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; }
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':
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);
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)
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
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]... );
Dalam GNU C, makro juga boleh menerima bilangan parameter yang berubah-ubah, contohnya:
#define pr_debug(fmt,arg...) \ printk(fmt,##arg)
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)
akan diperluaskan kepada:
printk("%s:%d", filename, line)
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")
akan dikembangkan dengan betul kepada:
printk("success!\n")
bukannya:
printk("success!\n",)
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 };
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, };
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, };
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__); }
__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__); }
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;
format属性也用于函数,表示该函数使用printf、scanf或strftime风格的参数,指定format属性可以让编译器根据格 式串检查参数类型。例如:
asmlinkage int printk(const char * fmt, ...) __attribute__ ((format (printf, 1, 2)));
上述代码中的第1个参数是格式串,从第2个参数开始都会根据printf()函数的格式串规则检查参数。
unused属性作用于函数和变量,表示该函数或变量可能不会用到,这个属性可以避免编译器产生警告信息。
aligned属性用于变量、结构体或联合体,指定变量、结构体或联合体的对齐方式,以字节为单位,例如:
struct example_struct { char a; int b; long c; } __attribute__((aligned(4)));
表示该结构类型的变量以4字节对齐。
packed属性作用于变量和类型,用于变量或结构体成员时表示使用最小可能的对齐,用于枚举、结构体或联合体类型时表示该类型使用最小的内存。例如:
struct example_struct { char a; int b; long c __attribute__((packed)); };
编译器对结构体成员及变量对齐的目的是为了更快地访问结构体成员及变量占据的内存。例如,对 于一个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)))
内建函数__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)
若代码中出现分支,则即可能中断流水线,我们可以通过likely()和unlikely()暗示分支容易成立还是不容易 成立,例如:
if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) if (ipv4_is_loopback(saddr)) goto e_inval;
在使用gcc编译C程序的时候,如果使用“-ansi–pedantic”编译选项,则会告诉编译器不使用GNU扩展语法。例如对 于如下C程序test.c:
struct var_data { int len; char data[0]; }; struct var_data a;
直接编译可以通过:
gcc -c test.c
如果使用“-ansi–pedantic”编译选项,编译会报警:
gcc -ansi -pedantic -c test.c test.c:3: warning: ISO C forbids zero-size array 'data'
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!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



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)

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.

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.

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? Semasa membangun di GO, menyambung ke pangkalan data Oracle adalah keperluan biasa ...

"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

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

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.
