shell
复习:
gcc
gcc a.c -o a
预处理:去掉#
gcc -E a.c -o a.i
编译:
gcc -S a.c -o a.s
汇编:
gcc -c a.c -o a.o
链接:
gcc a.c -o a
一、程序编译问题
1.两类:
hello.c:7:2: 错误: expected ‘;’ before ‘return’ //缺少分号
hello.c:(.text+0x19): undefined reference to `prin' //链接
collect2: ld 返回 1
hello.c:4:2: 警告: 隐式声明与内建函数‘printf’不兼容 [默认启用]
2.gcc hello.c -o hello -Wall //-Wall 显示所有警告
二、多文件编译
//main.c
#include<stdio.h>
int main()
{
fun();
puts("i am main....");
}
//fun.c
#include<stdio.h>
void fun()
{
puts("i am fun....");
}
gcc main.c fun.c
./a.out
练习:从键盘输入一个正数 输出此数的位数 如:235 3 1234 4
//main.c
#include<stdio.h>
int main()
{
int n;
puts("input :");
scanf("%d",&n);
printf("%d\n",judge(n));
}
//judge.c
#include<stdio.h>
int judge(int a)
{
int count=0;
while(a!=0)
{
a/=10;
count++;
}
return count;
}
gcc main.c judge.c -o judge
./judge
三、GDB调试
gcc hello.c -o hello -g //-g 会将调试信息写入可执行文件 程序会变大
list //默认显示前10行
(gdb) break 4 //表示在第4行设置断点
run //在断点处停下来 可以查看变量的值
print i //查看变量的值
c //继续运行 如果碰到断点会停下来
n //一次执行一行
q //退出
跟我一起写Makefile
四、项目管理器makefile
1.
主要多文件编译
Makefile里面主要是源代码的编译规则 通过make命令 来执行makefile
make执行时 需要一个makefile
2.makefile 名称:makefile Makefile MAKEFILE
(1)编写Makefile
//vi Makefile
///
hello:
gcc main.c fun.c -o hello
执行:make
make 是命令 当执行这个命令 会自动找Makefile
make: “hello”是最新的。//执行make时 会检查源文件是否有更新 如果没有更新 不重新编译
(2)clean
/
hello:
gcc main.c fun.c -o hello
clean:
rm hello
make clean //make命令可以执行某一个目标 如clean
练习:
jud
gcc main.c judge.c -o judge
clean:
rm judge
(3)//如果一个目录依赖于另一个目标 则另一个目标也会被执行
hello:main.c fun.c //hello目标依赖于main.c fun.c
gcc main.c fun.c -o hello
clean:
rm hello
rebuild:clean hello //先执行clean 再执行hello
(4)为了提高编译效率 通常会先将.c文件生成.o目标文件
然后如果某个源文件修改 就重新相应的.o文件 其他的没有修改的.c文件则不会重新编译
hello:main.o fun.o
gcc main.o fun.o -o hello
main.o:main.c
gcc -c main.c vi
fun.o:fun.c
gcc -c fun.c
clean:
rm hello
rebuild:clean hello
//如果main.c 修改 重新生成main.o fun.c 不会重新生成
(5)简化:
Makefile文件中可以使用一些预设变量
$@是完整的目标名称
$^ 所有依赖
$< 第一个依赖文件
预设变量不可以放在":"行,在这一行依赖关系最好写上。
hello:main.o fun.o i
gcc $^ -o $@
main.o:main.c
gcc -c $<
fun.o:fun.c
gcc -c $<
继续简化:
.o:.c
gcc -c $<
//
hello:main.o fun.o
gcc $^ -o $@
.o:.c
gcc -c $<
clean:
rm hello
rebuild:clean hello
/
(6)再简化
在Makefile中可以定义变量 定义变量好处:方便修改
//
EXEC = hello
CC = gcc
OBJ = main.o fun.o
$(EXEC):$(OBJ)
$(CC) $^ -o $@
.o:.c
$(CC) -c $<
clean:
rm $(OBJ)
rm $(EXEC)
rebuild:clean $(EXEC)
/
跟我一起写Makefile
五、指针
1.定义指针
int * p;
int a=90 ;
p = &a;
*p=100;
a=100;
int b;
p=&b;
char* q;
float *f;
..
2.指针指向数组
int a[5];
数组名:数组首地址==&a[0]
int *p;
p=a;
for(i=0;i<5;i++)
{
*(p+i)
}
、
六、数组指针:本质是指针 指向二维数组的指针
int a[2][3]={{10,20,30},{40,50,60}}
1.如何定义数组指针指向二维数组
int (*p)[3];//定义一个指针p 指向列数为3的二维数组 数组中每个元素类型为int
数组指针定义必须明确要指向的二维数组的列数
2.使用、
#include<stdio.h>
int main()
{
int i,j;
int a[2][3]={{10,20,30},{40,50,60}};
int (*p)[3];
p = a;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("%d ",p[i][j]);//注意此处p[i][j]=(*(p+i)[j])
}
putchar('\n');
}
return 0;
}
练习:已知二维数组
int a[3][4]={{7,10,-2,3},{4,30,6,-15},{0,5,27,-7}};
利用数组指针将数组中各个元素相加求和
#include<stdio.h>
void get_sum(int (*p)[4],int row)//int(*)[4]
{
int i,j,sum=0;
for(i=0;i<row;i++)
{
for(j=0;j<4;j++)
{
sum = sum+p[i][j];
}
}
printf("%d\n",sum);
}
int main()
{
int a[3][4]={{7,10,-2,3},{4,30,6,-15},{0,5,27,-7}};
get_sum(a,3);//int (*)[4]
return 0;
}
七、指针数组:本质是数组 由指针组成的数组
int (*p)[3]
int * p[3] |int*|int*|int*|
char *p[3] |char*|char*|char*|
char *a[3]={"zhao","qian","sun"};
//a[0]="zhao"
//a[1]="qian"
for(i=0;i<3;i++)
{
printf("%s\n",a[i]);
}
八、冒泡排序
char *p[5]={"yang","li","liu","wang","zhang"};
1.冒泡
冒泡排序
实现过程:从小到大
(1)比较数据中的前两个数 将大数放后面 较小数放前面 然后比较第二个数和
第三个数
(2)依次类推
(3)如果n个数据排序 需要排n-1趟
#include<stdio.h>
#include<string.h>
int main()
{
char *p[5]={"yang","li","liu","wang","zhang"};
int i,j;
char *t;s
for(i=0;i<4;i++)
{
for(j=0;j<4-i;j++)
{
if(strcmp(p[j],p[j+1])>0)
{
t = p[j];
p[j] = p[j+1];
p[j+1] = t;
}
}
}
for(i=0;i<5;i++)
{
puts(p[i]);
}
return 0;
}
九、函数
1.
int fun(int ,int );
int main()
{
int x = fun(x,y);
}
int fun(int a,int b)
{
语句;
return 90;
}
练习2:
#include<stdio.h>
void fun(char ch,int col,int row)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
putchar(ch);
}
putchar('\n');
}
}
int main()
{
fun('a',5,3);
return 0;
}
2.交换函数
#include<stdio.h>
void swap(int *pa,int *pb)
{
int tmp;
tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void sort(int *p,int n)
{
int i,j;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1-i;j++)
{
if(p[j]>p[j+1])
{
swap(&p[j],&p[j+1]);
}
}
}
}
void out_put(int *p,int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%d ",p[i]);
}
}
int main()
{
int a[]={6,3,8,0,1,34,9,90};
sort(a,sizeof(a)/sizeof(int));
out_put(a,sizeof(a)/sizeof(int));
}
作业1:函数练习题4,5
int my_strcmp( char *s1, const char *s2);
#include<stdio.h>
int fun(char *p,char *q)
{
for(;!((*p=='\0')&&(*q=='\0'));p++,q++)
{
if(*p==*q)
{
continue;
}
else if(*p>*q)
{
return 1;
break;
}
else
{
return -1;
break;
}
}
return 0;
}
int main()
{
char a[50];
char b[50];
puts("inpuy two string:");
scanf("%s\n",a);
scanf("%s",b);
int x=fun (a,b);
printf("%d",x);
}
练习5:
#include<stdio.h>
int is_within(char c,char *str)
{
while(1)
{
if(*str==c)
{
return 1;
}
else
{
str++;
if(*str=='\0')
return 0;
}
}
}
int main()
{
char str[30];
char c;
int x;
puts("Please input the char:");
c=getchar();
getchar();
puts("Please input the str:");
gets(str);
x=is_within(c,str);
printf("%d\n",x);
return 0;
}
作业2:指针练习题第5题
1 3 5 7 9
2 4 6 8 10 12 14 16
1 2 3 4 5 6 7 8 9 10 12 14
指针版本:
#include<stdio.h>
void sort(int *p1,int *p2)
{
int i=0,j=0;
while(i<10&&j<10)
{
if(*p1<*p2)
{
printf("%d ",*p1);
p1++;
i++;
}
else
{
printf("%d ",*p2);
p2++;
j++;
}
}
if(i<j)
{
while(i<10)
{
printf("%d ",*p1);
p1++;
i++;
}
}
else
{
while(j<10)
{
printf("%d ",*p2);
p2++;
j++;
}
}
}
int main()
{
int a[10]={1,3,5,7,9,11,13,15,17,19};
int b[10]={2,4,6,8,10,11,14,16,18,20,};
sort(a,b);
}