タグ付けされた質問 「c」

Cは、システムプログラミング(OSおよび組み込み)、ライブラリ、ゲーム、クロスプラットフォームに使用される汎用プログラミング言語です。このタグは、ISO 9899標準で定義されているC言語に関する一般的な質問で使用する必要があります(特に指定のない限り、最新バージョン9899:2018。バージョン固有のリクエストには、c89、c99、c11などのタグも付けます)。CはC ++とは異なり、合理的な理由がない限り、C ++タグと組み合わせるべきではありません。

10
Catalina 10.15にアップグレードした後、MacでCプログラムをコンパイルできません
前の質問があります。Mojaveへのアップグレード後にMacでCプログラムをコンパイルできません。その答えは、問題のほとんどのバリエーションをカバーしています。 現在、2019年10月7日月曜日以降、macOS Catalina 10.15にアップグレードできます。もう一度、アップグレード中に/usr/include(Mojave 10.14.6から)Catalinaにアップグレードする前にXCode 11.0がインストールされていたとしても、ディレクトリはアップデートによって吹き飛ばされました。その結果、/usr/includeディレクトリが存在することを期待してビルドされたコンパイラは、もはや機能しません。 Mojaveの問題の主な推奨手順—コマンドを使用: open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg ディレクトリ/Library/Developer/CommandLineTools/Packages/が存在しないため、ゲートの外では機能しません(したがって.pkg、開くファイルがまだありません)。 ディレクトリを作成して入力するための良い(公式の)方法はあり/usr/includeますか?
64 c  xcode  macos  gcc  macos-catalina 

