1. 程式人生 > >C進階3

C進階3

//----------------------------------------------------
字串:有序字元的集合。
C語言中沒有字串的概念,字串是以“\0”結尾的字元陣列。
字串字面量的本質是一個數組,可以看做常量指標,字元不可改變,至少包含一個字元“\0”.

#include <stdio.h>
int main()
{
   

     char ca[] = {'H', 'e', 'l', 'l', 'o'};
        char sa[] = {'W', 'o', 'r', 'l', 'd', '\0'};
        char ss[] = "Hello world!";
        char* str = "Hello world!";
        
    printf("%s\n", ca);  //error,%s為字串
    printf("%s\n", sa);
    printf("%s\n", ss);
    printf("%s\n", str);
    
    return 0;
}

#include <stdio.h>
int main()
{
    char b = "abc"[0];    
    char c = *("123" + 1);
    char t = *"";         
    
    printf("%c\n", b);// a
    printf("%c\n", c);// 2
    printf("%d\n", t);// 0
    
    printf("%s\n", "Hello");
    printf("%p\n", "World");
    
    return 0;
}

//--------------------------------------
snprintf函式本身是可變引數函式,原型:
int snprintf(char* buffer,int buf_size,const char*fomart,…)
當函式只有3個引數時,如果第三個引數沒有包含格式化資訊,函式呼叫
沒有問題;相反,如果第三個引數包含了格式化資訊,但缺少後續對應引數,則程式
行為不確定。
例:

int main()
    {
    char buf[10] = {0};
    char src[] = "hello %s";  
    snprintf(buf,sizeof(buf),src);
    printf(“buf = %s\n”,buf);
    return 0;
    }

注:%s替換為 dt等量;或者保留%s,src改為src,“DT”
//-------------------------------------------------

#include <string.h>
int main()
{
    #define STR "Hello, \0D.T.Software\0"
    
    char* src = STR;
    char buf[255] = {0};
    
    snprintf(buf, sizeof(buf), src);
    
    printf("strlen(STR) = %d\n", strlen(STR)); // 7
    printf("sizeof(STR) = %d\n", sizeof(STR)); // 22
    
    printf("strlen(src) = %d\n", strlen(src)); // 7
    printf("sizeof(src) = %d\n", sizeof(src)); // 4
    
    printf("strlen(buf) = %d\n", strlen(buf)); // 7
    printf("sizeof(buf) = %d\n", sizeof(buf)); // 255
    
    printf("src = %s\n", src);  //  Hello,
    printf("buf = %s\n", buf);  //   Hello,
    
    return 0;
}

注:字串相關函式均以第一個出現的‘\0’作為結束符。
字串之間的相等比較需要用strcmp完成,不可直接用進行比較。
一些現代編譯器能將相同的字串字面量對映到同一個無名字元陣列,因此
為true。
//------------------------------------------------
▲字串的移動:

#include <stdio.h>
#include <string.h>

void right_shift_r(const char* src, char* result, unsigned int n)
{
    const unsigned int LEN = strlen(src);
    int i = 0;
        
    for(i=0; i < LEN; i++)
    {
        result[(n + i) % LEN] = src[i];
    }
    
    result[LEN] = '\0';
}

int main()
{
    char result[255] = {0};
    
    right_shift_r("abcde", result, 2);
    
    printf("%s\n", result);
    
    right_shift_r("abcde", result, 5);
    
    printf("%s\n", result);
    
    right_shift_r("abcde", result, 8);
    
    printf("%s\n", result);
    
    return 0;
}

//---------------------------------------------------
int array[5]的型別為int[5].
C語言中通過typedef為陣列型別重新命名:typedef type(name)[size]
陣列型別:typedef int(AINT5)[5];typedef float(AFLOAT10)[10];
陣列定義:AINT5 iArray;AFLOAT10 fArray;
可通過陣列型別定義陣列指標:ArrayType* pointer;
也可以直接定義:type(*pointer)[n];pointer為陣列指標變數名,type為指向的陣列的型別。

#include <stdio.h>

typedef int(AINT5)[5];
typedef float(AFLOAT10)[10];
typedef char(ACHAR9)[9];

int main()
{
    AINT5 a1;
    float fArray[10];
    AFLOAT10* pf = &fArray;
    ACHAR9 cArray;

    char(*pc)[9] = &cArray;
    char(*pcw)[4] = cArray; //error
    
    int i = 0;
    
    printf("%d, %d\n", sizeof(AINT5), sizeof(a1)); // 20,20
    
    for(i=0; i<10; i++)
    {
        (*pf)[i] = i;    //==>fArray[i]=i
    }
    
    for(i=0; i<10; i++)
    {
        printf("%f\n", fArray[i]);
    }
    
    printf("%p, %p, %p\n", &cArray, pc+1, pcw+1);

    return 0;
}

