C語言基礎

一、C語言中判斷數據類型或者表達式長度符;不是一個函數,字節數的計算在程序編譯時進行,而不是在程序執行的過程中才計算出來。


 char str[ ]="abcd";

sizeof(str)=5

strlen(str)=4


char str[20]="0123456789";
int a=strlen(str); //a=10; >>>> strlen 計算字符串的長度,以結束符 0x00 爲字符串結束。
int b=sizeof(str); //而b=20; >>>> sizeof 計算的則是分配的數組 str[20] 所佔的內存空間的大小,不受裏面存儲的內容改變。  

二、

  void foo(void){
unsigned int a=6;
int b=-20;
if(a+b>6)printf(">6\n");
else printf(">6\n");
}


當表達式中存在有符號類型和無符號類型時所有的操作數都自動轉換爲無符號類型。因此,從這個意義上講,無符號數的運算優先級要高於有符號數,這一點對於應當頻繁用到無符號數據類型的嵌入式系統來說是豐常重要的。 

執行a+b時,b要以unsigned int的形式讀取內存中的數據,即將-20的補碼按照unsigned int的形式理解讀取(4,294,967,276)

也即:b = -20;先轉化爲 -20 + 2^32 = 4,294,967,276(unsinged int);此時與 a = 6相加必然大於 6

但是如果是與立即數操作,那麼不改變b的類型

即   int b=-20;

   b+6 是 等於-14的


三、大小端  判別 方法

  (1)int a=0x1234;
char *p=(char*)&a;
if(*p==0x12) printf("大端模式");
else if(*p==0x34) printf("小端模式");


(2)union w{
int a;
char b;
}temp;
temp.a=1;
if(temp.b==1)printf("小端模式");
else if(temp.b==0)printf("大端模式");
}


四、  求第二大數

   #include<stdio.h>
const int MINNUMBER=-32768;
void sec_max_func(int *,int);
void main(){
int arr[]={2,3,1,4};
int num=sizeof(arr)/sizeof(arr[0]);
printf("num=%d\n",num);
sec_max_func(arr,num);
}
void sec_max_func(int arr[],int num){
int i=1;;
int sec_max=MINNUMBER;
int max=arr[0];
for(;i<num;i++){
if(arr[i]>max)
  {
    sec_max=max;
    max=arr[i];
  }
else {
     if(arr[i]>sec_max)
          sec_max=arr[i];
   }
}
printf("sec_max=%d\n",sec_max);

}

五、將字符串下標m開始往後的字符複製到新字符數組中

   #include<stdio.h>
void strcopy(char *src,char *dest,int m){
char *p1,*p2;
p1=src+m;
p2=dest;
while(*p1) *(p2++)=*(p1++);
*p2='\0';
}
void main(){
int m;
char str1[100]="0123456789",str2[100];
//gets(str1);
scanf("%d",&m);
strcopy(str1,str2,m);
printf("%s\n",str2);
}

六、C 語言中

a^b是按位異或的意思

七、C語言單精度雙精度

   

如果是(輸出printf)的輸出項是double或float時,

可以用%f或%e作爲格式描述字符,(其中double也可以用%lf或%le)。

double的意思是可以有16位有效數字,

而在固定格式輸出的時候,都默認的是6位,

輸出語句printf用double的時候f前面加l是沒有效果的,

你要輸出長度,可以寫,%0.8f,這樣就是輸出8個有效數字了,要輸出幾位就改0.後面的參數。


注意:如果是(輸入scanf)的輸入項爲double時,則必須用%lf或%le(必須有個l)作爲格式描述字符。

          位於輸入項爲float與上面的一致。

  void main(){
float a=3.14;
double b=3.141592658;
printf("float=%f\n",a);
printf("double=%0.8f\n",b);
}

八、關於常量池不能被修改 是隻讀的

  main()
{
 char *s="CEAeded";
char *p=s;
*p='A';
 printf("%s\n",s);
}

該程序崩潰 

char* str = "hello"

   str = "pri"

  prinf("%s",str);有什麼問題?直接崩潰,char *s = "hello",hello存在了常量存儲區,只能讀不能修改

九、不用第三個變量即可更改兩個變量的值    經典

   int a=3,b=5;

  a=a+b;

 b=a-b;

a=a-b;

十、關於數組地址

  1、一維數組

  main()
{
 int a[]={1,2,3,4};
 int *p=(int *)(a+1);
 printf("*p=%d\n",*p);
p=(int *)(&a+1);
 printf("&a+1=%d\n",*(p-1));
 printf("*(a+1)=%d\n",*(a+1));
}

a表示數組首元素的地址 即a 與&a[0]是一樣的意義;

