亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪(fǎng)問(wèn)板塊 發(fā)新帖
查看: 2081 | 回復(fù): 4
打印 上一主題 下一主題

[C] C如何用宏區(qū)別常量資源和變量資源? [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2013-07-03 11:34 |只看該作者 |倒序?yàn)g覽
本帖最后由 true_casey 于 2013-07-03 11:35 編輯
  1. static
  2. void testB (char *src)
  3. {
  4.         /* 判斷傳入的src 是屬于 @1/2/3 ??? */
  5.         do_somthing ();
  6. }

  7. static
  8. void testA (char *src)
  9. {
  10.         char *a = "hello world";
  11.         char b[100] = "hello world";

  12.         testB (a);                                        /* @1 */
  13.         testB (b);                                        /* @2 */
  14.         testB ("hello world" );                                /* @3 */
  15. }
復(fù)制代碼
@1 有名常量
@2 緩沖資源
@3 未名常量

怎么用宏去區(qū)別???

論壇徽章:
17
處女座
日期:2013-08-27 09:59:352015亞冠之柏太陽(yáng)神
日期:2015-07-30 10:16:402015亞冠之薩濟(jì)拖拉機(jī)
日期:2015-07-29 18:58:182015年亞洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥豬
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56雙子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
2 [報(bào)告]
發(fā)表于 2013-07-03 14:40 |只看該作者
本帖最后由 myworkstation 于 2013-07-03 14:42 編輯

編譯器和語(yǔ)言并沒(méi)有直觀的提供什么功能去實(shí)現(xiàn)這個(gè)處理,可以換個(gè)思路,在C中有四個(gè)存儲(chǔ)類(lèi)型static,automatic,register,dynamic。每種類(lèi)型的存儲(chǔ)的地址都是可識(shí)別的,通過(guò)對(duì)存儲(chǔ)地址的判斷可以識(shí)別實(shí)事的變量或常量變型。
char *a = "hello world";testB (a); 和 testB ("hello world" );  這兩個(gè)調(diào)用實(shí)際上是一樣的。編譯器在處理的時(shí)候會(huì)把對(duì)hello world的變引指向相同的地方(編譯器基本都這么進(jìn)行優(yōu)化處理,不屬于標(biāo)準(zhǔn)規(guī)定)。根據(jù)上述說(shuō)法那下面的公式成立:編譯器對(duì)常量變量的內(nèi)存處理策略+操作系統(tǒng)的內(nèi)存布局=可明確定位的內(nèi)存識(shí)別。由于操作系統(tǒng)的內(nèi)存布局因系統(tǒng)而定,編譯器的實(shí)現(xiàn)也各有不同,所以就算得出結(jié)論要實(shí)現(xiàn)相關(guān)處理的代碼也是很難進(jìn)行移植的。下面是完成相關(guān)功能的代碼在linux下測(cè)試通過(guò)。
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4.     int global_dummy = 0;
  5.     static
  6.     void testB (char *src)
  7.     {
  8.             /* 判斷傳入的src 是屬于 @1/2/3/4*/
  9.             int local_dummy = 0;
  10.             if( (unsigned long)src < (unsigned long )&local_dummy ){
  11.                 //if( src > testB ){
  12.                     if(  (unsigned long )src <  (unsigned long )&global_dummy ){
  13.                         printf("string literal\n\n");
  14.                     }
  15.                     else if (  (unsigned long ) src > (unsigned long ) &global_dummy){
  16.                         printf("malloc string\n\n");
  17.                     }
  18.                 //}
  19.             }
  20.             else
  21.             {
  22.                 printf("array: stack\n\n");
  23.             }
  24.     }
  25.     static
  26.     void testA ()
  27.     {
  28.             char *a = "hello world";
  29.             char b[100] = "hello world";
  30.             char *c = malloc(100);
  31.             strcpy(c,a);
  32.             printf("char *a = \"hello world\";\n");
  33.             testB (a);                                        /* @1 */
  34.             printf("char b[100] = \"hello world\";\n");
  35.             testB (b);                                        /* @2 */
  36.             printf(" (\"hello world\" )\n");
  37.             testB ("hello world" );                                /* @3 */
  38.             printf("char *c = malloc(100);\n");
  39.             testB (c );                                /* @4 */
  40.             free(c);
  41.     }

  42. int main(int argc,const char** argv)
  43. {
  44.     testA();
  45.     return 0;
  46. }
復(fù)制代碼
程序的運(yùn)行結(jié)果如下:
char *a = "hello world";
string literal

char b[100] = "hello world";
array: stack

("hello world" )
string literal

char *c = malloc(100);
malloc string


下面貼個(gè)linux下程序運(yùn)行的內(nèi)存布局圖,可以加深對(duì)上述代碼的理解

