int main(int argc,char *argv[])
主函数一般不带参数,但是带上参数后可以方便对文件进行各种操作
假设该c程序为test.c 并且有两个文件a.txt 和b.txt
输入命令行
gcc -o test test.c
./test a.txt b.txt
这两个参数的作用: argc 是指命令行输入参数的个数(以空白符分隔) argv存储了所有的命令行参数
argc的值在该情况下为3
argv[0]为./test
argv[1]为a.txt
argv[2]为b.xtx
这样极大的简便了对文件进行操作
变量
1、普通局部变量存储于进程栈空间,使用完毕会立即释放。
2、静态局部变量 存储在全局数据区,即使不对其进行赋值,也会被初始化为0即使函数返回,值也被保存下来,类似于全局变量,出了函数只是失去了对该变量的访问权限
3、静态局部变量和全局变量的区别大致在于全局变量可以在整个程序中使用,但静态局部变量只能在具体分配的函数中使用
static int a = 2018;
static void func(void)
{
static int b;
printf("a = %d, b = %d\n", a++, ++b);
}
int main(int argc, char *argv[])
{
func( );
func( );
func( );
return 0;
}
//输出结果:
2018 1
2019 2
2020 3
memset 函数
char a[5];
memset(a,'1',5);
循环输出结果为:1 1 1 1 1
//
int a[5];
memset(a,1,20);
输出结果却是:16843009 16843009 16843009 16843009 16843009
原因
如果用memset(a,1,20),就是对a指向的内存的20个字节进行赋值,每个都用数1去填充,转为二进制后,1就是00000001,占一个字节。一个int元素是4字节,合一起是0000 0001,0000 0001,0000 0001,0000 0001,转化成十六进制就是0x01010101,就等于16843009,就完成了对一个int元素的赋值了。
定义一个无穷大的数为0x3f3f3f3f的原因也在于此。
改正
若要对整个数组进行赋值
应改为memset(a,1,sizeof(int)*5)
关于指针
首先给大家介绍一下常见的指针
*和const 的顺序和对应汉字的顺序一样
const char *p1; 常量指针 指针的内容可以修改,但是指向的内容不能修改
char const *p2; 指针常量 指针的指向不能修改,但是指向的内容可以修改
~
(int *)a ; a以前可能不是一个整形指针,被强制转化为int型指针
int *a ; 定义一个指针,指向的数据为整型
~
int *a[5]; []的优先级高于 *,所以定义的是一个数组,里面存放的为int *型数据,即是一个指针数组
int (*a)[5]; ()优先级高于[],所以定义的是一个指针,指向一个由5个整形数据构成的数组
二维数组和指针
个人认为二维数组和指针的关系首先要记住一句话
指针变量的加减,是以指针所指向的类型空间为单位进行偏移
结合这句话和下面的表格 可以很好的理解二维数组和指针
定义一个二维数组 int a[3][4]
a指向a[0]这个一维数组
a[0]可以看做是一维数组的数组名
a[0]指向的是a[0][0]
内容 | 指向 | +1后跨越的字节数 |
---|---|---|
&a | 指向二维 | 4*12B |
a | 指向一维 | 4*4B |
&a[0] | 指向一维 | 4*4B |
a[0] | 指向int型数据类型 | 4B |
理解: 无论是几维数组,数组的名字表示指向降低一个维度的数组,每次增加一个 &向上提升一个维度 ,增加一个 []向下降低一个维度 ,所以才会使&a指向整个二维数组,&a[0]向上提升一个维度指向了一维数组。
只有了解了不同方式的指向才能搞懂二维数组用指针的表示方法
对a[m][n]的不同表示方法
表述方式 | 理解 |
---|---|
a[m][n] | 常规方法 |
*(a[m]+n) | a[m]所指向的是int型数据单元,+n跨越n*4B,得到的是地址,需要解引用 |
* (*(a+m)+n | a指向的是一维数组,+m跨越m*16B,解引用后相当于a[m] |
a所存放的是a[0]的地址,a[0]存放的是a[0][0]的地址,所以需要逐层解引用的到需要的值