- scanf函数:
第一个参数:格式控制字符串,包括格式转换说明和需原样输出的普通字符。使用所有格式转换说明时,输入值之前的空白(空格,制表符,换行符等等)会被跳过,值后面的空白表示该值的结束。
剩余的参数:变量,用于存储函数所读取的输入数据。变量前加“&”符号。数组名前无需加,数组元素需要加。
返回值:函数成功转换并存储于参数中的值的个数。
文件名约定:C的源代码通常保存于以.c扩展名命名的文件中。由#include指令包含到C源代码的文件被称为头文件,通常拥有扩展名. h。
翻译:源代码被转换为可执行的机器指令。组成一个程序的每个源文件通过编译过程分别转换为目标代码(机器指令的初步形式,用于实现程序的语句),然后各个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。链接器同时也会引入标准C函数库或程序员个人的程序库中任何被该程序所用到的函数。
编译:首先是预处理器处理。在这个阶段,预处理器在源代码上执行一些文本操作。例如,用实际值代替由#define指令定义的符号以及读入由#include指令包含的文件内容。然后,源代码经过解析,判断它语句的意思。这个阶段产生绝大多数错误和警告信息。
程序的执行:程序必须载入内存。在宿主环境(有操作系统),这个任务由操作系统完成。那些不是存储在堆栈中的尚未初始化的变量将在这个时候得到初始值。一个小型的启动程序与程序链接在一起,它负责处理一系列日常事务,如收集命令行参数以便使程序能够访问它们。接着便调用main函数。在绝大多数机器里,程序将使用一个运行时堆栈(stack),它用于存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程中将一直保留它们的值。最后是程序的中止。“正常”终止就是main函数返回。
一个ANSI C(美国国家标准协会(ANSI)对 C语言发布的标准)程序由声明和函数组成。函数定义了需要执行的工作,而声明则描述了函数和(或)函数将要操作的数据类型(数据本身)。
字符:
换行符用于标志源代码每一行的结束,当正在执行的程序的字符输入就绪时,它也用于标志输入行的末尾。
转义序列:由一个反斜杠加上一个或多个字符组成
1.在上下文环境中想使用某个特定的字符,但该字符在这个环境里有特别的意义。
\?在书写连续多个问号时使用,防止它被解释为三问号词(几个字符的序列合起来表示另一个字符)
\"用于表示一个字符串常量内部的双引号
\'用于表示字符常量'
\\用于表示一个反斜杠,防止它被解释为一个转义序列符
2.有些字符并不在源代码中出现,但它们在格式化程序输出或操纵终端显示屏时很有用。如换行符和水平制表符。
4种基本数据类型:整型、浮点型、指针、聚拢类型(数组、结构)
整型:字符、短整型、长整型、整型。它们都分有符号和无符号两个版本。
与数组名不同,当一个结构变量在表达式中使用时,它并不被替换成一个指针。
在声明结构时,必须列出它包含的所有成员。这个列表包括每个成员的类型与名字。标签(tag)字段允许为成员列表提供一个名字,这样它就可以在后续的声明中使用。标签允许多个声明使用同一个成员列表,并且创建同一种类型的结构。
struct tag{member-list} variale-list;
struct SIMPLE {
int a;
char b;};
struct SIMPLE x;
struct SIMPLE y[20];
声明结构时可以使用的另一个良好的技巧是用typedef创建一种新的类型。
typedef struct{
...}Simple;
Simple x;
Simple y[20];
区别在于Simple现在是个类型名而不是个结构标签。
结构成员:
可以在一个结构外部声明的任何变量都可以作为结构的成员。一个结构的成员可以和其他结构的成员的名字相同。
结构成员的访问是通过点操作符(.)访问的。点操作符接受两个操作数,左操作数就是结构变量的名字,右操作数就是需要访问的成员的名字,表达式的结果是指定的成员。点操作符的结合性从左向右,且优先级与下标引用相同,高于间接访问符(*)
箭头操作符接受两个操作数,但左操作数必须是一个指向结构的指针。箭头操作符对左操作数执行间接访问取得指针所指向的结构,然后和点操作符一样,根据右操作数选择一个指定的结构成员。
在一个结构内部包含一个类型为该结构本身的成员不合法,但可以包含指向该结构本身的指针。它事实上所指的是同一类型的不同结构。与此类似的还有不完整的声明。
typedef struct{
int a;short b[2];}Ex2;
typedef struct EX {
int a;char b[3];Ex2 c;struct EX *d;}Ex;
Ex x={10,'Hi',{5,{-1,25}},0};
Ex *px=&x;
int *pi=&px->a;
指针的内容是地址,指针的类型决定从该地址开始读取几个字节。此处表达式*px的右值是px所指向的整个结构,px与pi具有相同的值,但它们的类型是不同的,所以*px的结果是整个结构,*pi的结果是一个单一的整型值。
px->b的值是一个指针常量。
->的优先级高于&
malloc从内存池中提取一块合适的内存,并向该程序返回一个指向这块内存的指针。这块内存在此时并没有以任何方式进行初始化。当一块以前分配的内存不再使用时,程序调用free函数把它归还给内存池供以后之需。
这两个函数的原型如下,它们都在头文件stdlib.h中声明。
void *malloc (size_t size);
void free(void *pointer);
size_t是一个无符号类型,定义于stdlib.h。malloc的参数就是需要分配的内存字节数。如果内存池中的可用内存可以满足这个需求,malloc就返回一个指向被分配的内存块起始位置的指针,类型为void*,标准表示一个void*类型的指针可以转换为其他任何类型的指针。否则就返回一个NULL指针。因此,对每个从malloc返回的指针都进行检查,确保它并非NULL是非常重要的。
单向链表添加节点数据:
#include <stdio.h>
#include <stdlib.h>
struct link *AppendNode(struct link *head);
void Displa=yNode(struct link *head);
void DeleteMemory(struct link *head);
struct link{
int data;struct link *next;
}
int main(void){
int i=0;char c;
struct link * head=NULL;
head=AppendNode(head);
DisplyNode(head);
DeleteMemory(head);
}
struct link*AppendNode(struct link *head){
struct link *p=NULL,*pr=head;int data;
p=(struct link*)malloc(sizeof(struct link));
if (p==NULL)
exit(0);
if(head==NULL){
head=p;}else{
while(pr->next!=NULL){
pr=pr->next;
}pr->next=p;
}scanf("%d",&data);
p->data=data;
p->next=NULL;
return head;}
void DisplyNode(struct link * head)
{
struct link *p=head;
int j=1;
while(p!=NULL){
printf("%5d%10d\n",j,p->data);p=p->next;
j++;
}
}
void DeleteMemory(struct link *head){
struct link *p=head,*pr=NULL;
while(p!=NULL){
pr=p;p=p->next;
free(pr);
}
}
指针指向一个要释放内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果传递的参数是一个空指针,则不会执行任何动作。