論壇徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16賽季CBA聯(lián)賽之青島
日期:2016-07-05 12:36:0515-16賽季CBA聯(lián)賽之廣東
日期:2016-06-29 11:45:542015亞冠之全北現(xiàn)代
日期:2015-07-22 08:09:472015年辭舊歲徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39獅子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技術(shù)圖書(shū)徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
3 [報(bào)告]
發(fā)表于 2013-07-03 15:51 |只看該作者
char *a = "hello world";
之所以能編譯通過(guò),是因?yàn)榫幾g器網(wǎng)開(kāi)一面,以照顧舊有的海量代碼。但不等于說(shuō) a[] 就是可寫(xiě)的,碼農(nóng)得自己保證不修改a[]值。
換種說(shuō)法,看到以前代碼中 char *a = "hello world"; 就不用改了,能編譯通過(guò);但正在寫(xiě)的代碼,可不能這樣,得寫(xiě)成正確的 const char *a = "hello world";

論壇徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16賽季CBA聯(lián)賽之江蘇
日期:2017-11-27 11:42:3515-16賽季CBA聯(lián)賽之八一
日期:2017-04-12 14:26:2815-16賽季CBA聯(lián)賽之吉林
日期:2016-08-20 10:43:1215-16賽季CBA聯(lián)賽之廣夏
日期:2016-06-23 09:53:58程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-02-11 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-02-09 06:20:0015-16賽季CBA聯(lián)賽之上海
日期:2015-12-25 16:40:3515-16賽季CBA聯(lián)賽之廣夏
日期:2015-12-22 09:39:36程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-08-24 06:20:002015亞冠之德黑蘭石油
日期:2015-08-07 09:57:302015年辭舊歲徽章
日期:2015-03-03 16:54:15
4 [報(bào)告]
發(fā)表于 2013-07-03 17:44 |只看該作者
屌爆了,完全不懂{:3_188:}

論壇徽章:
17
處女座
日期:2013-08-27 09:59:352015亞冠之柏太陽(yáng)神
日期:2015-07-30 10:16:402015亞冠之薩濟(jì)拖拉機(jī)
日期:2015-07-29 18:58:182015年亞洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥豬
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56雙子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
5 [報(bào)告]
發(fā)表于 2013-07-03 18:28 |只看該作者
回復(fù) 3# bruceteen


    你的提醒很有必要,這個(gè)行為在不同的c和c++的編譯器上有會(huì)不同的行為,應(yīng)該說(shuō)char *a = "hello world";這種寫(xiě)法不能算錯(cuò)誤的寫(xiě)法,所以c編譯器不報(bào)錯(cuò)也不警告,就此問(wèn)題稍微展開(kāi)一下,說(shuō)說(shuō)這個(gè)做具體會(huì)有什么樣的行為。早期的K&C認(rèn)為這是完全合法的,但從K&C第二版標(biāo)準(zhǔn)開(kāi)始就明確指出“修改string literal的結(jié)果是未定義的,字符串并不總是可修改的,可能會(huì)放在只讀內(nèi)存區(qū)域“。從C89開(kāi)始,這個(gè)問(wèn)題有了更明確的規(guī)定。char *a = "hello world";定義a是一種字符指針類(lèi)并使用指定的字符數(shù)組(類(lèi)型為array of char)“hello world"初始化,如果試圖修改數(shù)組的內(nèi)容行為將是未定義的。關(guān)鍵的解釋就在"未定義“這個(gè)解釋上,實(shí)際上未定義不是錯(cuò)誤,它在這里表示代碼不可移值。所以在c89和c99規(guī)范的”公共擴(kuò)展“部分有如下規(guī)則:String literals是可修改的,此時(shí)指向另外一個(gè)內(nèi)容完全相同的對(duì)象。在c++中則有區(qū)別,c++2003標(biāo)準(zhǔn)規(guī)定string literal是由const字符數(shù)組構(gòu)成的(array of n const char),所以C++明確了string literal是不可修改的。C++沒(méi)有規(guī)定所有內(nèi)容相同的string literal會(huì)指向同一個(gè)對(duì)象(相同的內(nèi)容指向唯一的對(duì)象),這是由編譯器實(shí)現(xiàn)決定的,同時(shí)指出了試圖修改string literal的行為是未定義的。為了兼容C,所以不加const 的char*依然是可用的,但通常編譯器會(huì)給出警告。最后C++標(biāo)準(zhǔn)明確規(guī)定不贊成這樣做(deprecated)!⌒揎棡閐eprecated表示將來(lái)不再支持這個(gè)特性。


這個(gè)問(wèn)題要解釋清楚就得看標(biāo)準(zhǔn)了。下面是相關(guān)標(biāo)準(zhǔn)中的信息摘要:

C99
char *p = "abc";
defines p with type ‘‘pointer to char’’ and initializes it to point to an object with type ‘‘a(chǎn)rray of char’’
with length 4 whose elements are initialized with a character string literal. If an attempt is made to use p to
modify the contents of the array, the behavior is undefined.

J.5.5 Writable string literals
1 String literals are modifiable (in which case, identical string literals should denote distinct
objects) (6.4.5).

C++2003
An ordinary string literal has type “array of n
const char” and static storage duration.

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementationdefined.
The effect of attempting to modify a string literal is undefined.

D.4 Implicit conversion from const strings [depr.string]
1 The implicit conversion from const to non-const qualification for string literals (4.2) is deprecated.
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專(zhuān)區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP