指针
1.指针是什么?起什么作用?
指针是变量的一种,里面是一个地址,通过这个地址找到要找的数据。
实质:单元的地址就是指针内容; 注:任何类型的指针都是4个字节(在三十二位机)
2. 指针运算符
&是取地址的运算符,*是表示指针运算符。
*在定义时表示变量是一个指针变量,而在使用时表示取值
3.指针变量的使用步骤:
1) 定义指针变量;
2)给指针变量赋地址(定义指针后若不给指针赋值则该指针为野指针,无法对其执行访问操作);
3)正常使用指针进行运算;
示例:
int *p;
*p = 3;
运行这段代码会出现段错误,即访问了一段不能访问的内存。因为指针p在定义后未被赋值而是由系统随机指定一个地址,但这个地址是不合法的,不可访问。所以定义指针后需要给指针赋值后才能使用。
4.分配内存malloc
原型:extern void *malloc(unsigned int num_bytes);
功能:分配长度为num_bytes字节的内存块
说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
当内存不再使用时,应使用free()函数将内存块释放。
分配内存过程可分为4步:
1)申请内存,所申请的内存是堆空间上的内存,使用后需要释放;如:
int* p = (int *) malloc ( sizeof(int) * 100 );
注:由我们计算需要的字节数,并进行强制类型转化
2)判断申请是否成功;如:
if(NULL == p)
{
perror("malloc");
exit(1);
}
3)释放内存。如:
free(p);
4)写成NULL
p = NULL;
5.指针和数组
指针数组:一个数组的元素值为指针则是指针数组。 指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。 指针数组说明的一般形式为:
类型说明符 *数组名[数组长度]
其中类型说明符为指针值所指向的变量的类型。
例如: int *pa[3];
表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变量。
注意: 指针数组在使用时要先对数组中的每一个指针元素都赋予一个确定的内存地址。
示例:
char *str[4];
for(i = 0; i < 4; i++)
{
scanf(“%c”, str[i]); }
这是不合法的,运行会出现段错误,即访问了一段不能访问的内存。
char *str[4] = {"hello", "world", "hey", "hi"};
这种使用是合法的。arr是一个在栈空间,有四个元素的数组,而每一个数组又是一个指针,所以说它的四个元素各占四个字节,所以变量arr的大小是16个字节。{“hello”, “world”, "hey", "hi"};它们都是常量,也存在在内存中,只是跟arr这个变量不在同一段空间,它们被分配在代码段中,每个字符串都有一个确切的内存地址。数组arr[4]的四个指针元素,分别存放着这四个字符串的首地址。
数组指针
6.指针和字符串
在C语言中,可以用两种方法访问一个字符串。
1)用字符数组存放一个字符串,然后输出该字符串。
int main()
{
char string[]=”I love China!”;
printf("%s\n",string);
return 0;
}
2) 用字符串指针指向一个字符串。
main()
{
char *string[]={”I love China!”,”I am ”};
printf("%s\n",string);
}
char *s="C Language"; 则表示s是一个指向字符串的指针变量。
把字符串的首地址赋予s。
3)字符数组和字符串的区别
1.字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以‘\0’作为串的结束。
字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。
2. 对字符串指针方式 char *ps="C Language";
可以写为:char *ps; ps="C Language";
而对数组方式: char st[]={"C Language"};
不能写为:char st[20] ; st={"C Language"}; 而只能对字符数组的各元素逐个赋值。
3.前面说过,当一个指针变量在未取得确定地址前使用是危险的,容易引起错误。但是对指针变量直接赋值是可以的。因为C系统对指针变量赋值时要给以确定的地址,"C Langage"是常量,存放在代码段中,"C Langage"就代表了存放字符串的内存首地址。
因此, char *ps="C Langage";
或者 char *ps; ps="C Language"; 都是合法的。
7.函数与指针
1)函数指针
函数指针变量定义的一般形式为:类型说明符 (*指针变量名)();
例如: int (*pf)();
表示pf是一个指向函数入口的指针变量,该函数的返回值(函数值)是整型。
2)指针函数
在C语言中允许一个函数的返回值是一个指针(即地址),这种返回指针值的函数称为指针型函数。
定义指针型函数的一般形式为:
类型说明符 *函数名(形参表)
{
…… /*函数体*/
}
其中函数名之前加了“*”号表明这是一个指针型函数,即返回值是一个指针。类型说明符表示了返回的指针值所指向的数据类型。
8.右左法则
右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
用变量a给出下面的定义:
1、一个整数。
2、一个指向整型数的指针。
3、一个指向指针的指针,它指向的指针是指向一个整型数。
4、一个有10个整型数的数组。
5、一个有10个指针的数组,该指针是指向一个整型数的。
7、一个指向函数的指针,该函数有一个整型参数并返回一个整型数。
8、一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型。
答案如下:
(1) int a; //整型变量
(2) intint *a; //整型指针变量
(3) intint **a; //整型指针的指针变量
(4) int a[10]; //整形数组
(5) intint *a[10]; //整型指针数组
(6) int (*a)[10]; //整型数组指针变量
(7) int (*a)(int); //函数指针变量
(8) int (*a[10])(int); //函数指针数组
9.main函数的参数
main (int argc,char *argv[])
argc(第一个形参)必须是整型变量,
argv( 第二个形参)必须是指向字符串的指针数组。
argc参数表示了命令行中参数的个数(注意:文件名本身也算一个参数);
argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。