If you know the size of the arrays at initialization (i.e. when the program is first run), you can usually get away with the use of fixed size arrays for which C will automatically manage memory for you.
#include <stdio.h>
void change_arg(int p) {
p *= 2;
}
int main()
{
int x = 5;
change_arg(x);
printf("%d\n", x);
}
#include <stdio.h>
int main(int argc, char* argv[]) {
int x = 2;
int *p = &x;
int **q = &p;
int ***r = &q;
printf("%d, %p, %p, %p, %p, %p, %p, %d", x, &x, p, &p, q, &q, r, ***r);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(){
int *ps = malloc(5 * sizeof(int));
for (int i =0; i < 5; i++) {
ps[i] = i + 10;
}
printf("%d, %d\n", *ps, ps[0]); // remmeber that *ptr is just a regular variable outside of a declaration, in this case, an int
printf("%d, %d\n", *(ps+2), ps[2]);
printf("%d, %d\n", *(ps+4), *(&ps[4])); // * and & are inverses
free(ps); // avoid memory leak
}
#include <stdio.h>
int main(){
int arr[] = {1, 2, 3};
printf("%d\t%d\t%d\t%d\t%d\t%d\n", *arr, arr[0], 0[arr], *(arr + 2), arr[2], 2[arr]);
}
#include <stdio.h>
#include <stdlib.h>
int main(){
int r = 3, c = 4;
// first allocate space for the pointers to all rows
int **arr = malloc(r * sizeof(int *));
// then allocate space for the number of columns in each row
for (int i=0; i<r; i++) {
arr[i] = malloc(c * sizeof(int));
}
// fill array with integer values
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
arr[i][j] =i*r+j;
}
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("%d ", arr[i][j]);
}
}
// every malloc should have a free to avoid memory leaks
for (int i=0; i<r; i++) free(arr[i]);
free(arr);
}
#include <stdio.h>
#include <stdlib.h>
int main(){
// example 1
typedef char* string;
char *s[] = {"mary ", "had ", "a ", "little ", "lamb", NULL};
for (char **sp = s; *sp != NULL; sp++) {
printf("%s", *sp);
}
printf("\n");
// example 2
char *src = "abcde";
char *dest = malloc(5);
char *p = src + 4;
char *q = dest;
while ((*q++ = *p--));
for (int i = 0; i < 5; i++)
printf("i = %d, src[i] = %c, dest[i] = %c\n", i, src[i], dest[i]);
}
#include <stdio.h>
#include <math.h>
// Create a function pointer type that takes a double and returns a double
typedef double (*func)(double x);
// A higher order function that takes just such a function pointer
double apply(func f, double x)
{
return f(x);
}
double square(double x)
{
return x * x;
}
double cube(double x)
{
return pow(x, 3);
}
int main(){
double a = 3;
func fs[] = {square, cube, NULL};
for (func *f=fs; *f; f++) {
printf("%.1f\n", apply(*f, a));
}
}
//run on VS 2010
#include <stdio.h>
void pf2_pointer_arry(int *a1, int *b1, int *Lab, int N){
int i,La,ta,tb,ta1,tb1,*a,*b,n=1;
a1[0]=3;
b1[0]=2;
Lab[0]=Lab[1]=1;
while(n<N){
ta=tb=0;
a=a1;
b=b1;
La=Lab[0];
for(i=0;i<La;i++){
ta1=(*a)*3+(*b)*4+ta;
tb1=(*a)*2+(*b)*3+tb;
*a=ta1%10;
*b=tb1%10;
ta=ta1/10;
tb=tb1/10;
a++;
b++;
}
Lab[0]=La;
Lab[1]=La;
if(ta){
*a+=ta;
Lab[0]++;
}
if(tb){
*b+=tb;
Lab[1]++;
}
n++;
}
}
int main(int argc,char* arg[]){
int i;
int a[100], b[100], Lab[2];
for (i = 0; i < 100; i++) a[i]=b[i]=0;
pf2(a,b,Lab,50);
printf("p=");
for(i=Lab[0]-1;i>=0;i--)
printf("%d",a[i]);
printf(" q=");
for(i=Lab[1]-1;i>=0;i--)
printf("%d",b[i]);
printf("\n");
getchar();
return 0;
}
#include <stdio.h>
void pf2(int *a1, int *b1, int *Lab, int N){
int i,La,ta,tb,ta1,tb1,*a,*b;
if(N<=1) {
a1[0]=3;
b1[0]=2;
Lab[0]=Lab[1]=1;
}
else{
pf2(a1, b1, Lab, N-1);
ta=tb=0;
a=a1;
b=b1;
La=Lab[0];
for(i=0;i<La;i++){
ta1=(*a)*3+(*b)*4+ta;
tb1=(*a)*2+(*b)*3+tb;
*a=ta1%10;
*b=tb1%10;
ta=ta1/10;
tb=tb1/10;
a++;
b++;
}
Lab[0]=La;Lab[1]=La;
if(ta){
*a+=ta;
Lab[0]++;
}
if(tb){
*b+=tb;
Lab[1]++;
}
}
}
int main(int argc,char* arg[]){
int i;
int a[100], b[100], Lab[2];
for (i = 0; i < 100; i++) a[i]=b[i]=0;
pf2(a,b,Lab,50);
printf("p=");
for(i=Lab[0]-1;i>=0;i--)
printf("%d",a[i]);
printf(" q=");
for(i=Lab[1]-1;i>=0;i--)
printf("%d",b[i]);printf("\n");
getchar();
return 0;
}
#include <stdio.h>
void MatrixByMatrix(double *outVector, double *A, double *v, int n, int p, int q)
{
int i, j, k;
double s, *pa,*pv;
for (i = 0; i<n; i++){
for (k = 0; k<q; k++){
s = 0;
pa=A+i*p;
pv=v+k*p;
for (j = 0; j < p; j++)
s += (*pa++) * (*pv++);
outVector[i*n + k] = s;
}
}
}
int main(int argc,char* argv[]){
int i, j;
double b[100], c[100], out[16];
srand(1);
for (i = 0; i < 100; i++)
b[i] = (rand() % 100) / 100.0;
srand(1000);
for (i = 0; i < 100; i++)
c[i] = (rand() % 100) / 100.0;
MatrixByMatrix(out, b, c, 4, 25, 4);
printf("Matrix out:\n");
for (i = 0; i<4; i++){
for (j = 0; j<4; j++)
printf("%lf ", out[i*4+j);
printf("\n");
}
fflush(stdin);
getchar();
return 0;
}
Details of this part can be found http://people.duke.edu/~ccc14/sta-663/CrashCourseInC.html
The processs of C program compilation can be quite messy, with all sorts of different compiler and linker flags to specify, libraries to add and so on.
For this reason, most C programs are compiled using the make build tool that you are already familiar with.
Here is a simple generic makefile that you can customize to compile your own programs adapted from the book 21st Centur C by Ben Kelmens (O’Reilly Media).
In addition, there are traiditonal dummy flags
Just fill in the blanks with whatever is appropriate for your program.
%%file stuff.c
#include "stuff.h"
void do_stuff() {
printf("The square root of 2 is %.2f\n", sqrt(2));
}
Try to fix the following buggy program
%%file buggy.c
# Create a function pointer type that takes a double and returns a double
double *func(double x);
# A higher order function that takes just such a function pointer
double apply(func f, double x){
return f(x);
}
double square(double x){
return x * x;
}
double cube(double x){
return pow(3, x);
}
double mystery(double x){
double y = 10;
if (x < 10)
x = square(x);
else
x += y;
x = cube(x);
return x;
}
int main(){
double a = 3;
func fs[] = {square, cube, mystery, NULL}
for (func *f=fs, f != NULL, f++) {
printf("%d\n", apply(f, a));
}
}
What other language has an annual Obfuscated Code Contest http://www.ioccc.org/?
In particular, the following features of C are very conducive to writing unreadable code:
Here is one winning entry from the 2013 IOCCC entry that should warm the heart of statisticians - it displays sparklines (invented by Tufte).
main(a,b)char**b;{int c=1,d=c,e=a-d;for(;e;e--)_(e)<_(c)?c=e:_(e)>_(d)?d=e:7;
while(++e<a)printf("\xe2\x96%c",129+(**b=8*(_(e)-_(c))/(_(d)-_(c))));}
%%file sparkl.c
main(a,b)char**b;{int c=1,d=c,e=a-d;for(;e;e--)_(e)<_(c)?c=e:_(e)>_(d)?d=e:7;
while(++e<a)printf("\xe2\x96%c",129+(**b=8*(_(e)-_(c))/(_(d)-_(c))));}
import numpy as np
np.set_printoptions(linewidth=np.infty)
print ' '.join(map(str, (100*np.sin(np.linspace(0, 8*np.pi, 30))).astype('int')))
%%bash
./sparkl 0 76 98 51 -31 -92 -88 -21 60 99 68 -10 -82 -96 -41 41 96 82 10 -68 -99 -60 21 88 92 31 -51 -98 -76 0