注:指標的運算,pc+1==>(unsigned int)pc + sizeof(pc)
//----------------------------------------
指標陣列:type
pArray[n];type*為陣列中每個元素的型別,pArray為陣列名,n為陣列大小。

#include <stdio.h>
#include <string.h>

#define DIM(a) (sizeof(a)/sizeof(*a))

int lookup_keyword(const char* key, const char* table[], const int size)
{
    int ret = -1;
    
    int i = 0;
    
    for(i=0; i<size; i++)
    {
        if( strcmp(key, table[i]) == 0 )
        {
            ret = i;
            break;
        }
    }
    
    return ret;
}

int main()
{
    const char* keyword[] = {
            "do",
            "for",
            "if",
            "register",
            "return",
            "switch",
            "while",
            "case",
            "static"
    };
    
    printf("%d\n", lookup_keyword("return", keyword, DIM(keyword)));
    printf("%d\n", lookup_keyword("main", keyword, DIM(keyword)));

    return 0;
}

//-------------------------------------------------------------
main函式是作業系統呼叫的函式,有引數和返回值。
現代編譯器支援在main之前呼叫其他函式。
▲重置動態空間大小:

#include <stdio.h>
#include <malloc.h>

int reset(char**p, int size, int new_size)
{
    int ret = 1;
    int i = 0;
    int len = 0;
    char* pt = NULL;
    char* tmp = NULL;
    char* pp = *p;
    
    if( (p != NULL) && (new_size > 0) )
    {
        pt = (char*)malloc(new_size);
        
        tmp = pt;
        
        len = (size < new_size) ? size : new_size;
        
        for(i=0; i<len; i++)
        {
            *tmp++ = *pp++;      
        }
        
        free(*p);
        *p = pt;
    }
    else
    {
        ret = 0;
    }
    
    return ret;
}

int main()
{
    char* p = (char*)malloc(5);
    
    printf("%p\n", p);
    
    if( reset(&p, 5, 3) )
    {
        printf("%p\n", p);
    }

    free(p);
    
    return 0;
}

//-------------------------------------------
二維陣列:
▲遍歷二維陣列

#include <stdio.h>
#include <malloc.h>

void printArray(int a[], int size)
{
    int i = 0;
    
    printf("printArray: %d\n", sizeof(a));

    for(i=0; i<size; i++)
    {
        printf("%d\n", a[i]);
    }
}

int main()
{
    int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
    int* p = &a[0][0];
    
    int i = 0;
    int j = 0;
    
    for(i=0; i<3; i++)
    {
        for(j=0; j<3; j++)
        {
            printf("%d, ", *(*(a+i) + j));
        }
        
        printf("\n");
    }
    
    printf("\n");
    
    printArray(p, 9);
    
    return 0;
}

▲動態申請二維陣列空間

#include<stdio.h>
#include<malloc.h>
int** malloc2d(int row,int col)
{
   int** ret = NULL;
   if((row > 0)&& (col > 0))
   {
     int* p = NULL;
	 ret = (int**)malloc(row * sizeof(int*));
	 p = (int*)malloc(row * col);
	 if((ret != NULL)&& (p != NULL))
	 {
	   int i = 0;
	   for(i=0;i<row;i++)
	   {
	    ret[i] = p + i * col;
	   }
	 }
	 else
	   {
	     free(ret);
		 free(p);
		 ret = NULL;
	   }
	 
	}
   return ret;
 }

void free2d(int** p)
{
    if( *p != NULL )
    {
        free(*p);
    }
    
    free(p);
}

int main()
{
    int** a = malloc2d(3, 3);
    int i = 0;
    int j = 0;
    
    for(i=0; i<3; i++)
    {
        for(j=0; j<3; j++)
        {
            printf("%d, ", a[i][j]);
        }
        
        printf("\n");
    }
    
    free2d(a);
    
    return 0;
}

//----------------------------------------
氣泡排序:

void main()
{
 int i,j,t,a[11];
  printf("請輸入10個數:\n");
  for(i=1;i<11;i++)
    scanf("%d",&a[i]);
  for(i=1;i<10;i++)
     for(j=1;j<11-i;j++)
        if(a[j]>a[j+1])
         {
		   t = a[j];
		   a[j]=a[j+1];
		   a[j+1] = t;
		   }		
     printf("排序後的順序是:\n");
	 for(i=1;i<11;i++)
	   printf("%5d",a[i]);
	  printf("\n");
}

//------------------------------------------