Let's trace your code.
List *l, *l1 = NULL;
defines two pointer variables of type List.
for (int i = 0; i < n; i++) {
you are starting a loop, which will traverse n times. Which means, if you call this function with 5, this loop will execute 5 times.
l = malloc(sizeof(List));
creates a List value in the memory, and stores the location of that value in the l pointer variable. For every pass through the loop, a different List value is created in the memory.
l->val = n-i;
assigns a value n-i to the val field of the newly created List value. For the first pass through the loop, i will be 0, so the val will contain 5 - 0, which is 5. For the second pass, i is 1, so for the second List, the val will contain 5 - 1, which is 4, and so on.
l->next = l1;
there is a next field in the List type, which is a pointer of the same type. For the first pass, li contains NULL, so it will point to null. For the second pass, l1 will contain the previously created List value, so the second List's next field will point it to that, and so on.
l1 = l;
stores the memory address of the newly created created element to be used in the next pass of the loop.
At a glance:
After the first pass of the loop (i = 0) -
5->NULL
After the second pass (i = 1),
4 -> 5 -> NULL
After the third (i = 2),
3 -> 4 -> 5 -> NULL
After the fourth (i = 3),
2 -> 3 -> 4 -> 5 -> NULL
After the fifth (and last) (i = 4),
1 -> 2 -> 3 -> 4 -> 5 -> NULL
List *makeList(int n)line is ?