私は中規模のプログラマであり、標準Cを学んでいます。現在、さまざまな種類のデータ型を格納するポインタを使用するクラス演習に苦労しています。 char型の配列標準配列で複数のデータ型を格納するためにchar配列を使用する
は、私は大きなchar型の配列があるとします。
static char arr[1000];
私の教授がそれを説明したように、私はこの配列の各要素は、1バイトの粒度を持つローカルメモリの塊、と考えることができます。それは役に立つと思われる。今、私は最初の4バイト/要素を取り、int型を格納したいとします、私はそれを理解したよう
int a = 100;
int* ptr = (int*)arr;
*ptr = a;
、2行目は、int型*ポインタを作成し、配列arrの冒頭で、それを指しています。 3行目は、aの値をその場所に書き込みます。 ptrはint型のポインタであり、arrには十分なスペースがあるので、sizeof(int)== 4であるため、4バイト/ 4要素分のデータを書き込みます。
これまでのところ、とても良いです。さて、私はこの概念を拡張したいとしましょう。
int a = 100;
int b = 200;
char* str = “My dog has fleas”
int c = 300;
論理的に次のようになります:
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
--------------------------------------------------------------------------------------
[ 100 ] [ 200 ] M y d o g h a s f l e a s \0 [ 300 ]
が、私はこの内の配列にデータを格納できるようにする必要があるのは、私がこの順で、私の配列に次を保存したいとしましょうその後、アレイ構造を事前に知っていれば、アレイを読み取ることができます。私のコード&の出力は以下の通りです。あらかじめ長い間ご容赦ください。それはコンパイルされますが動作しません。私のデバッガでそれを精査することは非常に混乱しています。私はどこで(そしてどのくらいの頻度で)オフトラックに行くのかは分かりません。誰かが洞察力やアドバイスを持っているなら、私はとても感謝しています。
int main(){
static char arr[1000];
int a = 100;
int b = 200;
char* str = "My dog has fleas";
int c = 300;
// Create pointers to load data:
int* ptrA = arr; // points to start of array
int* ptrB = ptrA + sizeof(int); // points 4 bytes into array
char* ptrStr = ptrB + sizeof(int); // points 8 bytes into array
int* ptrC = ptrStr + sizeof("My dog has fleas"); // points to after the string
// (I don't know how to use sizeof() to measure the actual length of the string
// Load data into my array
*ptrA = a; // Assign int 100 into the array?
*ptrB = b; // Assign int 200 into the array?
*ptrStr = memcpy(ptrStr, str, sizeof("My dog has fleas")); // Write "My dog has fleas" into the array?
*ptrC = c; // Assign int 300 into the array?
// Knowing the array's structure, walk it and print results:
char* walkIt = arr;
int counter = 0;
while (counter < 30) {
if (counter == 0) {
// we are pointing at what should be the first int
int* tmpPtr1 = (int*)walkIt;
printf("%d ", *tmpPtr1);
}
else if (counter == 4) {
// we are pointing at what should be the second int
int* tmpPtr2 = (int*)walkIt;
printf("%d ", *tmpPtr2);
}
else if (counter == 8) {
// we are pointing at what should be the string
printf("%s ", walkIt);
}
else if (counter == 25) {
// we are pointing at what should be the third int
int* tmpPtr3 = (int*)walkIt;
printf("%d ", *tmpPtr3);
}
walkIt++; // Continue walking the array
counter++; // Don't walk too far
}
return 0;
}
出力がこれです:それは別のへのポインタをキャストして得られたポインタを参照解除、ボンネットの下に物事は多分そのようになるというのは本当だが
100 0 0
'memcpy(ptrStr、str、sizeof("私の犬はノミがあります) "))'。文字列の 'sizeof'はあなたが望む結果を与えるわけではありません。それはちょうどあなたのポインタのサイズを返します。代わりに 'strlen'を使用してください。あるいは、 'strcpy'を使ってコピーを行います。 – kaylum
私はこの練習のポイントが何であるか完全には分かっていませんが、あなたの教授はあなたに不満を与えているようです。 'char'の配列の全部または一部に' int'や他の非'char'型のようにアクセスすることは、C言語では有効ではありません。 –
あなたの教授は、あなたがしていることが[厳密なエイリアシングルール](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule)に違反しているので間違っています。最適化。この目的のために 'union'を使う方が良いでしょう。 – Jack