C语言复习 第二波

来源:互联网 发布:php写android服务器端 编辑:程序博客网 时间:2024/06/02 02:35

C语言复习 第二波~

一、数组

1、数组定义

int a = 10;
int arr[10];//这种定义在C99下是合法的,只不过所有windows下的编译器都不支持,在gcc下可顺利执行。
结果如右图: 

2、数组指针和指针数组

指针数组:指针数组可以说成是”指针的数组”,首先这个变量是一个数组,其次,”指针”修饰这个数组,意思是说这个数组的所有元素都是指针类型 。
char *arr[4] = {"hello","world","shanxi","xian"};   //这个数组呢有四个元素,每个元素都是char*类型的指针。
数组指针:数组指针可以说成是”数组的指针”,首先这个变量是一个指针,其次,”数组”修饰这个指针,意思是说这个指针存放着一个数组的首地址,或者说这个指针指向一个数组的首地址。
char (*pa)[4];//pa是一个指针指向一个char [4]的数组,每个数组元素是一个char类型的变量。

3、二维数组

int brr[3][4] = {{1,2,3},{4,5,6},{7}};//brr[0][6] = 6 因为二维数组的分配是连续的,所以当看似越界时,可先往后分析。

4、数组的sizeof

void Show(int arr[3][4]){printf("%d,%d\n",sizeof(arr),sizeof(*arr)); //4 , 4*4=16}int main(){int arr[20][4];printf("%d\n",sizeof(arr)); //320 = 20*4*4Show(arr);return 0;}

二、字符串

1、字符串的定义

int main(){char str1[5] = {'a','b','c'}; //okchar str2[5] = {"abc"};       //okchar str3[5] = "abc";         //ok //char str4[5] = "hello";     //error 越界char str5[] = "hello";        //ok4int arr[][4] = {1,2,3,4,5,6,7,8,9}; //ok//int arr[3][] = {1,2,3,4,5,6,7,8,9};//error 行能省略,列不可以return 0;}
2、字符数组和字符串常量的区别

int main(){//字符数组和字符串常量的区别char *str1 = "abcde";//1char str2[] = "abcde";//2str1[0] = 'x';//3 字符串常量不可以改变 编译不会出错,运行会崩溃str2[0] = 'x';//4}
3、字符串的长度sizeof和strlen

sizeof:sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。数组求长度:sizeof(ar)/sizeof(ar[0]);
strlen:strlen(char*)函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个'\0',如果你只定义没有给它赋初值,这个结果是不定的,它会从数组首地址一直找下去,直到遇到'\0'停止。
int main(){char str1[100] = "abcde";char str2[100] = "abcd\0ef\n";char *str3 = "abcde";char *str4 = "abcd\0ef\n";char str5[] = "abcde";char str6[] = "abcd\0ef\n";char str7[100];printf("%d,%d\n",sizeof(str1),strlen(str1));//100,5printf("%d,%d\n",sizeof(str2),strlen(str2));//100,4printf("%d,%d\n",sizeof(str3),strlen(str3));//4,5printf("%d,%d\n",sizeof(str4),strlen(str4));//4,4printf("%d,%d\n",sizeof(str5),strlen(str5));//6,5printf("%d,%d\n",sizeof(str6),strlen(str6));//9,4printf("%d,%d\n",sizeof(str7),strlen(str7));//100,112,对于没有初始化的数组,其大小未知}

4、字符串的一系列函数:拷贝、连接、比较、求长度、atoi、itoa

三、结构体和联合体

这个部分最重要的应该就是结构体的字节数问题。
字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)

如果不进行内存对齐,cpu在访问时效率就会很低,例如结构体里面有个char有个int,假设内存每次访问四个字节,不进行内存对齐,则先访问char和int的三个字节,再访问int的第四个字节,然后剔除第一个字节,合并第二个到第五个字节,很麻烦。

#include<iostream>using namespace std;//32位下,所有指针类型都是4字节,64位下所有指针都是8字节/*1、找出结构体中最宽的基本类型成员大小。2、依此大小为宽根据字节对齐准则进行计算。*//*32位下 24字节a(4)  d(4)b(4)  c(4)e(8)64位下 32字节a(8)d(8)b(4)c(4)e(8)*/struct T {    char a;    int *d;    int b;    int c:16;//位域,它是4字节,但是只取二进制前16位    double e;};int main(){     T *p;     cout<<sizeof(*p)<<endl;}//腾讯笔试:#include<iostream>using namespace std;typedef union{    long i; //4    int k[5]; //20    char c; //1}DATE; //20/*内存分布如下:cat(4) a1(4)a2(4)  a3(4)a4(4)  a5(4)dog(8)*/struct data // 32{    int cat; //4    //DATE cow;//20  相当于int k[5];     int a1;  //4     int a2;  //4     int a3;  //4     int a4;  //4     int a5;  //4    double dog;//8}too;int main(){     DATE max;     data d;     cout<<sizeof(d)<<endl; //32     printf("%d\n",sizeof(struct data)+sizeof(max)); //52     return 0;}

四、可变参数编程

va_list list;//char *list;
va_start(list,a);//找到...开头
va_arg(list,int);//从...取数据
va_end(list)//判断结束
原创粉丝点击