首页 > 其他分享 >C语言 笔记 1

C语言 笔记 1

时间:2023-08-20 16:36:18浏览次数:32  
标签:const 变量 int 笔记 C语言 ++ 数组 指针

指针有什么用?

场景A

通过函数交换两个变量的值

eg. 交换变量a,b的值

int swap(int *a, int *b){
	int temp = 0;
	temp = *a;
	*a = *b;
	*b = temp;
}

场景B

返回结果有多个,或return返回状态,指针返回结果

int divide(int a,int b,float *res){
	int ret = 1;
	if(b != 0){
		*res = (float)a/b;
	}else{
		ret = 0;
	}
	return ret;
}

指针最常见的错误

定义了指针变量,但是没有指向任何变量,就开始使用。

int main(){
	int *p;
	*p = 12;
	printf("%d",*p);
	return 0;
}

指针与数组

数组变量是特殊的指针

  • 数组变量本身表达地址。所以
    • int a[10]; int* p = a; //无需用&取地址
    • 但是数组的单元表达的是变量,需要用&取地址
    • a == &a[0]
  • []运算符可以对数组做,也可以对指针做
    • p[0] <==> a[0]
  • 运算符可以对指针做,也可以对数组做
    • *a 操作的是数组的第一个单元
  • 数组变量是const的指针,不能被赋值
    • int b[] --> int * const b;

指针与const

如果指针被const修饰

  • 表示一旦得到了某个变量的地址就不能再指向其他变量
    • int * const q = &i; // 指针 q 是 const
    • *q = 26; // OK
    • q++; // Error

如果所指是const

  • 表示不能通过指针修改那个变量(并不能使那个变量成为const)
    • const int *p = &i;
    • *p = 26; // Error
    • i = 26; // OK
    • p = &j; //OK

这些都是啥意思?

int i;
const int* p1 = &i;
int const* p2 = &i;
int *const p3 = &i;
  • 判断哪个被const了标志是const在*的前面还是后面
    • const * :所指被const了
    • * const :指针被const了

转换

  • 总是可以把一个非const的值转换成const的
void f(const int * x);
// const int * x; 所指被const了,表示传入的变量在这个函数中绝对不会被修改
int a = 15;
f(&a); // ok,传入一个非const值,转换为const,不能修改
const int b = a;
f(&b); // ok,传入const值,不能修改

f(const int * x){
	x++; // error,const不能修改
}
  • 当要传递的参数的类型比地址大的时候,这是常用的手段:既能用比较少的字节数传递值给参数,又能避免函数对外面的变量修改

const数组

  • const int a[] =
  • 数组变量本身就是const指针,这里的const表明数组的每个单元都是const int
  • 所以必须通过初始化进行赋值

保护数组值

  • 因为把数组传入函数时传入的是地址,所以函数可以修改数组值
  • 传入时用const修饰,可以保护数组值不被函数修改
  • int f(const int arr[]);

指针运算

指针+1的含义

  • 给一个指针加1表示要让这个指针指向下一个单元的变量
int a[10];
int *p = a;
*p -> a[0];
*(p+a) -> a[1];
  • 如果指针不是指向一片连续分配的空间(如数组),则这种运算没有意义。

指针可用的运算符

  • 给指针加减一个整数 (+ , += , - , -=)
  • 递增递减 (++ , --)
  • 两个指针相减(返回两个指针之间的距离)
int a[] = {5,4,3,2,1};
int *p1 = &a[1];
int *p2 = &a[4];
printf("%d\n",p2-p1); // 输出结果:3

指针的大小比较

  • 两个指针可以比较大小
  • 只有在两个指针指向同一数组时比较才有意义
  • 比较结果依赖于指针在数组中的相对位置
int a[] = {1,0};
int *p = &a[0];
int *q = &a[1];
printf("%d",p>q); //输出0
printf("%d",*p>*q); //输出1

指向符合字面量的指针

int *p = (int []){0,1,2,3,5};

C99特性,可以减少一些麻烦。不用声明一个数组,再用指针指向这个数组的第一位。

指针用于数据处理

*和++运算符的组合

++ 优先级大于 *

表达式 含义
*p++ 或 *(p++) 自增前表达式的值是*p,然后自增p
(*p)** 自增前表达式的值时*p,然后自增*p
*++p或者*(++p) 先自增p,自增后表达式的值仍是*p
++*p或者++(*p) 先自增*p,自增后表达式的值仍是*p

动态内存分配

在C99中,可以用变量做数组定义的大小,C99之前呢?

C99之前可以给指针分配一定大小的内存,来存放数组,这样就能实现定义数组的大小。

int *arr = (int*)malloc(n*sizeof(int));

malloc分配的是void*,需要强制转换成int*,然后用数组大小n乘以单个int占用的字节就可以把能存放n个int型的空间分配给了*arr。

malloc

  • 使用malloc函数需要引入头文件stdlib.h

  • malloc返回一个指针,类型为void*

  • 如果malloc请求失败,返回NULL

  • malloc的参数为size,以字节为单位

  • 使用free()释放内存

小记

对于以下代码段,正确的说法是:

