//----------------------------------------------------
字符串:有序字符的集合。
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");
}
//------------------------------------------