int *p[5] p |int*|int*|int*|int*|int*| p[0]
int (*p)[5]
int *p=NULL ;
char *q=NULL ;
int a;
p=&a;
p=malloc
一、变量
int a;
char b;
int *p;
struct s s1;
1.局部变量:定义在函数内部
#include<stdio.h>
void fun()
{
int y;//局部变量 不同函数的局部变量可以同名
}
int main()
{
fun();
int y;//局部变量
return 0;
}
总结:
(1)局部变量只能在定义的函数的内部生效
(2)局部变量没赋初始值 其值为随机数
(3)两个函数中可以有同名的局部变量
2.全局变量:定义函数外部
总结:
(1)全局变量有效范围:从定义的位置开始 到本文件结束
(2)全部变量未初始化 自动清零 0 '\0' NULL
(3)全局变量可以局部变量同名 局部屏蔽全局
3.extern
(1) 一个文件中 修饰全局变量
#include<stdio.h>
void fun()
{
extern int b;//声明变量b在别的地方定义过 这里直接使用
printf("%d\n",b);
}
int b=100;
int main()
{
fun();
return 0;
}
(2)在不同文件中声明全局变量
//main.c
#include<stdio.h>
int b=100;
int main()
{
fun();
printf("main_b:%d\n",b);
return 0;
}
//fun.c
#include<stdio.h>
extern int b;//声明变量b在别的地方定义过 这里直接使用
void fun()
{
printf("fun_b:%d\n",b);
}
4.static 静态变量定义关键字
(1)修饰局部变量
局部变量是静态局部变量 只初始化一次 下一次使用上一次的结果
#include<stdio.h>
int fun()
{
static int a=0;
a++;
return a;
}
int main()
{
int ret = fun();
printf("%d\n",ret);//1
ret = fun();
printf("%d\n",ret);//2
ret = fun();
printf("%d\n",ret);//3
return 0;
}
(2)static 修饰全局变量
//main.c
#include<stdio.h>
static int b=9;//表示变量本文件生效 即便其他文件extern声明 也不能使用
int main()
{
fun();
return 0;
}
//fun.c
#include<stdio.h>
extern int b;
void fun()
{
printf("fun_b:%d \n",b);//报错
}
(3)static 修饰函数
限制函数本文件生效 其他文件不可以使用
二、指针
1.静态分配 编译 int a int a[5] int *p;
2.动态分配 运行
3.void malloc(size_t size)
(1)char *p=(char*)malloc(100);
(2)char *p=(char*)malloc(100*sizeof(char));
(3)int *p=(int*)malloc(4*sizeof(int));
4.if(NULL==p)
5.free(p);
例子:
int *p=(int*)malloc(4*sizeof(int));
if(NULL==p)
{
puts("malloc error");
exit(-1);
}
int i;
for(i=0;i<4;i++)
{
p[i]=i+1;
}
free(p);
练习:学生人数由输入确定 动态分配内存 保存学生成绩 然后求出平均分
#include<stdio.h>
#include<stdlib.h>
struct stu
{
char name[20];
int score;
};
int main()
{
int n,i,sum=0;
puts("pleaes input the num of stu:");
scanf("%d",&n);//3
struct stu *p=(struct stu *)malloc(n*sizeof(struct stu));
if(NULL==p)
{
puts("malloc error!");
exit(-1);
}
puts("please input name score:");
for(i=0;i<n;i++)
{
scanf("%s%d",p[i].name,&p[i].score);
sum += p[i].score;
}
printf("%d\n",sum/n);
free(p);
return 0;
}
三、内存模型
代码区 静态区 堆区 栈区
linux公社
四、命令行参数
1.
./a.out aa bb cc
(1)标准main函数
int main(int argc,char*argv[])//标准main函数
{
//argc 表示参数的个数
//argv 存储所有的命令行参数
//argv[0] 指向可执行文件名字 ./a.out
//argv[1] 指向第一个选项参数
//argv[2] 指向第二个选项参数
}
#include<stdio.h>
int main(int argc,char*argv[])
{
int i;
printf("argc:%d\n",argc);
for(i=0;i<argc;i++)
{
printf("%s\n",argv[i]);
}
}
gcc main.c
./a.out aa bb cc
argc:4
./a.out ---argv[0]
aa ----------argv[1]
bb ----------argv[2]
cc ----------argv[3]
练习:传参并输出打印
./myprog oh my god
练习:./prog 3 + 2
#include<stdio.h>
int main(int argc,char*argv[])//./prog 3 + 2
{
int i,n;
n = atoi(argv[1]);//将字符串整数转成十进制整数
printf("%d\n",n*5);
char op = (*argv[2]);
}
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char*argv[])//./prog 3 + 2
{
if(argc!=4)//错
{
printf("%s op1 opeation op2\n",argv[0]);
exit(-1);
}
int op1 = atoi(argv[1]);
int op2 = atoi(argv[3]);
char opera = *(argv[2]);// char *p="+" *p
switch(opera)
{
case '+':
printf("%d\n",op1+op2);
break;
case '-':
printf("%d\n",op1-op2);
break;
case '*':
printf("%d\n",op1*op2);
break;
case '/':
printf("%d\n",op1/op2);
break;
default:
printf("error!");
break;
}
}
五、递归:可能造成死循环 栈空间不足
函数直接或间接调用自身
1.间接
void fun2()
{
fun1();
}
void fun1()
{
fun2()
}
int main()
{
fun1();
}
2.直接
void fun1()
{
int arr[10000];
fun1();
}
int main()
{
fun1();
}
3.递归一定要有结束条件
5!=5*4*3*2*1;
5!=5*4!
4!=4*3!
3!=3*2!
2!=2*1!
n!=n*(n-1)!
#include<stdio.h>
int recur(int n)
{
int result;
if(n==1)
{
return 1;
}
result = n*recur(n-1);
return result;
}
int main()
{
int ret;
ret = recur(6);
printf("%d\n",ret);
return 0;
}
练习:求1-6的阶乘之和
#include<stdio.h>
int recur(int n)
{
int result;
if(n==1)
{
return 1;
}
result = n*recur(n-1);
return result;
}
void get_sum()
{
int i,sum=0;
for(i=0;i<6;i++)
{
sum = sum+ recur(i+1);
}
printf("%d\n",sum);
}
int main()
{
get_sum();
return 0;
}
六、
int a;
a=100;
int *p;
p=&a;
int **q;
q=&p;
#include<stdio.h>
int main()
{
int a;//0级地址
a=100;
int *p;
p=&a;//一级地址
int **q;
q=&p;//&&a 二级地址
printf("*q:%p p:%p &a:%p\n",*q,p,&a);
printf("**q:%d *p:%d a:%d\n",**q,*p,a);
return 0;
}
练习:编写函数get_memory
实现:动态分配10个int型空间 通过函数把分配的空间首地址传给调用者
方法1:
#include<stdio.h>
#include<stdlib.h>
int * get_memory()
{
int *p = (int*)malloc(10*sizeof(int));//0x12345678
if(NULL==p)
{
puts("malloc failed");
exit(-1);
}
return p;
}
int main()
{
int *q=NULL;
printf("before:%p\n",q);
q = get_memory();
printf("after:%p\n",q);
return 0;
}
方法2:
#include<stdio.h>
#include<stdlib.h>
void get_memory(int **p)//p=&q *p-->q
{
*p = (int*)malloc(10*sizeof(int));//0x12345678
}
int main()
{
int *q=NULL;
printf("before:%p\n",q);
get_memory(&q);
printf("after:%p\n",q);
return 0;
}
错误例子:
#include<stdio.h>
#include<stdlib.h>
void get_memory(int *p)//p=q
{
p = (int*)malloc(10*sizeof(int));
}
int main()
{
int *q=NULL;
get_memory(q);
*q=90;
return 0;
}
作业1:将字符串a中所有字符传送到字符串b中 每传3个字符 放一个空格
例如:a串"abcdefg" 则b串为"abc def g"
作业2:对于从键盘输入的英文短文 统计
统计:字母的个数 单词的个数 及行数
i am a student.
you are a teacher.
Bye!
#include<stdio.h>
void ct()
{
char c;
int char_num=0,word_num=0,line_num=1,s;
s=0;//状态判断
while((c=getchar())!='`') //获取字符,如果输入`,结束循环
{
if(c!=' '&&c!='\n')
{
char_num++; //输入的不是换行和空格,字符数加一;
}
if(c=='\n') //输入的是换行,行加一;
{
line_num++;
}
if(c=='\n'|| c==' ')// 输入的是换行或者空格,让状态符s置0;
{
s=0;
}
else if(s==0) //当状态符等于0且又接受到了不是空格或者换行的字符时(接收到了新的单词);
{
s=1; //将s置1(确认接收新单词后,在同一个单词输入内不会再进入这项判断);
word_num++; //单词数加1
}
}
printf("line_num=%d\nword_num=%d\nchar_num=%d\n",line_num,word_num,char_num);
}
int main()
{
ct();
return 0;
}
28个字母 9个单词 3行