目录
一、C语言易混淆
1.C语言中puts跟printf的区别
puts跟printf的主要区别:
- 1.puts输出后自动换行,也就是自动加入换行符,不需要手动加入
- 2.puts就是输出字符串,printf支持多种输出
例如
#include <stdio.h>
int main()
{
char c;
puts("请输入一个字符”);
c = getchar(); //调用函数
puts("你输入的字符是");
putchar(c); //调用函数
return 0;
}
编译结果:
2.define 和 typedef 两者的联系和区别
define用来定义一些常量和宏函数,然后在预处理阶段,编译器会直接替换
typedef用于定义一些新的类型,看起来更加直观或写起来更加方便
比如在单片机中,我们经常使用unsigned char
但是经常写又太麻烦,就会使用:
(1)typedef unsigned char uchar;
(2) #define uchar unsigned char(这个末尾不用加分号)
代码示例:
#include <stdio.h>
//#define uchar unsigned char
typedef unsigned char uchar;
int main()
{
uchar p;
p = 10;
printf("%d\n",p);
return 0;
}
编译结果:p = 10;
以上这种情况两者没有很大区别
再来看一种情况,用它们来定义一种指针类型
首先用typedef定义一种指针类型,示例代码:
#include <stdio.h>
typedef char* pstr;
int main()
{
pstr p1 = NULL;
pstr p2 = NULL;
return 0;
}
这种情况下p1和p2都是指针类型
接着用#define定义一种指针类型,示例代码:
#include <stdio.h>
#define pstr char*
int main()
{
pstr p1 = NULL;
pstr p2 = NULL;
return 0;
}
预处理后你会发现p1是指针类型,p2还是char类型,原因是宏定义只做简单的替换
还有一种容易踩坑的,当你加上const关键字时,示例代码:
#include <stdio.h>
typedef char* pstr;
int main()
{
const pstr p;//const修饰的是*p而不是p
p++;//这种是错误的,编译会出错
(*p)++;//这种是正确的
return 0;
}
代码中的const是修饰的是指针p而不是指针p指向的内容
二、C语言简单算法
1.斐波那契数列
代码示例:
#include <stdio.h>
int main()
{
int i;
int array[30]; //定义数组有30个数
array[0] = 0; //第一个为0
array[1] = 1; //第二个为1
int sum = sizeof(array)/sizeof(array[0]); //sum为总数
for(i=2;i<sum;i++)
{
array[i] = array[i-1] + array[i-2];
}
for(i=0;i<sum;i++)
{
printf("%d\t",array[i]);
}
return 0;
}
编译结果如下
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229
2.C语言选择排序法
选择排序法分两种排序,从小到大或者从大到小,如下所示:
#include <stdio.h>
int main()
{
int array[] = {23,5,46,797,65,43,12,59,87,64,13};
int i;
int j;
int length;
int temp;
length = sizeof(array)/sizeof(array[0]);
for(i=0;i<length-1;i++)
{
for(j=i+1;j<length;j++)
{
if(array[i]>array[j])
{
temp = array[i];
array[i] = array[j];
array[j] =temp;
}
}
}
for(i=0;i<length;i++)
{
printf("%d\t",array[i]);
}
}
编译结果
5 12 13 23 43 46 59 64 65 87 797
#include <stdio.h>
int main()
{
int array[] = {23,5,46,797,65,43,12,59,87,64,13};
int i;
int j;
int length;
int temp;
length = sizeof(array)/sizeof(array[0]);
for(i=0;i<length-1;i++)
{
for(j=i+1;j<length;j++)
{
if(array[i]<array[j])
{
temp = array[i];
array[i] = array[j];
array[j] =temp;
}
}
}
for(i=0;i<length;i++)
{
printf("%d\t",array[i]);
}
}
编译结果
797 87 65 64 59 46 43 23 13 12 5
3.C语言冒泡排序法
冒泡排序法类型分为两种,从小到大排或者从大到小排,如下所示:
#include <stdio.h>
int main()
{
int array[] = {10,13,51,34,68,97,46,78,54,12,5,45};
int i;
int j;
int temp;
int length;
length = sizeof(array)/sizeof(array[0]);
for(i=0;i<length-1;i++)
{
for(j=0;j<length-i-1;j++)
{
if(array[j]>array[j+1])
{
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
for(i=0;i<length;i++)
{
printf("%d\t",array[i]);
}
return 0;
}
编译结果
5 10 12 13 34 45 46 51 54 68 78 97
#include <stdio.h>
int main()
{
int array[] = {10,13,51,34,68,97,46,78,54,12,5,45};
int i;
int j;
int temp;
int length;
length = sizeof(array)/sizeof(array[0]);
for(i=0;i<length-1;i++)
{
for(j=0;j<length-i-1;j++)
{
if(array[j]<array[j+1])
{
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
for(i=0;i<length;i++)
{
printf("%d\t",array[i]);
}
return 0;
}
编译结果
97 78 68 54 51 46 45 34 13 12 10 5 5136
三、结构体练习题目示例
1.运用结构体输出成绩较高的学生的信息
#include <stdio.h>
#include <string.h>
struct Student
{
int num;
char name[32];
double score;
int age;
char address[32];
};
int main()
{
struct Student S1;
struct Student S2 = {2,"jiaxin",99,18,"guangdong"};
struct Student max;
S1.num = 1;
S1.score = 100;
S1.age = 18;
strcpy(S1.name,"zgl");
strcpy(S1.address,"guangdong");
max = S1;
if(S1.score<S2.score)
{
max = S2;
}
printf("成绩较好的是:\n");
printf("num:%d\t,name:%s\t,score:%lf\t,age:%d\t,address:%s\n",max.num,max.name,max.score,max.age,max.address);
return 0;
}
编译结果:
2.结构体数组应用之选票系统
首先介绍几个字符串常用API:
- malloc(开辟):函数原型 void *malloc(size_t size)
- C库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。
- strcpy(字符串复制):strcpy(stu.name,"zgl");
- strcmp(字符串对比):int strcmp(const char *s1,const char *s2);
- 若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数
- memset(清除):函数原型 void *memset(void *str, int c, size_t n)
选票系统代码示例:
#include <stdio.h>
#include <string.h>
struct Xuanmin
{
char name[32];
int ticket;
};
int main()
{
int len;
int i;
int j;
int waiver = 0;
int mark;
char tempname[32];
struct Xuanmin xm[3];
struct Xuanmin max;
len = sizeof(xm)/sizeof(xm[1]);
for(i=0;i<len;i++)
{
xm[i].ticket = 0;
printf("please input the %d num people :\n",i+1);
scanf("%s",xm[i].name);
}
for(i=0;i<5;i++)
{
mark = 0;
memset(tempname,'\0',sizeof(tempname));
printf("you want to vote :");
scanf("%s",tempname);
for(j=0;j<len;j++)
{
if(strcmp(tempname,xm[j].name) == 0)
{
xm[j].ticket++;
mark = 1;
}
}
if(mark == 0)
{
printf("be waiver\n");
waiver++;
}
}
for(i=0;i<len;i++)
{
printf("%s total ticket = %d\n",xm[i].name,xm[i].ticket);
}
max = xm[0];
for(i=0;i<len;i++)
{
if(max.ticket<xm[i].ticket)
{
max = xm[i];
}
}
printf("be waiver = %d\nthe max = %d\n",waiver,max.ticket);
return 0;
}
编译结果:
四、C语言常见关键字
1.const关键字
在C语言中通常我们把const关键字称作只读变量,不能通过变量本身修改它的数值,但是可以通过其他方式去修改,比如通过地址
const在笔试题中经常以下面的4种方式出现,问哪些能修改,哪些不能修改
我们只需要记住一个原则,就近原则,const靠近谁,修饰的就是谁
第一个和第二个一样,const放在前面和后面都是在星号前面,靠近星号,所以它们修饰的是*p,
也就是指针p可以修改,但是p指向的内存不能修改
第三个const靠近p,所以它修饰指针p,也就是指针p不能修改,但是p指向的内存可以修改
第四个综合了前面三个,指针p不能修改,p指向的内存也不能修改
2.static关键字在C语言中的作用
static关键字有三个主要作用:
1.修饰全局变量
2.修饰函数
3.修饰局部变量
(1)首先是修饰全局变量,就是变量只能在本文件中使用,不能在其他文件中使用
代码示例:vi 1.c
vi 2.c
编译:gcc 1.c 2.c -o main
./main
编译结果:
假设用上static关键字
编译出错:因为num被static修饰,只能在1.c文件中使用
(2)其次,可以用static修饰函数,作用也差不多,函数只能在本文件中调用
比如这次在2.c中用static修饰函数
编译的时候又会出错:因为在1.c中无法使用2.c中的函数
(3)static修饰局部变量,可以改变变量的生命周期,直到程序运行结束时才会被释放
经典笔试题示例:num存放在栈区,函数调用完会释放
编译结果:
用static修饰:num存放在静态数据区,程序运行结束才释放
编译结果: