たとえば、データ型があり、その型の変数またはポインターを宣言せずに、そしてもちろん演算子X
を使用せずに、そのサイズを知りたいです。sizeof
これは可能ですか?データ型のサイズと範囲を含む標準のヘッダー ファイルを使用することを考えましたが、それはユーザー定義のデータ型では機能しません。
私の考えでは、これは「++、+=、または + を使用せずに 2 つの int を追加するにはどうすればよいですか?」というカテゴリに当てはまります。時間の無駄です。このようなことを行うことで、未定義の動作のモンスターを回避しようとすることができます.
size_t size = (size_t)(1 + ((X*)0));
型の変数または へのポインターを宣言していないことに注意してくださいX
。
ほら、これsizeof
は言語機能です。唯一のものなので、これを実現するための唯一の移植可能な方法です。
いくつかの特殊なケースでは、特定のオブジェクトのサイズを理解するために他のヒューリスティックを使用する移植不可能なコードを生成することができます[*] (おそらくオブジェクトに独自のサイズを追跡させることにより)が、すべての簿記を自分で行う必要があります。 .
[*] OOP の意味ではなく、非常に一般的な意味のオブジェクト。
まあ素人ですが、この問題をやってみたらsizeofを使わずに正解できました。これが役立つことを願っています..整数のサイズを見つけようとしています。
int *a,*s, v=10;
a=&v;
s=a;
a++;
int intsize=(int)a-(int)s;
printf("%d",intsize);
このインタビューの質問に対する正しい答えは、「sizeof() が私のためにそれを行い、そうする唯一の移植可能な方法であるのに、なぜ私はそれをしたいのですか?」です。
パディングの可能性は、それを導入するために使用されるルールの知識がなければ、すべての希望を防ぎます. そして、それらは実装に依存します。
Xがデータ型の場合:
#define SIZEOF(X) (unsigned int)( (X *)0+1 )
Xが変数の場合:
#define SIZEOF(X) (unsigned int)( (char *)(&X+1)-(char *)(&X) )
特定のプロセッサのABIを読むと、構造がメモリ内でどのように配置されるかが説明されています。プロセッサごとに異なる可能性があります。sizeof
しかし、コンパイラを書いているのでない限り、この問題を解決する唯一の正しい方法であるだけを使いたくないのは驚くべきことです。
これを試して:
int a;
printf("%u\n", (int)(&a+1)-(int)(&a));
コンパイラのソースを調べてください。あなたが得るでしょう:
そしてこれから、何かの予想サイズ。
少なくとも変数にスペースを割り当て、センチネル値を入力できれば、少しずつ変更して値が変化するかどうかを確認できますが、それでもパディングに関する情報はわかりません。
これがコードです。トリックは、ポインタオブジェクトを作成し、そのアドレスを保存し、ポインタをインクリメントしてから、前のアドレスから新しいアドレスを減算することです。重要なポイントは、ポインタがインクリメントされるとき、実際にはそれが指しているオブジェクトに等しいサイズで移動することです。したがって、ここではクラス(そのオブジェクトが指しているオブジェクト)のサイズです。
#include<iostream>
using namespace std;
class abc
{
int a[5];
float c;
};
main()
{
abc* obj1;
long int s1;
s1=(int)obj1;
obj1++;
long int s2=(int)obj1;
printf("%d",s2-s1);
}
よろしく
これらの回答の多くは、構造がどのように見えるかを知っていることを前提としています。このインタビューの質問は、既成概念にとらわれずに考えるように求めることを意図していると思います。答えを探していましたが、ここで気に入った解決策が見つかりませんでした。私はより良い仮定をします
struct foo {
int a;
banana b;
char c;
...
};
foo[2] を作成すると、メモリ内に 2 つの連続する foo オブジェクトが作成されます。そう...
foo[2] buffer = new foo[2];
foo a = buffer[0];
foo b = buffer[1];
return (&b-&a);
私のポインター演算が正しく行われたと仮定すると、これがチケットになるはずです-そしてそのポータブルです! 残念ながら、パディング、コンパイラ設定などもすべて役割を果たします。
考え?
# include<stdio.h>
struct node
{
int a;
char c;
};
void main()
{
struct node*ptr;
ptr=(struct node*)0;
printf("%d",++ptr);
}
main()
{
clrscr();
int n;
float x,*a,*b;//line 1
a=&x;
b=(a+1);
printf("size of x is %d",
n=(char*)(b)-(char*)a);
}
このコード スクリプトでは、sizeof 演算子を使用せずに任意のデータのサイズを計算できます。1 行目の float を、計算したいサイズの型に変更するだけです。
#include <stdio.h>
struct {
int a;
char c;
};
void main() {
struct node*temp;
printf("%d",(char*)(temp+1)-(char*)temp);
}
これを試して、
#define sizeof_type( type ) ((size_t)((type*)1000 + 1 )-(size_t)((type*)1000))
次のユーザー定義データ型の場合、
struct x
{
char c;
int i;
};
sizeof_type(x) = 8
(size_t)((x*)1000 + 1 ) = 1008
(size_t)((x*)1000) = 1000
これは、C++ バイトが常に 8 バイナリ ビットであるとは限らないこと、および符号なしの型のみが明確に定義されたオーバーフロー動作を持つことを考慮に入れています。
#include <iostream>
int main () {
unsigned int i = 1;
unsigned int int_bits = 0;
while (i!=0) {
i <<= 1;
++int_bits;
}
unsigned char uc = 1;
unsigned int char_bits = 0;
while (uc!=0) {
uc <<= 1;
++char_bits;
}
std::cout << "Type int has " << int_bits << "bits.\n";
std::cout << "This would be " << int_bits/8 << " IT bytes and "
<< int_bits/char_bits << " C++ bytes on your platform.\n";
std::cout << "Anyways, not all bits might be usable by you. Hah.\n";
}
#include
<limit>
確かに、またはだけでもかまいません<climits>
。
#include <bits/stdc++.h>
using namespace std;
int main()
{
// take any datatype hear
char *a = 0; // output: 1
int *b = 0; // output: 4
long *c = 0; // output: 8
a++;
b++;
c++;
printf("%d",a);
printf("%d",b);
printf("%d",c);
return 0;
}