引言
C语言基础小结
正文
#include<stdio.h>
int main(){
char str1[ ]="hello";
char str2[ ]="hell\0o";
char str3[ ]={'h','e','l','l','o'};
char str4[ ]={'h','e','l','\0','l','o'};
char str5[10]="hello";
char str6[10]={'h','e','l','l','o'};
char *str7="hello";
printf("str1=%s:%d, %d\n",str1,sizeof(str1),strlen(str1));
printf("str2=%s:%d, %d\n",str2,sizeof(str2),strlen(str2));
printf("str3=%s:%d, %d\n",str3,sizeof(str3),strlen(str3));
printf("str4=%s:%d, %d\n",str4,sizeof(str4),strlen(str4));
printf("str5=%s:%d, %d\n",str5,sizeof(str5),strlen(str5));
printf("str6=%s:%d, %d\n",str6,sizeof(str6),strlen(str6));
printf("str7=%s:%d, %d\n",str7,sizeof(str7),strlen(str7));
return 0;
}
str1=hello:6, 5//自动在末尾补'\0',sizeof统计了该'\0',strlen遇到\0结束
str2=hell:7, 4//strlen遇到\0结束
str3=hello:5, 6//不会在末尾补'\0',strlen未找到'\0',输出不可靠
str4=hel:6, 3
str5=hello:10, 5//sizeof得到分配内存大小
str6=hello:10, 5
str7=hello:8, 5//64位机上,此处sizeof(char*)=8,自动在末尾补'\0'
小结如下:
- sizeof(…)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。
它的功能是:获取内存大小,获得保证能容纳实现所建立的最大对象的字节大小。
由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。实际上,用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。
具体而言,当参数分别如下时,sizeof返回的值表示的含义如下:
数组——编译时分配的数组空间大小;
指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4);
类型——该类型所占的空间大小;
对象——对象的实际占用空间大小;
函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。
- strlen(…)是函数,要在运行时才能计算。参数必须是字符型指针(char*)。当数组名作为参数传入时,实际上数组就退化成指针了。
它的功能是:返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。
- sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以”\0”结尾的。
- 应该注意char p[]=”hello world”;和char *p=”hello world”的区别;前者存放在栈里,后者存放在静态区
关于内存分配:
int a = 0; //全局初始化区
char *p1; //全局未初始化区(C++中则初始化为NULL)
int main()
{
int b; //b分配在栈上,整型
char s[] = "abc"; //s分配在栈上,char *类型;"abc\0"分配在栈上,运行时赋值,函数结束销毁
char *p2; //p2分配在栈上,未初始化
char *p3 = "123456"; //p3指向"123456"分配在字符串常量存储区的地址,编译时确定 p3存储在栈上
static int c = 0; //c在全局(静态)初始化区,可以多次跨函数调用而保持原值
p1 = (char *)malloc(10); //p1在全局未初始化区,指向分配得来得10字节的堆区地址
p2 = (char *)malloc(20); //p2指向分配得来得20字节的堆区地址
strcpy(p1, "123456"); //"123456"放在字符串常量存储区,编译器可能会将它与p3所指向的"123456"优化成一块
return 0;
}
- 注意以下初始化方法:
char str[10]="hello";//正确,用字符串常量来初始化字符数组
char str1[ ];//错误,中括号内如果不写数字,则必须为字符数组提供初始值,以便编译器进行内存分配。
char str[10];
str="hello";//错误,不能用赋值语句对整个字符数组赋值
str={'h','e','l','l','o'}; // 错误
str[0]='H';str[1]='e';str[2]='l';str[3]='l';str[4]='o'; // 正确