a+1  表示數組第二個元素的地址 即&a[1]

&a和a和&a[0]結果一樣,但是意義不同,&a表示的是指向數組的指針 (int *)(&a+1) 則指向了數組a的 a[5](當然只是這麼說,是沒有a[5]的。形象的說是偏移到了數組a的長度即sizeof(a)*sizeof(int))

2、關於二維數組     http://blog.csdn.net/david_xtd/article/details/7305586

http://blog.csdn.net/yangchang999/article/details/6664069

雖然a[0]、a都是數組首地址,但二者指向的對象不同。

a[0]是一維數組的名字,它指向的是一維數組a[0]的首元素a[0][0],對其進行“*”運算,得到的是一維數組元素a[0][0]的值即*a[0]與a[0][0]是同一個值。

而a是一個二維數組的名字,它指向的是二維數組a的首元素a[0]對a進行“*”運算,得到的是一維數組a[0]的首地址即*a與a[0]是同一個值。它的指針移動單位是“行”,所以a+i指向的是第i個行數組,即指向a[i]。

當用int *p;定義指針p時,p的指向是一個int型數據,而不是一個地址,因此,用a[0]對p賦值是正確的,而用a對p賦值是錯誤的。這一點請務必注意。

  int *p=a[0];對的

   對於二維數組a,其a[0]數組由a指向,a[1]數組則由a+1指向,a[2]數組由a+2指向,以此類推。因此,*a與a[0]等價、*(a+1)與a[1]等價、*(a+2)與a[2]等價,┅,即對於a[i]數組,由*(a+i)指向。由此,對於數組元素a[i][j],用數組名a的表示形式爲:
*(*(a+i)+j)
指向該元素的指針爲:
*(a+i)+j

十一、堆和棧的區別

一個由C/C++編譯的程序佔用的內存分爲以下幾個部分
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其
操作方式類似於數據結構中的棧。
2、堆區(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回
收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。
3、全局區(靜態區)(static)—,全局變量和靜態變量的存儲是放在一塊的,初始化的
全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另
一塊區域。 - 程序結束後由系統釋放。
4、文字常量區 —常量字符串就是放在這裏的。 程序結束後由系統釋放
5、程序代碼區—存放函數體的二進制代碼。

二、例子程序 
這是一個前輩寫的,非常詳細 
//main.cpp 
int a = 0; 全局初始化區 
char *p1; 全局未初始化區 
main() 

int b; 棧 
char s[] = "abc"; 棧 
char *p2; 棧 
char *p3 = "123456"; 123456\0在常量區,p3在棧上。 
static int c =0; 全局(靜態)初始化區 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); 
分配得來得10和20字節的區域就在堆區。 
strcpy(p1, "123456"); 123456\0放在常量區,編譯器可能會將它與p3所指向的"123456"
優化成一個地方。 
}


十二、

26. MySQL中表test選擇10條到20條記錄的語句是()
select * from test limit 10,10;     //不會MySQL,忘記關鍵字limit寫錯了。 
//多謝xiaozdong指正 
limit是mysql的語法
select * from table limit m,n
其中m是指記錄開始的index,從0開始,表示第一條記錄
n是指從第m+1條開始,取n條。
select * from tablename limit 2,4
即取出第3條至第6條,4條記錄

   十三、 關於#和##

##是連接符號,由兩個井號組成,其功能是在帶參數的宏定義中將兩個子串(token)聯接起來,從而形成一個新的子串。但它不可以是第一個或者最後一個子串。所謂的子串(token)就是指編譯器能夠識別的最小語法單元。具體的定義在編譯原理裏有詳盡的解釋。

#符是把傳遞過來的參數當成字符串進行替代


假設程序中已經定義了這樣一個帶參數的宏:
#define PRINT( n ) printf( "token" #n " = %d", token##n )
同時又定義了二個整形變量:
int token9 = 9;
現在在主程序中以下面的方式調用這個宏:
PRINT( 9 );
那麼在編譯時,上面的這句話被擴展爲:
printf( "token" "9" " = %d", token9 );
注意到在這個例子中,PRINT(9);中的這個”9”被原封不動的當成了一個字符串,與”token”連接在了一起,從而成爲了token9。而#n也被”9”所替代。

可想而知,上面程序運行的結果就是在屏幕上打印出token9=9


還有點不明白?

再來一個例子:
#define PRINT( n ) printf( "token" #n " = %d", game##n )
int token9 = 9;
int game9 = 99;
調用:
PRINT(9);
屏幕上打印出:
token9 = 99

十四、*p++ 等價於*(p++)

發佈了41 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章