C语言重点知识复习2
来源:互联网 发布:go高级编程书籍 编辑:程序博客网 时间:2024/06/06 04:55
1.指针的算术运算
(1)指针之间不允许相加,但允许相减
指针相减表示两个指针之间间隔的单元格数(1.先计算出字节数 2.再除以权重)
(2)指针运算需要调整
p+数字(n) 加n单元格的权重 权重为指针变量去掉一个*,求sizeof(),乘n
数字之间不需要调整,直接加或减
#include <stdio.h>#include <stdlib.h>int main(){ int arr[10] = {1,2,3,4,5,6,7,8,9}; int *p = arr; //指针-指针 int *q = &arr[8]; printf("%d\n",p-q);//-8 printf("%d\n",q-p);//8 printf("%d\n",(short *)q-(short *)p);//16 printf("%d\n",(double *)q-(double *)p);//4 printf("%d\n",(unsigned long)q-(unsigned long)p);//32 int *p1 = (int *)2000;//指针+-数字 printf("%d\n",p1+2);//2008 printf("%d\n",(char *)p1+2);//2002 printf("%d\n",(long long)p1+2);//2002 printf("%d\n",(double **p1+2);//2008}
2.数组和指针的替换
int arr[10];int *p = arr;arr[i] = *(arr+i);p[i] = *(p+i);
3.指针和数组的其他知识
(1)数组名代表整个数组长度的两种情况
int arr[10] = {0,1,2,3,4,5,6,7,8,9};sizeof(arr) = 40;cout<<&arr<<endl;//1000cout<<&arr+1<<endl;//1040
(2)类型
int arr[10]; int *p = arr;int brr[3][4]; int (*q)[4] = brr;//二维数组的数组名是指向一位数组的指针
brr[0]是int*类型
brr[0]+1是int*类型(+数字,对类型无影响)
brr[2][3]是int类型
(3)二位数组是否越界
int brr[3][4] = {{1,2,3},{4,5,6},{7}}; printf("%d\n",brr[0][6]);//6 二维数组是线性存储的,可以越界访问
(4)字符串的定义正确的是?
char str1[5] = {'a','b','c'};//ok char str2[5] = {"abc"};//ok char str3[5] = "abc";//ok char str4[] = "hello"; //ok char str5[5] = "hello";//error,越界
(5)字符数组的大小
sizeof—求内存的字节数,所有的字符都要放进去
strlen—字符串的有效长度,碰到’\0’就结束
#include <stdio.h>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"; printf("%d,%d\n",sizeof(str1),strlen(str1));//100,5 printf("%d,%d\n",sizeof(str2),strlen(str2));//100,4 printf("%d,%d\n",sizeof(str3),strlen(str3));//4,5 printf("%d,%d\n",sizeof(str4),strlen(str4));//4,4 printf("%d,%d\n",sizeof(str5),strlen(str5));//6,5 printf("%d,%d\n",sizeof(str6,strlen(str6);//9,4 return 0;}
(6)字符数组和字符串常量的区别
int main(){ char *str1 = "abcde";//1 char str2[] = "abcde";//2 str1[0] = 'x';//3 编译没问题,运行崩溃 str2[0] = 'x';//4 return 0;}
str1是字符常量,在全局静态变量区(.rodata段),不能修改其值
str2是字符数组,在栈上,自己的内存,可以随便修改
改错题可能会考,需要在定义时显示的加上const,这样编译就不会通过
const const char *str1 = “abcde”;
(7)下列各变量的含义
int *a;//整型指针int *b();//函数,无参数,返回值是int *int c[4];//整型数组int *d[4];//指针数组,每个数组的元素是一个int类型的指针int (*e)[4];//数组指针,该指针指向一个含有4个整型元素的数组int (*f)();//函数指针,该指针指向一个函数,函数无参数,返回值是int类型
4.交换函数
#include <stdio.h>void Swap1(int *p1, int *p2){ int *tmp = p1; p1 = p2; p2 = tmp;}void Swap2(int *p1, int *p2){ int *tmp;//野指针 *tmp = *p1; *p1 = *p2; *p2 = *tmp;} void Swap3(int *p1, int *p2){ int tmp = *p1; *p1 = *p2; *p2 = tmp;}int main(){ int a = 10; int b = 20; printf("a=%d,b=%d\n",a,b); Swap1(&a, &b); printf("swap1:a=%d,b=%d\n",a,b); Swap2(&a, &b); printf("swap2:a=%d,b=%d\n",a,b); Swap3(&a, &b); printf("swap3:a=%d,b=%d\n",a,b); return 0;}
子函数和父函数之间要建立联系,必须传指针并解引用
5.返回数组/指针
#include <stdio.h>char *Fun1(){ char arr[] = "hello world"; return arr;}int main(){ printf("%s\n",Fun1());///返回局部数组,乱码}`
arr是局部变量,出Fun1函数后,函数栈帧回退,arr的地址可能已经被重新分配给别的函数使用。不能返回局部变量!!!
6.结构体和联合体
struct A{ char a;//1+1 short b;//2 int c;//4};//8struct B{ char a;//1+3 int b;//4 short c;//2};//10+2struct C//位段{int a:10;//a占10位int b:2;//a占2位};//4,必须是int的倍数struct D{ char a;//1 struct DD//有类型有变量,以单个最大的数据类型对齐 { char b;//1+3 int c;//4 }d;//8};//9+3struct E{ short a;//2 struct EE//有类型没变量,不占内存 { char b; int c; };//不占内存 int d;//4};//6+2struct F{ int a;//4 struct//没类型没变量,生成一个透明的变量,a/b/c/d同级 { char b;//1+3 float c;//4 }; char d;//1+3};//16struct G{ char a;//1 struct//只有变量没有类型(与有变量有类型)相同 { char b;//1+3 int c;//4 }d;//8};//9+3union H//共用体{ char a; short b; int c;};//4
7.可变参数编程 3个宏
需要引入头文件#include<stdarg.h>va_list list;//相当于char* list;va_start(list, num);//找到...开头va_arg(list,int);//从…取数据va_end(list);//list==NULL,关闭
编程题:编写一个名叫max_list的函数,它用于检查任意数目的整型参数并返回它们中的做大值,参数列表必须以一个负数结尾,提示列表的结束。
#include <iostream>#include <stdarg.h>using namespace std;int Max_list(int a,...)//1,4,9,-1{ int max = a; int cur = a; va_list list;//char *list; va_start(list,a);//找到...开头 while(cur >= 0) { cur = va_arg(list,int);//从...取数据 if(max < cur) { max = cur; } } va_end(list);//list = NULL; return max;}int main(){ printf("%d\n",Max_list(1,5,9,0,2,5,-1)); return 0;}
8.malloc常见错误
malloc一般都是内存的问题(程序崩溃/内存泄露)
面试题:C++是兼容C的,C已经有了malloc/free,C++为什么还要有new/delete?
答:malloc/free是C语言的标准库函数,new/delete是C++的运算符
对于非内置数据类型的对象来说,使用malloc/free无法满足动态创建对象的要求。对象创建的时候要自动调用构造函数,对象消亡的时候要自动调用析构函数。malloc/free是库函数,不在编译器权限的控制范围内,不能把调用构造函数和析构函数的任务强加给malloc/free。因此,C++需要一个能完成动态分配并初始化内存的运算符new,一个可以清理并释放内存的运算符delete。
- C语言重点知识复习2
- C语言重点知识复习1
- C 语言重点知识
- C语言重点知识小结
- C语言小知识复习2
- C语言与数据结构复习重点
- 计算机网络知识复习重点
- C语言知识复习①
- C语言重点知识,面试必备!!
- 操作系统 重点知识复习总结
- C语言基础学习(1~3)重点复习
- C语言易忘知识记录复习
- C语言小知识复习1
- C语言小知识复习3
- C语言复习2
- c语言复习2
- C语言复习2
- PHP 重点复习 2
- 随机生成字母数字的组合
- 函数签名(方法签名)Type signature
- javascript1
- 海思IVE函数使用-1 (DMA使用 HI_MPI_IVE_DMA)
- 关于java和python的环境搭建问题
- C语言重点知识复习2
- 面向对象6---抽象
- [并行计算] 1. 并行计算简介
- 类型转化
- Spring 开启Annotation <context:annotation-config> 和 <context:component-scan>诠释及区别
- GitBash的安装和使用
- SQL1999语法
- canvas的width和style里面的width
- Session