1.外部变量
外部static , extern
存储方式 : 静态
存储区: 静态存储区
生存区: 程序整个运行期间
作用域: 本文件 , 其他文件
赋初值 : 编译时赋值,只赋一次
未赋初值: 自动赋初值0或者空字符
自动变量是最常用的。 关键字auto能够显式地指定存储类别。
显式定义 auto int x,y;
隐含定义 等价 int x,y;
实际上关键字“auto”可以省略,auto不写则隐含确定为“自动存储类别”,即动态存储方式。
程序中大多数变量属于自动变量。
eg:
让上面两个文件同时编译,gcc 1.c 2. c -o 1
可输出num的值为100.
运行的结果为 : 1 2 3
如果不加 static ,运行结果为 1 1 1 void()里 int i = 0,每调用这个函数时,i都等于1.
2.指针的概念
指针是变量的一种,里面是一个地址,通过这个地址找到要找的数据。
实质 : 单元的地址就是指针内容。
指针是变量,指针有变量的特性:
系统为指针分配内存空间;
指针有自己的地址;
指针能够存值,但这个值比较特殊: 地址 。
指针本身所占据的内存区:
占4个字节byte ,32bite 。
用以上程序就能得出,用sizeof函数测出,所有类型的指针都占4byte,在32的平台里。
3.指针运算符
**
&是取地址的运算符,*是表示指针运算符
*号的两个含义:定义时,表示后面的变量,是指针
使用时,表示取值。
eg : int *p1,a;
p1 = &a;
*p1 = 3;
把一个变量的地址赋予指向相同数据类型的指针变量;
例如:int a, *pa ;
pa = &a ; //把a的地址给pa,都是整型
把一个指针变量的值赋予相同类型的另一个指针变量;
int a,pa = &a, pb ;
pb = pa; // 把a的地址给pb;
**eg:int x=3, y=0 , *px = &x;
y = *px +5; //y = 8
y = ++px; // 先运算px, y=4
y = px++; // (px)++是x的内容加1;
px++是先求px的值(x),然后再px++,指向下一个元素,不再指向x;
指针变量的使用步骤:
1 定义指针变量;
2.给指针变量赋地址;
3.正常使用指针进行运算
4.地址传递
通过指针实现地址传递,取其数据;
相当于:通过变量名,查找数据,进行运算;
#include<stdio.h>
void swap(int x, int y)
{
x = x + y;
y = x - y;
x = x - y;
}
int main()
{
int a = 1, b = 2;
swap(a,b);
printf("a = %d, b =%d",a,b);
}
5.数组传值与指针地址传值的区别
利用指针运算实现库函数strcpy
因为指针是通过地址找到数据,所以在拷贝字符串时,直接用地址赋值过去,每个字符的地址依次给过去传输;
而数组,是通过字符挨个传输。
#include<stdio.h>
#include<string.h>
void mystrcpy(char dest[], char src[])
{
int i, length = strlen(dest);
for(i = 0; i < length ; i++)
{
dest[i] = src [i];
}
}
int main()
{
char str[32] = "helloworld";
char ptr[32] = "abcd";
mystrcpy(str,ptr);
printf("%s\n",str);
return 0;
}
6.内存申请
用malloc函数。申请内存,需要用到#include< stdlib >
char *str = (char *)malloc(sizeof(char) * 128) //同时要强制转换成指针类型
7.指针和数组的区别
char *s;
s = "helloworld";
char ch[32] = {0};
strcpy(ch,"helloworld");
*因为char s是野指针,指向不能使用的内存。
它有可能是乱码,也可能是空的,也可能是正在使用的内存。
所以它不能用strcpy函数,strcpy函数是把,"helloworld"的地址,传输给s指针的地址。
但可以直接通过把“helloworld”的地址赋给s。
而 char ch[32]是定义一个32字节的字符串,它本身系统有给他分配地址,而"helloworld"字符串,系统也给他分配了空间,而系统给的空间是不能改变的,所以想要把’helloworld"的地址直接给s是不可能的。只能用strcpy函数,把"helloworld"的地址传输给s,通过s里的地址找到内容。
8.指针和字符串
在C语言中,可以用两种方法访问一个字符串。
1)用字符数组存放一个字符串,然后输出该字符串。
int main()
{
char string[] = “helloworld”;
printf("%s",string);
return 0;
}
2) 用字符串指针指向一个字符串。
int main()
{
char *string[] = {“helloworld”,"hello"};
printf("%s\n",string);
return 0;
}
运行结果是乱码,要加上下标printf("%s\n",string[0]); //或者string[1]
*char s=“C Language”; 则表示s是一个指向字符串的指针变量,把字符串的首地址赋予s 。
9.字符数组和字符串的区别
**1. 字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以‘\0’作为串的结束。
字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。
2. 对字符串指针方式 char *ps=“C Language”;
可以写为:
char *ps; ps=“C Language”;
而对数组方式: char st[]={“C Language”};
不能写为:
char st[20]; st={“C Language”};
而只能对字符数组的各元素逐个赋值。
3.当一个指针变量在未取得确定地址前使用是危险的,容易引起错误。
但是对指针变量直接赋值是可以的。因为C系统对指针变量赋值时要给以确定的地址。
因此, char ps=“C Langage”;
或者 char ps; ps=“C Language”; 都是合法的。