下图是 4G 内存中每个字节的编号(以十六进制表示):
我们将内存中字节的编号称为 地址(Address) 或 指针(Pointer) 。地址从 0 开始依次增加,对于 32 位环境,程序能够使用的内存为 4GB,最小的地址为 0,最大的地址为 0XFFFFFFFF。
下面的代码演示了如何输出一个地址:
- #include <stdio.h>
- int main(){
- int a = 100;
- char str[20] = "c.biancheng.net";
- printf("%#X, %#X\n", &a, str);
- return 0;
- }
0X28FF3C, 0X28FF10
%#X
表示以十六进制形式输出,并附带前缀0X
。a 是一个变量,用来存放整数,需要在前面加&
来获得它的地址;str 本身就表示字符串的首地址,不需要加&
。
CPU 访问内存时需要的是地址,而不是变量名和函数名!变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。编译和链接过程的一项重要任务就是找到这些名称所对应的地址。
例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
oxx(char* dest)
{
dest = (char*)malloc(30);
strcpy(dest, "content has been modied");
}
void
oxx2(char* dest)
{
strcpy(dest, "content hat been modied");
}
int main()
{
char* dest;
char str[30];
dest = &str[0];
strcpy(dest, "It's a simple");
oxx(dest);
printf("oxx dest=%s\n", dest);
oxx2(dest);
printf("oxx2 dest=%s\n", dest);
}
1、oxx改变的是“变量”_dest,调用函数时传给_dest的“值”已经被抛弃。然后对_dest重新赋值后,再对其“指向的地址单元”进行操作。由于_dest “指向的单元”是在函数内部申请的,所以,程序结束之后,_dest和_dest所申请的单元都会被删除。而_dest的值又没有通过return来返回给main。所以,它也就没有改动dest指向单元的内容了。
2、oxx2是对_dest“指向的单元”赋值,_dest又与dest指向相等的“地址单元”,所以,它也就是改变了dest“指向的单元”的值。
3、oxx是把dest当成一个变量;oxx2是把dest当成一个载体,对他指向的单元进行操作。