我使用C语言并不频繁,一般都是用来实现数据结构与算法,因为面向过程的编程方式容易理解算法的原理,但是呢,如果很长时间没写算法,那么就意味着C语言的某些语法就生疏了,但是总有那么一些,在写算法的时候,特别常用的,所以,我就专门写下来,不用再没头没脑的复习C语言了。
在提醒一下,这里只说C语言,不涉及C++。
声明普通变量
#include
int main()
{
int iVar = 10;
float fVar = 10.01;
double dVar = 10.001;
//bool flag = true;//C语言中没有bool类型
char cVar = 'a'; //字符类型使用单引号括起来
printf("%d
", iVar);
printf("%f %f
", fVar, dVar);
printf("%c
", cVar);
printf("%s
", NAME);
return 0;
}
声明指针
int *ptr = NULL; //这里请使用大写的NULL,小写的null不对
int a = 10;
ptr = &a;
printf("%p %d
", ptr, *ptr);
声明数组
//定义整型数组(浮点型是一样的)
int arrInt[10] = {1,2,3,4,5,6,7,8,9,10};
//也可不指定数组长度,长度会根据实际的元素个数来设置
int arrInt2[] = {9,8,7,6,5,4,3,2,1};
printf("%d
", sizeof(arrInt) / 4); //10
printf("%d
", sizeof(arrInt2) / 4); //9
int i = 0;
//遍历数组——case1
for (i = 0; i < 10; i++) {
printf("%d ", arrInt[i]);
}
//数组名还有另外一层含义:数组首地址(可以加*解引用来访问值)
int *ptr = arrInt;
printf("%d
", *ptr); //输出了arrInt[0] --> 1
//遍历数组——case2
for (i = 0; i < 10; i++) {
printf("%d ", *(ptr++));
printf("%d ", *(arrInt + i));
//printf("%d ", *(arrInt++)); 不要尝试这么做
}
字符与字符串
//务必保证数组长度比字符数量多1,因为结束有一个
char arrCh1[6] = {'h', 'e', 'l', 'l', 'o', ' '};
char arrCh2[] = {'h', 'e', 'l', 'l', 'o', ' '};
char arrCh3[] = "hello"; //自动添加 ,推荐使用这种方法,可以不用指定长度。
char *arrCh4 = "hello world"; //声明一个字符型指针,指向字符串的首地址,推荐使用。
//注意strlen只会返回字符数组中,实际的字符数量(并不是声明的长度)
//所以arrCh1的长度是5,并不会将 算在长度中
printf("%d
", strlen(arrCh1)); //5
printf("%d
", strlen(arrCh2)); //5
printf("%d
", strlen(arrCh3)); //5
printf("%d
", strlen(arrCh4)); //11
//遍历字符数组(字符串)
int i = 0;
while (arrCh1[i] != ' ') {
printf("%c ", arrCh1[i++]);
}
//直接输出字符串。因为数组名是字符串的首地址,那么就可以直接输出了
//注意不用加*
printf("%s
", arrCh1);
printf("%s
", arrCh2);
printf("%s
", arrCh3);
printf("%s
", arrCh4);
声明并创建结构体
#include
#include
struct Person {
//int age = 10; 不能设置默认值
int age;
char *name;
}; //末尾加分号
int main()
{
//创建结构体变量的时候,前面不止要加结构体名,还要加struct关键字
struct Person p;
p.age = 10;
p.name = "abcdefg";
printf("%d %s
", p.age, p.name);
//结构体指针
struct Person *ptr;
ptr = (struct Person*)malloc(sizeof(struct Person));
ptr->age = 20;
ptr->name = "xyzdddddd";
printf("%d %s
", ptr->age, ptr->name);
free(ptr);
return 0;
}
共用体
#include
#include
//这个union只占用10个字节空间
union Info {
int age;
char name[10];
char addr[10];
};
int main()
{
//声明共用体实例同样要使用union关键字加上共用体名称
union Info t;
t.age = 10;
printf("%d
", t.age);
//给字符数组赋值可以使用strcpy(dest, source)
strcpy(t.name, "hello");
printf("%s
", t.name);
//此时age的数据已经被清除了。因为他们共用一段空间
printf("%d
", t.age);
return 0;
}
typedef和define
#include
//define用来定义常量,语句末尾不加分号
#define ONE "1111111"
//define是预编译器处理
//typdef用来声明别名,语句末尾要加分号
typedef int* ptr;
//typedef是编译器处理
int main()
{
int a = 10;
ptr b = &a; //使用新定义的类型
printf("%s
", ONE); //输出常量
printf("%d
", *b);
return 0;
}
隐式类型转换
注意在类型转换的时候,精度丢失的问题。
#include
int main()
{
double dd = 10.0001;
int ii = dd; //隐式转换。
printf("%d
", ii); //10
printf("%f
", dd); //10.0001
//printf("%d
", dd); //错误用法。注意不会发生类型转换
int i = 10;
double d = i / 3.0; //隐式转换
printf("%f
", d); //3.333333
return 0;
}
强制类型转换
注意在类型转换的时候,精度丢失的问题。
#include
#include
struct Person {
int age;
char *name;
};
int main()
{
double dd = 100.0001;
int a = dd; //隐式转换
double b = (double)a; //强制类型转换
printf("%d
", a);
printf("%f
", b);
//强制类型转换
struct Person *p = (struct Person*)malloc(sizeof(struct Person));
return 0;
}
函数
函数可以定义为无返回值(void),或者有返回值(int、char.....)
无返回值的函数
#include
//打印数组
void PrintArr(int *a, int length){
int i;
for (i = 0; i < length; i++){
printf("%d ",a[i]);
}
}
int main()
{
int a[] = {9,8,7,6,5,4,3,2,1};
int length = sizeof(a) / 4;
PrintArr(a, length);
return 0;
}
有返回值的函数
#include
int is_odd(int a){
return a&1;
}
int main()
{
printf("%d
", is_odd(2)); //0
printf("%d
", is_odd(3)); //1
return 0;
}