C語(yǔ)言中的一些小坑記錄(sizeof,函數(shù)指針,長(zhǎng)字符的值)

說(shuō)在前面

好久都沒(méi)有用過(guò)c了(之前用c++寫(xiě)過(guò)合數(shù)fft,算法而言沒(méi)有遇到很多坑),好像以前學(xué)習(xí)的時(shí)候也沒(méi)怎么學(xué)。某些知識(shí)點(diǎn)很容易遺忘,稍微寫(xiě)點(diǎn)東西記錄一下。以下內(nèi)容僅用于學(xué)習(xí)用途,不可以用作其他用途。



tips:所有思考題的答案都在文末


1 字符類型和數(shù)字
int a = '12'; // 默認(rèn)256進(jìn)制,且數(shù)字為ascii的值
/**有 ‘\’存在時(shí)有少許變化*/
int b = '\0' ;//后面跟0到2位8進(jìn)制,之后全為256進(jìn)制
int c = '\???' ; // \ 后面的?可以為8進(jìn)制,第一位為0參照上一條,否則后面跟0到2位8進(jìn)制,之后全為256進(jìn)制
int e = '\x';//這種方式x后面跟0到2位16進(jìn)制(與x連接的0最后一個(gè)有效,如\x000aa = \x0aa),最多兩位(不含無(wú)效0),之后全為256進(jìn)制

思考題 char a = '00'; a = ?;



2 sizeof 和 struct
  struct A{
    
    int a;
    char b[5];
    int c;
    short d;
  };
  
struct B{
    
    int a;
    char b[5];
    short d;
    int c;
  };

  sizeof(A) == sizeof(B) // false
//這里false的原因主要是內(nèi)存字節(jié)對(duì)齊導(dǎo)致的,內(nèi)存的字節(jié)對(duì)齊默認(rèn)是結(jié)構(gòu)體基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)里面最大的為準(zhǔn)。
//A 和 B 明明是一樣的變量 但sizeof(A) = 20,sizeof(B) = 16,所以對(duì)齊采用相對(duì)良好的設(shè)計(jì)會(huì)節(jié)省很多內(nèi)存。
// 具體對(duì)齊方式的話 按照結(jié)構(gòu)體的順序放入到內(nèi)存,盡可能的保證內(nèi)存不切片。如下所示(假設(shè)每個(gè)片段為4字節(jié))
//      Mem                          A                             B
//1      0x1000                      a                              a
//2      0x1004                     b[0]~b[4]                 b[0]~b[4]
//3------0x1008                     b[5]                         b[5],d             
//4      0x100c                      c                                c
//5      0x1010                      d                                

//第三行的話,由于片段大小為4, 所以不能同時(shí)放下 b[5] 和c 但可以放下 b[5] 和 d
//記筆記,從內(nèi)存地址取值的時(shí)候,如果把c切片成3字節(jié)放在第三行,剩下一個(gè)字節(jié)放在第四行,這樣子對(duì)c的讀取就會(huì)需要兩次讀取,會(huì)降低效率的

// 結(jié)構(gòu)體含結(jié)構(gòu)體的情況,計(jì)算最大對(duì)齊內(nèi)存只需要計(jì)算基礎(chǔ)類型

思考題

struct A{ char a; int b;double c ;int d ; };
struct B{ int a;short b;char c[8];struct A d; int e;unsigned int f; };
sizeof(B) = ?

3 函數(shù)指針
/**聲明*/
int *(*p)();
void (*p)(void *,int);

思考題 描述一下p((void *) &q) 的執(zhí)行過(guò)程

void q(void *);
void p(void *a){
   ((void (*)(void *)) a)((void *)&q);
};
void q(void *a){
    ((void (*)(void *)) a)((void *)&p);
};
4 const
  char * const p = "123456";
  char *n = (char*)malloc(10);
  strcpy(n,"123456");
  char const * q = n;
  const char * m = "123456";

  q++;//q  "23456\0"
  m++;//m  "23456\0"    
  p++;// err
  q[0] = '0';//err
  m = '0';//err
  p = '0';// p  "023456\0"
//const 修飾的不能改變,僅限修飾的對(duì)象

思考題 const char * a = "123456"; a[0] = '\0'; printf(a);

5 typedef

主要是用于方便,沒(méi)啥好記錄的

typedef char * charptr;
typedef void (*p)(void *,int);

//使用
charptr a = 0,b = 0;
void func(p a){
    if(a == NULL) return ;
    a(0,0);
}
6 string

strcpy ,memcpy,memmove,等使用不當(dāng)會(huì)訪問(wèn)到非法內(nèi)存(不是自己申請(qǐng)的空間)。

令人激動(dòng)的答案

  1. '0' (不管大小端機(jī)器的都是0)
  2. 48 (仔細(xì)看注釋就明白了)
  3. 題意可能有點(diǎn)蒙,也可能蒙得出來(lái),對(duì),這就是一個(gè)循環(huán)
  4. (a[0] = '\0' 就算沒(méi)有const都會(huì)報(bào)錯(cuò)!)自己去執(zhí)行看看,這個(gè)解釋起來(lái)沒(méi)意思了呀

結(jié)語(yǔ),C語(yǔ)言總的來(lái)說(shuō)還是不錯(cuò)的,輕便易使用,但是我好像好幾年都沒(méi)有接觸過(guò)這些即使我學(xué)過(guò)。

有問(wèn)題可以給我發(fā)郵件 yoghourtrain@gmail.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容