char *p; 
while(1){
	p = malloc(1);
	*p = 0; 
}
  • A. 最终程序会因为没有没有空间了而退出
  • B. 最终程序会因为向0地址写入而退出
  • C. 程序会一直运行下去
  • D. 程序不能被编译

正确为B选项。一直给p分配内存,但不释放,最终malloc会因内存不足而请求失败,返回NULL。此时指针p的地址指向了NULL(0地址),此时对0地址写入,系统崩溃退出。

单字符的输入输出

putchar

  • int putchar(int c);
  • 向标准输出写一个字符
  • 返回写了几个字符,EOF(-1)表示写失败

getchar

  • int getchar(void);
  • 从标准输入读取一个字符
  • 返回类型为int,是为了返回EOF(-1)
    • Windows -> Ctrl+Z
    • Unix -> Ctrl+D

字符串数组

  • char **a
    • a是一个指针,指向另一个指针,那个指针指向一个字符(串)
  • char a[][n]
    • 一个数组a,每个单元都能放下长度为10的字符(串)
    • 缺点,字符串长度固定,不能超出
  • char *a[]
    • 一个数组a,每个单元都是一个char*,可以存放字符串
    • 相比a[][],字符串的长度不受限制

程序参数

  • int main(int argc,char const *argv[])
  • argc是argv字符串数组的数量
  • argv[0] 是启动程序的命令本身
    • 当使用符号链接时,反应符号链接的名字
  • 当然可以不叫argc和argv,名字可以自己取
#include<stdio.h>

int main(int n,char const *a[]){
    for(int i = 0; i < n; i++){
        printf("%d => %s\n",i,a[i]);
    }
    return 0;
}

将该文件编译为叫做test的程序,使用 ./test 运行

0 => ./test

使用 ./test abc def 114 514 运行

0 => ./test
1 => abc
2 => def
3 => 114
4 => 514

使用 ln -s test test2 创建符号链接

使用 ./test2 abc def 114 514 运行

0 => ./test2
1 => abc
2 => def
3 => 114
4 => 514

标签:const,变量,int,笔记,C语言,++,数组,指针
From: https://www.cnblogs.com/orzmiku/p/17644186.html

相关文章

  • C语言 笔记2
    枚举常量符号化我们可以用下面代码将常量符号化constintred=0;constintyellow=1;constintblue=2;用枚举可以简写成enum=colors{red,yellow,blue};此时,red=>0,yellow=>1,blue=>2枚举枚举是一种用户定义的数据类型,他用关键词enum以如下语法来声明......
  • C语言 笔记4
    全局变量定义在函数外部的变量是全局变量。全局变量具有全局的生存期和作用域全局变量与任何函数都无关在任何函数内部都可以使用全局变量不能使用变量给全局变量初始化不初始化的全局变量默认为NULL函数内的同名变量会隐藏全局变量inta=1;{ inta=2; { in......
  • C语言 笔记3
    可变数组设计一个Array库,提供数组初始化,数组数据查看和修改的功能,且数组大小可变。array.h/*可变数组*///array_block,每次触发自动增长时增长的数量,记作一个array_block#defineARRAY_BLOCK10typedefstruct{intsize;int*array;}Array;Arrayarr......
  • C语言 笔记5
    格式化输入输出输入-printfprintf("%[flags][width][.prec][hlL]type...",参数表...);返回值输出的字符数flagFlag含义-左对齐+给一个正数强制加一个+号(space)正数留空0左边补零,不能和左对齐同时使用width和precwidth含义number......
  • 「Python」第一阶段第七章笔记
    函数的多返回值"""函数的多返回值"""defmy_return():return1,2x,y=my_return()print(x,y,type(x),type(y))函数的多种传参方式"""函数的多种传参方式-位置-参数-缺省-不定长"""#位置传参形参实参位置对应defadd(a=0,b=0)......
  • 「Python」第一阶段第五章笔记
    函数的初体验"""函数的初体验"""name="OrzMiku"print(f"{name}这个名字有{len(name)}个字符长")函数的定义"""函数的定义def函数名(参数表):函数体return返回值"""defsayHello():print("HelloW......
  • 「Python」第一阶段第二章 笔记
    字面量#字面量:写在程序中固定的值print(114514)print(1919810)print("HelloWorld")注释"""Python中的多行注释"""print("多行注释用三个引号开头三个引号结尾")#Python中的单行注释print("单行注释以井号开头")变量"""变量名=变量值&......
  • 「Python」第一阶段第三章笔记
    布尔类型和比较运算符"""跳过"""if语句基本格式"""if语句基本格式if条件:代码块"""age=int(input("请输入你的年龄:"))ifage>=18:print("老东西速速爆金币!")quit()print("小东西给我磕一个!")......
  • 「Python」第一阶段第四章笔记
    while循环"""while条件:代码块"""num=255;#python没有++和--whilenum:print(num)num-=1for循环for基础语法"""for循环(感觉更像是一个foreach循环)for临时变量in序列类型:代码块"""name="OrzMiku......
  • 「Python」第二阶段第一章笔记
    初识对象"""初识对象"""#1.设计一个类classStu:name=None#学生姓名gender=None#学生性别nationality=None#学生国籍native_place=None#学生籍贯age=None#学生年龄#2.创建一个对象stu_1=Stu()#3.对象属性进行赋......