Bu C kodunun çıktısı 49'dur, ancak birisi bana nasıl olduğunu açıklayabilir mi? [çiftleme]

Jan 20 2021
#include <stdio.h>

#define CUBE(x) (x * x * x)

int main() {
    printf("%d", CUBE(4+5));
    return 0;
}

Yanıtlar

5 MarkSouls Jan 20 2021 at 14:31

Makro, kodu şuna çevirecektir:

printf("%d", (4+5 * 4+5 * 4+5));

etkili olan:

printf("%d", 4 + (5*4) + (5*4) + 5); // 29

Küp 9almak 729istiyorsanız yazmalısınız CUBE((4+5)).

9 chqrlie Jan 20 2021 at 14:34

Derleme işlemi sırasında makronun nasıl genişletildiği aşağıda açıklanmıştır:

printf("%d", (4+5 * 4+5 * 4+5));

Çünkü *daha yüksek bir önceliğe sahip +bu ifade olarak değerlendirilir (4 + (5 * 4) + (5 * 4) + 5)üreten 49yerine beklenen 729.

Bu tür operatör öncelik sorunlarından kaçınmak için, tüm makro argümanlar makro tanımında ve ifadenin kendisinde parantez içine alınmalıdır:

#define CUBE(x)  ((x) * (x) * (x))

Bununla birlikte, bu genişlemenin birden çok kez CUBEdeğerlendirildiğini unutmayın; bu x, makro bağımsız değişkeninin CUBE(i++).

Tüm bu sorunları önlemek için bir işlev kullanın ve derleyicinin onu optimize etmesine izin verin:

int cube(int x) {
    return x * x * x;
}

static inlineBu işlev tanımının önüne ekleyebilirsiniz , ancak modern eniyileyiciler bu olmadan işlevi yine de satır içi olacaktır.

3 Tecto Jan 20 2021 at 14:32

C ön işlemcisi tam anlamıyla x'in tüm örneklerini 4 + 5 yerine koyacak ve sonuçta aşağıdaki kod ortaya çıkacaktır:

i = 4+5*4+5*4+5;

(önce çarpma, sonra toplama)

3 SahadatHossain Jan 20 2021 at 14:31

CUBE((4+5))Numaraları eklemek ve sonra göndermek istiyormuş gibi girdi vermeniz gerekiyor CUBE. Çünkü , yerine bütünü ayarladığı için CUBE(4+5), temelde genişletilir . Öyleyse, = çarpma önce gelir ve sonra onları toplamak verir .4+5*4+5*4+54+5x4+5*4+5*4+54+20+20+549

Makroyu #define CUBE(x) ((x)*(x)*(x))gerçekte olduğu gibi tanımlayın, önce (4+5)her biri için işlemi ilerletin (x)ve sonra *işlemi yapın.

Diğer bir yol ise sadece CUBE((4+5))makroyu çağırırken kullanmaktır , temelde önce iki sayıyı ekledi ve (4+5)= 9ve sonra CUBE(9)şöyle yapın:

#include<stdio.h>
#define CUBE(x) (x * x * x)

int main( )
{
    printf("%d", CUBE((4+5)));
    return 0;
}
1 BasileStarynkevitch Jan 20 2021 at 14:29

Okuma Modern C , daha sonra n1570 taslak C standart ve dokümantasyonu GCC ve GDB ve cpp . Ayrıca bu C referans web sitesine bakın.

Github veya GNU yazılımı gibi mevcut açık kaynak projelerinden ilham alın .

Son ile GCC derleyicisi, onu çağırmak olarak gcc -Wall -Wextra -g. Önceden -C -Eişlenmiş formu almak için seçenekleri de kullanın .

GCC'nin ifade-ifade uzantısı da ilginizi çekebilir .

Sizin CUBE(4+5)makro genişletilmiş etmektir 4+5*4+5*4+5olarak hesaplanır hangi 4+(5*4)+(5*4)+5önceliğine göre C operatörleri .

Şunun static inlinegibi bir işlevi kodlamayı düşünün:

static inline int cube(int x) { return x*x*x; }

veya en azından bir makroya ihtiyacınız varsa

#define CUBE(X) ((X)*(X)*(X))

bunun için iyi çalışmaz CUBE(i++)( inlineişlevle birlikte, cube(i++)yapmasını istediğiniz şeyi yapar: bir ikez artırın!).

BTW, bazı C kodu oluşturmak için GPP veya GNU m4'ü (veya kendi oluşturucunuzu veya GNU bizonunu ) kullanabilirsiniz. Genel bir kural olarak, AST s ile düşünün : C kodu oluşturduğunuzda, örneğin Chicken Scheme , SWIG veya CAIA veya benim manydl.c'de olduğu gibi, pek çok yararsız parantez kullanın.

Kodunuzda (ve belki Frama-C ) Clang statik analizcisini de kullanabilirsiniz .

MISRA C veya GNU gibi bazı kodlama yönergelerini okumak ilginizi çekebilir .