1樓:
開始你可能看不懂,不必深究,這個得慢慢去體會,用的多了沒準哪天就開竅了。如果有問題再說。
2樓:XYZ指示物
一般人會想用typeid(expr).name() 比如typeid((a)).name()
有些人可能會想到用decltype+模板然後自己輸出這樣就能不丟失&和&&和CV之類的資訊
然而我研究上述方法後得出了乙個終極大招template
T>struct type_dumper ;使用方法 type_dumper dump; 比如 type_dumper dump; 編譯然後你就會得到診斷資訊類似如下error: static_assert failed "type dump" note: in instantiation of template class 'type_dumper' requested here 於是乎你就精確地得知了乙個表示式的型別當然type_dumper的實現無論反正報錯就好了 3樓:李鵬 試著來回答一下這個問題,如有錯誤,一定要幫我指出來哈。 先說結論,C語言裡,陣列名是「不可修改的左值」。 在C語言裡,變數有左值和右值之分。 比如 x = y;中,x為左值,y為右值。區別如下: x代表乙個記憶體位址,y代表的是某個記憶體位址中存放的內容。 x在編譯時已知,y在執行時才可知。 不過,陣列名卻是另類的存在。 陣列名代表的是內容還是位址?是位址。所以陣列名是左值。 陣列名可以被修改被賦值嗎?不可以。而左值是可以的。這跟左值矛盾。 為此,在新的ANSI C標準中,x已不再稱作左值,而稱作「可修改的左值」。 「可修改」意味著它可以被賦值。 而陣列名是「不可修改的左值」,它不能被賦值。 那麼,陣列名是指標常量還是指標變數?都不是。它只是有點像指標常量而已。 在C裡,指標和陣列給人一種錯覺,認為它們是相同的。其實完全不同。 比如:int a[10]; int *p; 陣列名a裡存放了乙個位址,這個位址的內容是乙個int型整數。 指標p也存放了乙個位址,這個位址的內容是另外乙個位址(一般是乙個long型整數)。 4樓:wcy123 #include #include #include void foo( const char *file ,int line ,const char*s ,void*p )#define FOO(x) foo(__FILE__,__LINE__,#x,((void*)(x))) intmain (int argc ,char *argv )程式輸出結果 gcc -O3 junk.c && ./a.out junk.c:13 0x7fff846d9040 junk junk.c:14 0x7fff846d9040 &junk junk.c:14 0x7fff846d9040 junk[0] junk.c:15 0x7fff846d9040 &junk[0] junk.c:16 0x7fff846d9040 &junk[0][0] 可以看到,這五個東西都是同樣的值。 在組合語言看來,這五個東西沒有區別。 C 語言中陣列的概念是乙個十分醜陋的設計。我寧願把它看作是語法糖。 就是說,用這種語法,可以方便的描述一連串記憶體的值,也方便計算元素位址的偏移量。 但無論如何,他就是一塊連續的記憶體。 記得很早以前我面試的時候,有人問我 C 語言裡面指標和陣列有啥區別,我腦子裡面想的是彙編,脫口說,沒有區別。從面試官鄙夷的表情上看到,我明顯回答錯了。我臨場反應慢,沒有想到怎麼解釋這個就是乙個語法糖,本質上沒有區別。 何為本質,看機器語言。 0000000000400410 : 400410: 48 83 ec 68sub $0x68,%rsp 400414: 41 b8 51 06 40 00 mov $0x400651,%r8d 40041a: ba 0d 00 00 00 mov $0xd,%edx 40041f: 48 89 e1mov %rsp,%rcx 400422: be 56 06 40 00 mov $0x400656,%esi 400427: bf 44 06 40 00 mov $0x400644,%edi 40042c: 31 c0xor %eax,%eax 40042e: e8 ad ff ff ff callq 4003e0 400433: 48 89 e1mov %rsp,%rcx 400436: 41 b8 5e 06 40 00 mov $0x40065e,%r8d 40043c: ba 0e 00 00 00 mov $0xe,%edx 400441: be 56 06 40 00 mov $0x400656,%esi 400446: bf 44 06 40 00 mov $0x400644,%edi 40044b: 31 c0xor %eax,%eax 40044d: e8 8e ff ff ff callq 4003e0 400452: 48 89 e1mov %rsp,%rcx 400455: 41 b8 5d 06 40 00 mov $0x40065d,%r8d 40045b: ba 0f 00 00 00 mov $0xf,%edx 400460: be 56 06 40 00 mov $0x400656,%esi 400465: bf 44 06 40 00 mov $0x400644,%edi 40046a: 31 c0xor %eax,%eax 40046c: e8 6f ff ff ff callq 4003e0 400471: 48 89 e1mov %rsp,%rcx 400474: 41 b8 66 06 40 00 mov $0x400666,%r8d 40047a: ba 10 00 00 00 mov $0x10,%edx 40047f: be 56 06 40 00 mov $0x400656,%esi 400484: bf 44 06 40 00 mov $0x400644,%edi 400489: 31 c0xor %eax,%eax 40048b: e8 50 ff ff ff callq 4003e0 400490: 31 c0xor %eax,%eax 400492: 48 83 c4 68add $0x68,%rsp 400496: c3retq 可以看到,每次呼叫 printf 之前,都是 "mov %rsp, %rcx" ,"%rsp" 就是這五個東西, 儘管語法亂七八糟,編譯出來的都是 "%rsp" 註解linux ABI $rcx 是第四個引數 因為用了 -O3 優化,foo 被 inline 展開了。 mov $0x400644 %rdi 是第乙個引數,"%s:%d %p %s" 這個常量字串。可以看到常量儲存的位置。 mov $0x400656, %esi 是第二個引數 "junk.c" 字串常量,可以看到同名常量字串有的時候會被合併。 mov $0xf, %edx 是第三個引數, line 開頭的 sub $0x68,%rsp 表示申請內存在 stack 上。3x4x8 = 0x60 ,怎麼多出來乙個 long long? 這個我搞不懂 5樓:啊魚 為什麼非要把陣列說成指標, 雖然陣列和指標有些不倫不類的關係,但是, 為什麼非要把陣列說成指標, 陣列就陣列,指標就指標,多好, 只不過是陣列名有時可以當成首位址使用, 為什麼非要把陣列說成指標, 按照 C 的寫法應該是 int p 4 但是既然是用 C 最好的方法還是用模板容器 using arr type std vector array 4 arr typep1 arr typep2 arr typep3 arr typep4 arr typep5 然後想要拷貝 std vector p... d41d8c 結構體的拷貝建構函式中,陣列可以拷貝。lambda的拷貝捕獲可以捕獲陣列 int a 2 a structured binding也可以產生陣列的拷貝 int a 2 auto x,y a 中,x和y繫結到a的副本中的元素。甚至char a asdf 這種初始化也可以看作陣列拷貝的特例... 不對,C 中定義的陣列,在記憶體分配上都是分配一塊連續的記憶體來儲存的,這個是不用懷疑的。問題分析 C 中,陣列在記憶體中的分配有靜態分配和動態分配兩種。靜態陣列建立的方式為 A a,它在棧上分配空間 動態陣列建立的方式是使用new 或 malloc在堆上分配。靜態分配 intarr 10 inta...C 中如何建立乙個不定長陣列的陣列指標?
為什麼c 中陣列不能直接拷貝給另一陣列?
c 定義全域性陣列,當陣列很大時,位址是不連續的嗎