C编译器和链接器
(1)、初次体验
# include <stdio.h> int main(int argc, char* argv[]) { printf("Hello World!\n"); return 0; }
(3)、位操作:位操作符呢一共有6种,分别是按位与(&),按位或(|),按位异或(^),取反(~),左移(<<),右移(>>)。
(4)、数组特性#include <stdio.h> void change(int x[]) { int temp = x[0]; x[0] = x[1]; x[1] = temp; printf("数组名的大小为:%d\n", sizeof(x)); } int main(void) { int a[2] = {11, 22}; printf("交换前的数组元素为:%d\t%d\n", a[0],a[1]); change(a); printf("交换后的数组元素为:%d\t%d\n", a[0],a[1]); printf("数组名的大小为:%d\n", sizeof(a)); return (0); }/**********************************************
n:数组下标
全局变量:定义在函数外部的变量叫全局变量。全局变量只需在一个源文件中定义,就可以作用于所有的源文件,当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。
静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在。它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里。不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
#include <stdio.h> void main() { int a, b; int *p;//定义指针变量p p = &b;//将变量b的地址存放在变量p中 a = 3;//直接引用变量a *p = 5;//间接引用变量b }
(9)、字符串和字符串函数
char word [40]; scanf("%s" ,word); printf("%s" ,word);
char word [40]; fgets(word ,40, stdin); fputs(word,stdout);
char word [40]; scanf("%s" ,word); printf("%s\n" ,word); //sizeof以字节为单位计算数据的大小 printf("%d\n" ,sizeof( word)); //strlen 以字符为单位计算字符串的长度 printf("%d\n" ,strlen( word));
总结:引用一个数组元素可以有两种方法:下标法:a[i];指针法:*(p+i)。
//区别:数组名是常量,存储第一个数组的地址,指针则是变量。 char heart[] = "I Love Mill"; char *head = "I Love Till"; //(1)都可以使用数组符号 for (i=0;i<6;i++) { printf("%c",heart[i]); } printf("\n"); for (i=0;i<6;i++) { printf("%c",head[i]); } printf("\n"); //(2)都可以使用指针加法 for (i=0;i<6;i++) { printf("%c",*(heart+i)); } printf("\n"); for (i=0;i<6;i++) { printf("%c",*(head+i)); } printf("\n"); //(3) 指针可以使用增量运算符,而数组名不可以 while(*(head)!='\0') { printf("%c",*(head++)); } printf("\n");
字符串在常量区,长度是12字节, 元素交换很方便,只需要交换指针。
(12)、指向指针的指针
变量的直接引用与间接引用
通过变量名叫做直接引用,通过指针对变量的引用叫间接引用
间接引用的两种情况
1,如果在一个指针变量中存放的是一个目标变量的地址叫做一级地址
2,如果在一个指针变量中存放的是指向目标变量的地址的指针变量的地址,那么这个就叫做二级地址。
void main()
{
int a = 99;
int *pa = &a;
int **ppa = &a;
}
这样是绝对不行的,因为类型不匹配呀!会报错啦!
那么再看这个程序:
void main()
{
int a = 99;
int *pa = &a;
int **ppa = &pa;
}
返回指针值的函数
(13)、容易混淆的const
关键字const 并不是把变量变成常量,在一个符号前加上const限定符只是表示这个符号不能被赋值,也就是它的值对于这个符号来说只是只读的。const 最有用的地方,就是限制函数的形参,这样该函数将不会修改实参指针所指的数据,但是其它的函数可能会修改它。
const int limit = 0;
const int *limit = &limit;
limit 是一个指向常量整形的指针,这个指针不能用于修改这个整型值,但在任何时候,这个指针本身的值是可以改变的。
const int * gra;
int const * gra;
int * const gra;
三者的区别:
最后一种情况,指针是只读的,前两种情况指针所指向的对象是只读的,也就是地址存储的整型值
(14)、C的内存分配方式:
内存划分:
1 、栈区 (stack) 由编译器自动分配释放 ,存放为运行函数而分配的局部变量、函数参数、返回数据、返回地址等。其操作方式类似于数据结构中的栈。
2 、堆区 (heap) 一般由程序员分配释放,程序员自己负责在何时用 free 或 delete 释放内存 。动态内存的生存期由程序员决定 ,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏 分配方式类似于链表。
3 、全局区 (静态区static) 存放全局变量、静态数据、常量。程序结束后又系统释放,全局变量的初始化是编译器做的。被写在了可执行文件里
4 、文字常量区 常量字符串就是放在这里的。 程序结束后由系统释放。
5 、代码区 存放函数体(类成员函数和全局函数) 的二进制代码。可读可执行。
(15)、stdafx.h Standard Application Framework Extensions
所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。 预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。 编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令之后的所有代码。 因此,所有的MFC实现文件第一条语句都是:#include "stdafx.h"。
与stdio.h的区别
我们一般用TC或vc编译C程序的时候都要首先包含这个stdio.h头文件,这个头文件里面包含了scanf和printf函数的定义,如果我们不在程序开头include这个文件,那么你调用上面这两个函数就不会成功,它其实和c++中的iostream.h文件的作用差不多的,它们一般都已经在stdafx.h文件中被包含。