int main(void)
{
// 输出一句话
printf("hello C程序员~");
system("pause"); // 卡住程序,方便观察结果
return 0;
}
注意:空格美观、句末分号、main主函数必有、英文分号、左花括号另起一行(保证上下对齐);
注释
头文件
主函数:应用程序入口,操作系统调用程序的接口;一个项目中只能有一个;
内建函数:printf... 编译器优化。
xxxxxxxxxx
int main(void) // C99标准主函数形式,C语言标准
{
// 这是主函数框架
}
ide根据文件后缀选择编译器,cpp调用c++编译器
C程序进行编译是以源程序文件为对象进行的,分别对各源程序文件进行编译并得到相应的目标函数后,再将这些目标函数连接成为一个统一的二进制可执行文件。C语言的这种特性很容易实现程序的模块化。
C语言源程序--》编译器--》二进制目标函数+系统库函数以及其他目标函数--》可执行程序
指令 | 解释 |
---|---|
井include <stdio.h> stdlib.h float.h | 0 |
井define | 0 |
符号常量(#define PRICE 40)
基本数据类型,变量声明必须在函数顶部;
int,signed( -2^31 ~ 2^31-1),unsigned(0-2^32-1)
内存:以字节为单位存储,一个字节8位,int占4个字节。
负值存储:补码:按位取反,+1
xxxxxxxxxx
unsigned int a = 0;
printf("%d \n", 12); // %d 以10进制整数形式输出数据
%d 、 %o 、 %x 、%X;
%u // 无符号整形
%hd // 短整型输出
%ld
%p 输出16进制地址
float,double,后缀
xxxxxxxxxx
float f = 123.4545; // warning: 数据截断
float f1 = 123.4545f; // 不警告
char
sizeof( params ):params可是是“int”,或者变量名,
xxxxxxxxxx
sizeof( int ); // 4
sizeof( short int ); // 2
sizeof( long int ); // 4
sizeof( char ); // 1
& 取地址
输入输出
xxxxxxxxxx
scanf ("%d", &a); // 注意,scanf中千万不要加"\n",scanf("%d \n"),错误
scanf_s("%d", &a);
printf ("%d",a);
指针(灵活)
数据类型 | 属性 | 打印 |
---|---|---|
整形 | int、short int、 long int | %d |
浮点型 | float(4字节)、 double(8字节)、long double(必须初始化) | %f, %lf(小数点后保留6位) |
字符型 | char | %c |
数组类型 | int arr[10] char message[20] | |
指针类型 | int *p | %p |
结构体类型 | struct tag{ ... } x; typedef(stddef.h) | |
共用体类型 | ||
复数浮点类型 |
C语言是完全模块化和结构化的语言,用函数作为程序的模块单位。
C语言允许直接访问物理地址,能进行位运算,能实现汇编语言的大部分功能,可以直接对硬件进行操作。C语言的可移植和硬件控制能力高,目前C语言主要用途之一是编写“嵌入式系统程序”。
scanf、printf是C语言的标准输入输出函数,
xint arr[10]; // 声明一个一维数组,长度为10
int arr01[10] = {1,2,3}; // 数据初始化,后面的全为“0”,只能在定义的时候这样写!!!
int arr02 = {0}; // 全部置零;
int arr03 = {1,2,3};
scanf ("%d", &arr[0]); // 输入
printf("%d \n", arr01[0]); // 打印输出
元素是一维数组的数组是二维数组
xxxxxxxxxx
int a[3][2]; // "3"表示有3个一维数组
// "2"表示每个小数组中有2个元素
可以按行列理解,但是在内存中都是现行排列的
0 0 | 0 1 | 1 0 | 1 1 | 2 0 | 2 1 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 |
xxxxxxxxxx
int arr[3][2] = {1,2,3,4,5}; // 按内存填充
地址:
数组拷贝
是一种数据类型,用来存放地址
关键点:类型(偏移、内存操作)
指针指向空间;
操作:
xxxxxxxxxx
int a = 22;
int *p = &a; // int 类型的指针,int表示装int类型的地址
// * 表示p是一个指针变量
// p是变量名字
printf("%p %p\n", p, &a); // 都打印 a的地址
printf("%d\n", sizeof(float)); // 4
printf("%d\n", sizeof(double)); // 8
// int *p; *是标志
// *p 内存操作运算符,读、写、取地址
xxxxxxxxxx
int a = 12;
int *p = &a;
printf("%p %d %d\n",p ,*p, a); // 读
*p = 145; // 写
printf("%p %d %d\n",p ,*p, a);
printf("%p %p %p\n",p ,&*p, &a); // 取地址
xxxxxxxxxx
int a = 3;
int *p = &a; // p 是 int*类型
int* *p1 = &p;
xxxxxxxxxx
int a[10] = {1,6,7,8,3,33,21};
int *p = &a[0];
// p+1 --> a[1]
xxxxxxxxxx
int a[2] = {1,2};
int b[5] = {7,7,8,3,2};
int* p[2] = {a,b};
int* p[2] = {&a[0], &b[0]};
&a // 数组类型的指针, +1跨整个数组
malloc( n ); // 生成n个字节!
memset( p, 0, 40); // 字节赋值
动态数组
xxxxxxxxxx
int a;
int *p;
scanf("%d", &a);
p = (int*)malloc(a);
xxxxxxxxxx
int main(void)
{
int *p = (int*)malloc(10);
if(p != NULL)
{
printf("%p", *p);
printf("%p", p[0]);
free(p); // 释放内存
p = NULL;
}
return 0;
} // 均输出p[0]地址
以 NUL结尾,‘\0’
库: string.h
字符操作
内存操作
xxxxxxxxxx
int strlen(int const *arr)
{
int length;
for(length = 0 ;*arr++ !='\0';){
length+=1;
}
return length;
}
结构(成员组成)
存在边界对齐问题,解决:把较为严格的成员放在前面,减少内存浪费
xxxxxxxxxx
struct SIMPLE{
float c;
int a;
char b;
};
struct SIMPLE x;
struct SIMPLE y[10], *z;
xxxxxxxxxx
typedef {
int a;
char b;
float c;
} Simple;
Simple x;
Simple y[10], *z;
xxxxxxxxxx
z = &x;
z->a;
// -> 优先级高于. 高于* 操作符
*p->a.b
error C2143: syntax error : missing ';' before 'type'
将变量申明放置到所有可执行代码之前;一般在 ANSI C 或者 C++中,在可执行代码中随时定义变量是允许的,但是在K&R C中是不允许的,因此才会出现这个错误。VC6.0 、VS2008 都是用的 K&R C 来实现 C语言的,因此编译过程中会报错。
scanf("%d, %d",&x1, &y1);,
输入为1 2 ,第二个数值为乱码数据,因为scanf函数的输入格式要与设定的%d, %d格式一致,输入1,2。
递归运算中,
xxxxxxxxxx
return n*jiecheng(--n); // jiecheng(5)=24,自增运算符优先级高于乘法运算符
return n*jiecheng(n-1); // jiecheng(5)=120