标签:产生 字母 静态变量 strcpy 编译器 寄存器变量 内存分配 控制 tps
No.1 计算机与程序设计语言的关系计算机系统由硬件系统和软件系统构成,硬件相当于人类的肉体,而软件相当于人类的灵魂,如果脱离了灵魂,人类就是一具行尸走肉
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
当我们在编译器上将代码写好,此时的文件是.c文件,该文件是C语言程序源代码的扩展名,此时的程序叫源程序,当程序通过编译器进行编译时,此时会产生一个目标程序.obj,将目标程序和库文件连接成机器码文件,就是exe可执行程序
安装Cygwin
什么是标识符 ?
在C语言中,变量名、常量名、关键字、函数名、方法名都属于标识符
标识符如何命名?
什么是关键字?
C语言中具有特殊含义的英文单词,通常用于构成语句,存储结构、定义数据类型等
关键字有哪些?
整型 用于准确地表示整数,根据表示范围的不同分为以下三种: 短整型(short) < 整型(int) < 长整型(long)
浮点型 用于标识实数(小数)根据范围和精度不同分为以下两种: 单精度浮点数(float) < 双精度浮点数(double)
数据类型的转换
强制类型转换 (类型关键字)(表达式)
字符常量
什么是变量?
程序在运行过程中,它的值可以随着程序的运行不断的动态修改,变量代表的内存的一个空间,而变量名的作用是可以通过变量名找到这个变量名对应的那个变量的空间
定义变量到底做了什么?
int a = 123,首先在内存中开辟了4个字节的内存空间,并且并这个内存空间起了一个名字,叫做a,后面的= 123,这一步完成的操作是变量的初始化,通过a这个变量,就那个内存空间存储了123这个数据
算术运算符
+、-、*、/、%分别表示加、减、乘、除、取余
#include <stdio.h>
int main() {
int num;
printf("请输入一个5位数:");
scanf("%d",&num);
printf("倒叙输出:\n");
for (int i = 0; i < 5; i++) {
printf("%d",num % 10);
num /= 10;
}
printf("\n");
return 0;
}
关系运算符
#include <stdio.h>
int main() {
int a = 1,b = 2,c = 3;
int x,y;
x = a + b == c; // x = 1
y = 11 >b != a; // y = 0
printf("x = %d,y = %d\n",x,y);
return 0;
}
逻辑运算符
#include <stdio.h>
int main() {
int year;
printf("请输入年份:");
scanf("%d",&year);
if ((!(year % 100) && !(year % 400))||year % 4 == 0){
printf("%d年是闰年",year);
}
else{
printf("%d年是平年",year);
}
return 0;
}
赋值运算符
条件表达式
#include <stdio.h>
int main() {
int a = 1;
int b = 2;
int c = 3;
int max = 0;
max = a>b?(a>c?a:c):(b>c?b:c);
printf("max=%d",max);
return 0;
}
逗号表达式
#include <stdio.h>
int main() {
int a = 1;
int b = 2;
int c = 3;
c = (a = 10,b = 10,2 * a + 5,a + a * b + c);
printf("a = %d, b = %d, c = %d\n",a,b,c); // a = 10, b = 10, c = 113
return 0;
}
长度测试运算符
#include <stdio.h>
int main() {
int a = 1;
float b = 2.0;
char c = ‘3‘;
printf("%d %d %d\n", sizeof(a), sizeof(b), sizeof(c)); // 4 4 2
return 0;
}
运算符的优先级
顺序结构与判断结构if的使用
什么是数组?
将数据类型一致的多个变量存放在一块连续的的内存空间中,元素按照索引的方式连续存放、访问
一维数组
数组定义 数据类型 数组名 [数组长度],例如 int num[10];
初始化
int num[5] = {1, 2 , 3}; 赋值了部分元素,没有赋值的系统会被初始化为0
二维数组
初始化
冒泡排序
#include <stdio.h>
int main() {
int nums[10];
// 随机为数组赋值
for (int i = 0; i < 10; ++i) {
nums[i] = rand()%100+1;
}
printf("原数组: \n");
// 编译原数组
for (int i = 0; i < 10; ++i) {
printf("%d ",nums[i]);
}
// 冒泡排序
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < i; ++j) {
if(nums[j]>nums[j+1]){
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
printf("\n");
printf("新数组: \n");
for (int i = 0; i < 10; ++i) {
printf("%d ",nums[i]);
}
return 0;
}
前面我们学习了数组的定义,假如我需要存储一个名字,就需要char[5] = {‘k‘, ‘e‘, ‘r‘, ‘n‘, ‘e‘, ‘l‘},但是这样当我们需要使用名字的时候就需要遍历整个数组,于是,我们可以把它当作一个整体来保存,这就是字符串
初始化
char name[7] = "kernel";
char name[7] = {"kernel"};
输入输出函数
scanf() 例如 scanf("%s",name);
gets() 例如 gets(name);
printf() 例如 printf("%s",name);
复制
#include <stdio.h>
#include <string.h>
int main() {
char name[7] = {"kernel"};
char names[7];
strcpy(names, name);
puts(names);
return 0;
}
拼接
#include <stdio.h>
#include <string.h>
int main() {
char str[10] = {"hello"};
strcat(str, "-world");
puts(str);
}
比较
#include <stdio.h>
#include <string.h>
int main() {
char name[7] = "kernel";
char names[7] = "kernel";
// strcmp函数,从左到右根据ASCII码进行比较,知道遇到不同的字符为止
// 相同返回0,第一个变量 > 第二个变量,返回一个比0大的数,否则,返回一个比0小的数
// 直接使用==比较的是两个变量的内存地址
printf("%d",strcmp(name,names));
printf("%d",name == names);
return 0;
}
长度
#include <stdio.h>
#include <string.h>
int main() {
char name[] = "kernel";
printf("字符串的长度=%d",strlen(name));
return 0;
}
C语言作为结构化的程序设计语言,模块化是一种重要的设计思想,在模块化设计中,我们通常将复杂的任务分割成若干模块的组合,让每个模块实现一定的功能,我们将这些模块成为函数,使用函数可以提高代码的可读性和复用性
当我们想调用自定义函数时,我们需要让系统知道存在这么一个函数,所以我们需要对函数进行声明,将自定义函数写在main函数之前的不用进行声明,写在main函数后面的函数需要进行声明
函数类型
函数名
形参与实参
函数体
# 函数的声明
int sum(int, int);
# 函数体
int sum(int x, int y){
return x + y;
}
# 函数的使用
int result = sum(10, 20);
传值是单向传递,形参的改变并不影响实参,实参和形参各自占用一段内存空间
传址是将实参的地址作为值传递给形参,实参与形参指向同一块内存空间,所以形参的改变会影响实参,在C语言中通过传址传递数据的一般是数据和指针,但是操作大批量数据时,会影响性能
#include <stdio.h>
#include <stdlib.h>
int main() {
int box(int);
int n;
long num;
printf("请输入一个整数:\n");
scanf("%d",&n);
num = box(n);
printf("%d的阶乘是:%d\n",n,num);
}
int box(int n){
if (n < 0){
printf("输入数据有误");
exit(0);
}
if (n == 0 || n == 1){
return 1;
}
else{
return n * box(n-1);
}
}
访问变量有两种方式
指向数组元素 用指针指向数组的某个元素 int *p;p = &num[4];
指向数组 用指针指向数组,数组名存储的是该数组的首地址,int *p;p = num;
字符串的定义除了之前提到的字符数组外,还有另外一种方式,现在我们可以使用char *str = "Hello",系统为该字符串分配相应的连续内存空间,将存储空间的首地址赋值给指针变量str
二维数组是按行与列存储数据的,可以看成若干行个长度为若干列一维数组,如num[4][2],就可以看成4个长度为2的一维数组,num代表二维数组首元素的地址,即&num[0],我们可以将num[0]看作指向num[0][0]的指针,那么num[0]+1即指向num[0][1],同理num[1]+2就指向num[1][2],通过前面的一维数组,我们知道num[i]等价于(num+i),同样的,扩展到二维数组上面来,num[i][j]与*(num+i)+j、num[i]+j都是等价的,而求num[i][j]的值,用、*(num[i]+j)与、*((num+i)+j)
#include <stdio.h>
int main(){
void replace(char *, char);
char str[] = "how do you do";
char c = ‘o‘;
replace(str,c);
puts(str);
}
void replace(char *s,char c){
char *p;
char *q;
for (p = s; *p && *p != c; p++) {
q = p;
while (*p){
while (*p && *p == c){
p++;
}
while (*p && *p != c){
*q++ = *p++;
}
}
*q = ‘\0‘;
}
}
#include <stdio.h>
void points(int x, int y, int(*p)()){
int res;
res = (*p)(x,y);
printf("%d",res);
}
int main(){
int max(int, int);
int min(int, int);
int x,y;
scanf("%d",&x);
scanf("%d",&y);
points(x,y,max);
points(x,y,min);
}
int max(int x, int y){
if (x > y){
return x;
} else{
return y;
}
}
int min(int x, int y){
if (x > y){
return y;
} else{
return x;
}
}
#include <stdio.h>
char *day_name(int n){
static char name[7][20] = {
"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"
};
return (n <1 || n>7)?name[0]:name[n];
}
int main(){
int i;
printf("请输入一个星期编号:\n");
scanf("%d",&i);
printf("编号%d对应的星期为:%s",i,day_name(i));
}
保存保存多个字符串的方式有两种
二级指针通常用来存储指针数组的地址以及实现指针数组元素的访问
使用方法 int a,*b,**c;b = &b;c = &b;
#include <stdio.h>
int main(){
int a[5] = {1,2,3,4,5};
int *b[5];
int **c;
for (int i = 0; i < 5; ++i) {
b[i] = &a[i];
}
c = b;
for (int i = 0; i < 5; ++i, ++c) {
printf("%d\n",**c);
}
}
//1
//2
//3
//4
//5
内存中存放了什么?
栈 函数调用返回地址,形参,局部变量等程序运行信息
堆 自由存储区域,动态分配申请该空间
动态分配函数
#include <stdio.h>
#include <stdlib.h>
#define N 10
int main()
{
int *p = 0;
int i, num, *q = 0;
p = (int *) malloc((N * sizeof(int)));
if (p == 0)
{
printf("内存分配错误!\n");
exit(0);
}
printf("请输入要存储的元素个数:\n");
scanf("%d", &num);
if (num <= N) {
for (i = 0; i < num; i++){
scanf("%d", p + i);
}
} else {
for (i = 0; i < num; i++){
q = (int *) realloc(p, (N + N) * sizeof(int));
}
if (q == 0){
exit(0);
}
for (i = 0; i < num; i++){
scanf("%d", q + i);
}
p = q;
} for (i = 0; i < num; i++){
printf("%3d", *(p + i));
}
printf("\n");
free(p);
return(0);
}
const关键字修饰的数据类型是指常类型,最简单的用法是用来定义const
常量,具有不变性,const修饰的常量在声明的时候就要进行初始化赋值,不然后面是不能赋值的
结构体类型定义
struct student{
int id; //学号
char name[20]; //姓名
char sex[4]; //性别
int age; //年龄
};
结构体变量定义
struct sudent{
int id; //学号
char name[20]; //姓名
char sex[4]; //性别
int age; //年龄
};
struct student stu1,stu2;
struct student{
int id; //学号
char name[20]; //姓名
char sex[4]; //性别
int age; //年龄
}stu1,stu2;
struct{
int id; //学号
char name[20]; //姓名
char sex[4]; //性别
int age; //年龄
}stu1,stu2;
结构体变量初始化
struct stu1;
stu1 = {10001,‘kernel‘,‘boy‘,18};
结构体变量的访问
结构体访问数组
使用方法和结构体一样
区别
结构体占据连续存储区域,每个成员都拥有自己的存储空间
共用体将不同数据类型的所有成员存储在一段存储区域内,各个成员共享一块存储空间
空间的大小取决于占存储空间最大的那个成员
不同时刻可以表现为不同的数据类型和数据长度,但是同一时刻只有一个成员的值有意义
#include <stdio.h>
union type{
int class_id; //班级
char title[20]; //职称
};
struct Person{
char name[10]; //姓名
char sex; //性别
int age; //年龄
int flag; //标记用户
union type t;
};
int main(){
struct Person person[10];
int i;
int num;
printf("请输入要录入的人员数量:\n");
scanf("%d",&num);
for (int i = 0; i < num; i++) {
printf("请输入ID为%d的用户的信息:\n",i + 1);
printf("姓名:");
scanf("%s",&person[i].name);
getchar();
printf("性别:");scanf("%c",&person[i].sex);getchar();
printf("年龄:");
scanf("%d",&person[i].age);
getchar();
printf("标识符:");
scanf("%d",&person[i].flag);
getchar();
if (person[i].flag == 0){
printf("请输入班级ID:");
scanf("%d",&person[i].t.class_id);
} else if (person[i].flag == 1){
printf("请输入教师的职称:");
scanf("%d",&person[i].t.title);
} else{
printf("输入有误,请重新输入!\n");
i -= 1;
}
}
printf("输出所有用户的信息:\n");
for (int i = 0; i < num; i++) {
printf("输出ID为%d的用户的信息:\n",i + 1);
printf("姓名:");puts(person[i].name);
printf("性别: \n");printf("%c",person[i].sex);
printf("年龄:\n");printf("%d",person[i].age);
if (person[i].flag == 0){
printf("学生的班级ID:");
printf("%d\n",person[i].t.class_id);
} else if (person[i].flag == 1){
printf("教师的职称:");
puts(person[i].t.title);
}
}
}
我们定义一些变量的时候,比如性别,不是男的就是女的,对于这些可控的变量值,我们就可以使用枚举来表示
#include <stdio.h>
int main(){
enum sex{
man,
woman
}s;
char msg[2][10] = {"男性","女性"};
for (s = man; s <= woman; s++) {
switch (s){
case man:puts(msg[man]);
break;
case woman:puts(msg[woman]);
break;
}
}
}
我们可以自定义数据类型,可以通过类型定义符起一个别名
#include <stdio.h>
typedef struct students{
char name[10];
char sex;
int age;
}stu;
int main(){
stu s1 = {"kernel",‘n‘,18};
}
分类
文件类型指针 FILE结构体变量
文件打开与关闭
文件读写操作
字符
# 写入
#include <stdio.h>
#include <string.h>
int main() {
FILE *fp;
char str[] = "Write The Data to File!";
int index = 0;
fp = fopen("test1.txt","w");
if(fp == NULL) {
printf("文件打开失败!\n");
exit(1);
}
while(index < strlen(str)){
fputc(str[index++],fp);
}
fclose(fp);
return 0;
}
# 输出
#include "stdio.h"
int main() {
FILE *fp;
char c;
int n = 1;
if((fp = fopen("test1.txt","r")) == NULL) {
printf("文件打开失败!\n");
exit(1);
}
while((c = fgetc(fp)) != EOF)
{
printf("%c",c); n++;
}
printf("\n");
fclose(fp);
return 0;
}
字符串
# 写入
#include <stdio.h>
int main() {
char str[] = "通过fputs方法往文件中写入信息!";
FILE *fp = fopen("test2.txt","w");
if(fp == NULL) {
printf("文件打开失败!\n"); exit(1);
}
fputs(str,fp); fclose(fp);
return 0;
}
# 读取
#include <stdio.h>
int main()
{
FILE *fp;
char str[20];
if((fp = fopen("test2.txt","r")) == NULL) {
printf("文件打开失败!\n");
exit(1);
}
while(fgets(str,3,fp) != NULL){
printf("%s",str);
}
printf("\n");
fclose(fp);
return 0;
}
格式化
# 写入
#include <stdio.h>
int main()
{
char c[] = "Today is 2014 July ";
int day = 22; char a = ‘t‘,b = ‘h‘;
FILE *fp; if((fp = fopen("test3.txt","w"))== NULL) {
printf("文件打开失败!\n"); exit(1);
}
fprintf(fp,"%s%d %c%c",c,day,a,b);
fclose(fp);
return 0;
}
# 读取
#include <stdio.h>
int main() {
//这里很容易出问题,所以我并不喜欢用fscanf这个函数
char c1[5],c2[5],c3[5],c4[5],c5[5],c6[5];
int day,year; FILE *fp;
if((fp = fopen("test3.txt","r"))== NULL) {
printf("文件打开失败!\n"); exit(1);
}
fscanf(fp,"%s%s%s%s%s%s",&c1,&c2,&c3,&c4,&c5,&c6);
printf("%s %s %s %s %s %s\n",c1,c2,c3,c4,c5,c6);
fclose(fp);
return 0;
}
数据块
# 写入
#include <stdio.h>
typedef struct
{
int id;
char name[20];
int age;
}STU;
int main()
{
STU stu;
FILE *fp;
char c;
//内容是追加的!
if((fp = fopen("test4.data","ab"))== NULL)
{
printf("文件打开失败!\n");
exit(1);
}
while(1)
{
printf("请输入学号: ");scanf("%d",&stu.id);
printf("\n请输入姓名: ");scanf("%s",&stu.name);
printf("\n请输入年龄: ");scanf("%d",&stu.age);
fwrite(&stu,sizeof(stu),1,fp);
printf("\n继续输入?(Y/N)\n");
getchar();
c = getchar();
if(c == ‘y‘ || c == ‘Y‘)continue;
else break;
}
fclose(fp);
return 0;
}
# 读取
#include <stdio.h>
typedef struct
{
int id;
char name[20];
int age;
}STU;
int main()
{
STU stu;
FILE *fp;
if((fp = fopen("test4.data","rb"))== NULL)
{
printf("文件打开失败!\n");
exit(1);
}
printf("输出文件中的内容:\n");
printf("学生学号 学生姓名 学生年龄\n");
while(fread(&stu,sizeof(stu),1,fp) == 1)
{
printf("%-15d%-15s%-15d\n",stu.id,stu.name,stu.age);
}
fclose(fp);
return 0;
}
字
feof 检测文件是否结束
ferror 执行输入输出时,文件是否出错,返回0则无错
作用域
生存周期
auto(自动变量) 这个是默认的,我们平时定义的变量都是自动变量
static(静态变量) 静态局部变量的初始化是在编译期进行的,如果没有进行赋值,系统默认初始值是0或\0,只能赋值依次,程序运行期间不能释放,生命周期是整个程序的运行周期
标签:产生 字母 静态变量 strcpy 编译器 寄存器变量 内存分配 控制 tps
原文地址:http://blog.51cto.com/13559120/2317643