表格乱码了,阿肆的github ,这里显示正常,都是传的md文件。
《The C Programing Language》
《C Primer 第六版》
《C和指针》
#include
#include
int main(void)
{
// 输出一句话
printf("hello C程序员~");
system("pause"); // 卡住程序,方便观察结果
return 0;
}
注意:空格美观、句末分号、main主函数必有、英文分号、左花括号另起一行(保证上下对齐);
注释
头文件
主函数:应用程序入口,操作系统调用程序的接口;一个项目中只能有一个;
内建函数:printf… 编译器优化。
int main(void) // C99标准主函数形式,C语言标准
{
// 这是主函数框架
}
ide根据文件后缀选择编译器,cpp调用c++编译器
C程序进行编译是以源程序文件为对象进行的,分别对各源程序文件进行编译并得到相应的目标函数后,再将这些目标函数连接成为一个统一的二进制可执行文件。C语言的这种特性很容易实现程序的模块化。
C语言源程序–》编译器–》二进制目标函数+系统库函数以及其他目标函数–》可执行程序
问题分析
设计算法
编写程序
对源程序进行编辑、编译、连接,得到可执行程序。
运行程序,分析结果。
调试,测试
编写程序文档,也称用户文档:程序名称、功能、运行环境、程序的安装、启动,需要输入的数据,以及使用注意事项等。
顺序结构
选择结构
循环结构
| 指令 | 解释 |
| —————————————- | —- |
| 井include
基本数据类型,变量声明必须在函数顶部;
int,signed( -2^31 ~ 2^31-1),unsigned(0-2^32-1)
内存:以字节为单位存储,一个字节8位,int占4个字节。
负值存储:补码:按位取反,+1
unsigned int a = 0;
printf("%d \n", 12); // %d 以10进制整数形式输出数据
%d 、 %o 、 %x 、%X;
%u // 无符号整形
%hd // 短整型输出
%ld
%p 输出16进制地址
float,double,后缀
float f = 123.4545; // warning: 数据截断
float f1 = 123.4545f; // 不警告
char
sizeof( params ):params可是是“int”,或者变量名,
sizeof( int ); // 4
sizeof( short int ); // 2
sizeof( long int ); // 4
sizeof( char ); // 1
& 取地址
输入输出
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语言的标准输入输出函数,
特点:类型相同的元素组成的元素
空间连续
一维数组,下标从“0”开始
定义 int a[5]
下标访问 a[5]
差异:前边是否有类型
int 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]); // 打印输出
debug 看数组中存储的数据
数组名是常量,不能进行赋值,是右值,永远不能改变!!!空间释放是通过数组名,数组名重新赋值,则造成内存泄露。
C语言不检测数据边界,考虑程序效率,所以写代码要注意。
数组大小: 【 sizeof(arr) / sizeof(int) 】
数字地址:&a[0]
地址特殊性:&a[0]+1 (地址加1,相当于加了一个类型的大小!!!),下一个住户
&a+1,相当于加一整个数组的长度单元!!!下一个小区
地址偏移:加减 n 个基本类型的大小
地址类型是指针类型
元素是一维数组的数组是二维数组
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 | | | | | | | | | | | |
int arr[3][2] = {1,2,3,4,5}; // 按内存填充
地址:
a = &a[0]
a[0]、a[1]、a[2]
a[0].[0]
取地址:
数组拷贝
循环
内存拷贝 memcpy(y,x, sizeof(x))
是一种数据类型,用来存放地址
关键点:类型(偏移、内存操作)
指针指向空间;
操作:
赋值
通过地址操作地址对应的空间
对内存操作(读、写、取地址)
p指向一个变量, *p就是这个变量本身
类型决定内存操作
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 内存操作运算符,读、写、取地址
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); // 取地址
int a = 3;
int *p = &a; // p 是 int*类型
int* *p1 = &p;
int a[10] = {1,6,7,8,3,33,21};
int *p = &a[0];
// p+1 --> a[1]
*p++ // 先执行p++,再取地址
p[0] == a[0],p[3] // 地址+下标访问元素
2[p] == p[2],下标运算本质:地址+下标
每个元素都是地址
链表,
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跨整个数组
int (*p)[5] = &a;
p1[5],【】优先级高于
用处:数组做函数参数用
malloc( n ); // 生成n个字节!
memset( p, 0, 40); // 字节赋值
动态数组
int a;
int *p;
scanf("%d", &a);
p = (int*)malloc(a);
#include
#include
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
字符操作
strlen()
strcpy()
strcmp()
strcat()
strchr() strrchr(char *string, int tar)
内存操作
memcpy(void *dest, void *str, size_t size) // size 为字节数,int需要在数组长度上*X4
参数式void * 型,而任何类型的指针都能转换为 void *型指针
memcmp
memset
memmove // 有重叠,新开辟缓存区存中间值,在拷贝回去
int strlen(int const *arr)
{
int length;
for(length = 0 ;*arr++ !='\0';){
length+=1;
}
return length;
}
结构(成员组成)
存在边界对齐问题,解决:把较为严格的成员放在前面,减少内存浪费
struct SIMPLE{
float c;
int a;
char b;
};
struct SIMPLE x;
struct SIMPLE y[10], *z;
typedef {
int a;
char b;
float c;
} Simple;
Simple x;
Simple y[10], *z;
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。
递归运算中,
return n*jiecheng(--n); // jiecheng(5)=24,自增运算符优先级高于乘法运算符
return n*jiecheng(n-1); // jiecheng(5)=120
阿肆的git