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");
}
//------------------------------------------