4
構造体の配列の最後に空の中括弧 '{}'が必要なのは何ですか?
Linuxカーネルでc コードをいくつかヒットしました。 static struct ctl_table ip_ct_sysctl_table[] = { { .procname = "ip_conntrack_max", .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, }, // ... { .procname = "ip_conntrack_log_invalid", .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = &log_invalid_proto_min, .extra2 = &log_invalid_proto_max, }, { } }; ここで、構造体の配列はで終わり{ }ます。どのような目的で追加されましたか? …

4
((void(*)())buf)();とは 平均?
私はpicoCTFでのバイナリの悪用の課題を解決しており、次のコードに遭遇しました。 ((void (*)())buf)(); どこbufの文字列です。 私は問題を解決しましたが、それが何をしているのか正確に理解できないようです。私はこのスレッドを見ましたが、理解できませんでした。 どういう((void (*)())buf)();意味ですか?

4
const char *配列初期化コンマがない場合にコンパイラ警告を生成します
Cコードで文字列リテラルテーブルをよく使用しています。これらのテーブルはすべて次のようになります。 static const char* const stateNames[STATE_AMOUNT] = { "Init state", "Run state", "Pause state", "Error state", }; 上記のコードの問題は、テーブルが長くなり、開発中に変更された場合、時々カンマを忘れることです。コードはコンマがないため問題なくコンパイルされますが、最後の文字列がに設定されているため、プログラムがクラッシュしNULLます。検証にはMinGWおよびKeilコンパイラを使用しました。 コンマが欠落している場合、私の初期化に対してコンパイラ警告を生成する方法はありますか?
53 c  initialization 


6
(x | y)-yなぜ単純にxまたは `x | 0`
私はカーネルコードを読んでいて、ある場所で次のifようなステートメント内の式を見ました if (value == (SPINLOCK_SHARED | 1) - 1) { ............ } ここで、SPINLOCK_SHARED = 0x80000000事前定義された定数です。 なぜ(SPINLOCK_SHARED | 1) - 1型変換が必要なのでしょうか。式の結果は80000000になります-0x80000000と同じですよね?それでも、なぜORing 1とSubtracting 1が重要なのですか? 何かを手に入れられないような気がします。

2
argcとargvのアドレスが12バイト離れているのはなぜですか?
私のコンピューター(Linuxを実行する64ビットIntel)で次のプログラムを実行しました。 #include <stdio.h> void test(int argc, char **argv) { printf("[test] Argc Pointer: %p\n", &argc); printf("[test] Argv Pointer: %p\n", &argv); } int main(int argc, char **argv) { printf("Argc Pointer: %p\n", &argc); printf("Argv Pointer: %p\n", &argv); printf("Size of &argc: %lu\n", sizeof (&argc)); printf("Size of &argv: %lu\n", sizeof (&argv)); test(argc, argv); return 0; …

2
スイッチがチェーン化されているのと同じように最適化されていないのはなぜですか?
次のsquareの実装は、連鎖ifステートメントに期待するような一連のcmp / jeステートメントを生成します。 int square(int num) { if (num == 0){ return 0; } else if (num == 1){ return 1; } else if (num == 2){ return 4; } else if (num == 3){ return 9; } else if (num == 4){ return 16; } else if (num == …

6
なぜこれはタイプパンニングされたポインターの警告を逆参照しているとコンパイラ固有に主張されているのですか?
Stack Overflow REのさまざまな 投稿 を 読みました:逆参照型でパンされたポインターエラーです。私の理解では、エラーは本質的に、異なる型のポインターを介してオブジェクトにアクセスする危険性についてのコンパイラー警告である(例外はに対して行われているように見えます)と理解でき、これは理解できる合理的な警告です。char* 私の質問は以下のコードに固有です:なぜポインターのアドレスvoid**をこの警告の修飾にキャストするの-Werrorですか(を介してエラーにプロモートされます)? さらに、このコードは複数のターゲットアーキテクチャ用にコンパイルされており、そのうちの1つだけが警告/エラーを生成します。これは、正当にコンパイラのバージョン固有の欠陥であることを意味しているのでしょうか? // main.c #include <stdlib.h> typedef struct Foo { int i; } Foo; void freeFunc( void** obj ) { if ( obj && * obj ) { free( *obj ); *obj = NULL; } } int main( int argc, char* argv[] ) { …
38 c  pointers  casting 

3
'#'文字をコマンドライン引数として渡すことができません
で始まる文字列#をコマンドライン引数として渡すことはできません。 ここに簡単なテストがあります: #include <stdio.h> int main(int argc, char *argv[]) { for (int i = 1; i < argc; i++) printf("%s ", argv[i]); putchar('\n'); return 0; } 次のように引数を入力すると、 2 4 # 5 6 argcis の値3とnot の値6。読み#、そこで停止します。なぜなのかわからないし、Cプログラミング言語とCプライマープラスのコピーにも答えがありません。

7
スタック配列のポインターへのポインターにアクセスできないのはなぜですか?
次のコードを見てください。これは、配列をとしてchar**関数に渡そうとします。 #include <stdio.h> #include <stdlib.h> static void printchar(char **x) { printf("Test: %c\n", (*x)[0]); } int main(int argc, char *argv[]) { char test[256]; char *test2 = malloc(256); test[0] = 'B'; test2[0] = 'A'; printchar(&test2); // works printchar((char **) &test); // crashes because *x in printchar() has an invalid pointer free(test2); return …
35 c 

4
strcasecmpアルゴリズムに欠陥がありますか?
私はstrcasecmpCで関数を再実装しようとしていますが、比較プロセスで矛盾しているように見えるものに気づきました。 から man strcmp strcmp()関数は、2つの文字列s1とs2を比較します。ロケールは考慮されません(ロケール対応の比較については、strcoll(3)を参照)。s1がそれぞれs2より小さい、一致する、またはs2より大きい場合、ゼロより小さい、等しい、またはゼロより大きい整数を返します。 から man strcasecmp strcasecmp()関数は、文字の大文字と小文字を無視して、文字列s1とs2のバイト単位の比較を実行します。s1がそれぞれs2より小さい、一致する、またはs2より大きい場合、ゼロより小さい、等しい、またはゼロより大きい整数を返します。 int strcmp(const char *s1, const char *s2); int strcasecmp(const char *s1, const char *s2); この情報を考えると、次のコードの結果は理解できません。 #include <stdio.h> #include <string.h> int main() { // ASCII values // 'A' = 65 // '_' = 95 // 'a' = 97 printf("%i\n", strcmp("A", "_")); printf("%i\n", …
34 c  strcmp 

7
Cでポインター比較はどのように機能しますか?同じ配列を指さないポインターを比較しても大丈夫ですか?
K&R(Cプログラミング言語第2版)の第5章で以下を読みました。 まず、特定の状況下でポインタを比較できます。もしpとq同じ配列のメンバーへのポイント、その後のような関係==、!=、<、>=、などの作業を適切に。 これは、同じ配列を指すポインターのみを比較できることを意味しているようです。 しかし、私がこのコードを試したとき char t = 't'; char *pt = &t; char x = 'x'; char *px = &x; printf("%d\n", pt > px); 1 画面に出力されます。 まず第一に、私はので、私は、未定義またはいくつかのタイプやエラーになるだろうと思ったptし、px(少なくとも私の理解では)同じ配列を指していません。 またpt > px、両方のポインタがスタックに格納されている変数を指しているため、スタックtが大きくなり、メモリアドレスがx?どちらがpt > px本当ですか? mallocが導入されると、さらに混乱します。また、8.7章のK&Rには、次のように書かれています。 ただし、によって返されるさまざまなブロックへのポインターをsbrk有意義に比較できるという前提はまだ1つあります。これは、配列内でのみポインタ比較を許可する標準では保証されていません。したがって、このバージョンのmallocは、一般的なポインタ比較が意味のあるマシン間でのみ移植可能です。 ヒープでmallocされたスペースを指すポインターとスタック変数を指すポインターを比較しても問題はありませんでした。 たとえば、次のコードは正常に機能し1、印刷されました。 char t = 't'; char *pt = &t; char *px = malloc(10); strcpy(px, pt); …

4
forkを呼び出すときにスレッドはコピーされますか?
スレッドで実行しているプログラムがありfork()、UNIXベースのシステムを呼び出す場合、スレッドはコピーされますか?現在のプロセスの仮想メモリが、生成された新しいプロセスに1:1でコピーされることを知っています。スレッドがプロセスの仮想メモリに独自のスタックを持っていることを知っています。したがって、少なくともスレッドのスタックもコピーする必要があります。ただし、仮想メモリに存在しないためにコピーされないスレッドが他にあるかどうかはわかりません。ない場合、2つのプロセスはスレッドを共有していますか、それとも独立したコピーですか?

6
2バイトを符号付き16ビット整数に変換する正しい方法は何ですか?
では、この答え、zwolはこの主張をしました。 2バイトのデータを外部ソースから16ビットの符号付き整数に変換する正しい方法は、次のようなヘルパー関数を使用することです。 #include <stdint.h> int16_t be16_to_cpu_signed(const uint8_t data[static 2]) { uint32_t val = (((uint32_t)data[0]) << 8) | (((uint32_t)data[1]) << 0); return ((int32_t) val) - 0x10000u; } int16_t le16_to_cpu_signed(const uint8_t data[static 2]) { uint32_t val = (((uint32_t)data[0]) << 0) | (((uint32_t)data[1]) << 8); return ((int32_t) val) - 0x10000u; } 上記の関数のどちらが適切かは、配列にリトルエンディアン表現またはビッグエンディアン表現が含まれるかどうかによって異なります。エンディアンネスはここでの問題ではありません、なぜzwolがに変換さ0x10000uれたuint32_t値から減算するのか疑問に思っていint32_tます。 なぜこれが正しい方法ですか? …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.